Changeset 238 for trunk/kernel/vfs/vfs.c
- Timestamp:
- Jul 19, 2017, 3:31:39 PM (8 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/kernel/vfs/vfs.c
r222 r238 248 248 } // end vfs_inode_destroy() 249 249 250 ///////////////////////////////////////////// 251 error_t vfs_inode_load( vfs_inode_t * parent, 252 char * name, 253 xptr_t child_xp ) 254 { 255 error_t error = 0; 256 257 assert( (parent != NULL) , __FUNCTION__ , "parent pointer is NULL\n"); 258 259 assert( (child_xp != XPTR_NULL) , __FUNCTION__ , "child pointer is NULL\n"); 260 261 // get parent inode FS type 262 vfs_fs_type_t fs_type = parent->ctx->type; 263 264 // call relevant FS function 265 if( fs_type == FS_TYPE_FATFS ) 266 { 267 error = fatfs_inode_load( parent , name , child_xp ); 268 } 269 else if( fs_type == FS_TYPE_RAMFS ) 270 { 271 assert( false , __FUNCTION__ , "should not be called for RAMFS\n" ); 272 } 273 else if( fs_type == FS_TYPE_DEVFS ) 274 { 275 assert( false , __FUNCTION__ , "should not be called for DEVFS\n" ); 276 } 277 else 278 { 279 assert( false , __FUNCTION__ , "undefined file system type\n" ); 280 } 281 282 return error; 283 284 } // end vfs_load_inode() 285 250 286 //////////////////////////////////////////// 251 287 void vfs_inode_remote_up( xptr_t inode_xp ) … … 594 630 595 631 if( error ) return error; 632 633 vfs_dmsg("\n[INFO] %s exit for %s / file_id = %d / file_xp = %l / at cycle %d\n", 634 __FUNCTION__ , path , file_id , file_xp , hal_get_cycles() ); 596 635 597 636 // success … … 1161 1200 cxy_t child_cxy; // cluster for child inode 1162 1201 vfs_inode_t * child_ptr; // local pointer on child inode 1163 vfs_inode_type_t inode_type; // child inode type1202 vfs_inode_type_t child_type; // child inode type 1164 1203 vfs_fs_type_t fs_type; // File system type 1165 1204 vfs_ctx_t * ctx_ptr; // local pointer on FS context … … 1206 1245 &child_xp ); 1207 1246 1208 if( found == false ) // child inode not found in inode tree => try to load it 1247 // if a child inode is not found in the inode tree: 1248 // - we create the missing inode/dentry couple in the inode tree, 1249 // - we scan the parent mapper to complete the child inode (type and extension), 1250 // - we return an error if child not found on device. 1251 // - if the missing child is a directory, we load the child mapper from device 1252 1253 // for the last name, the behaviour depends on the "mode" argument: 1254 1255 if (found == false ) // directory node not found in inode tree 1209 1256 { 1210 1257 vfs_dmsg("\n[INFO] %s : <%s> not found, try to load it\n", … … 1214 1261 vfs_inode_unlock( parent_xp ); 1215 1262 1216 // get cluster and local pointer on parent inode1263 // get parent inode FS type 1217 1264 parent_cxy = GET_CXY( parent_xp ); 1218 1265 parent_ptr = (vfs_inode_t *)GET_PTR( parent_xp ); 1219 1266 1220 // get local pointer on parent inode context 1221 ctx_ptr = (vfs_ctx_t *)hal_remote_lpt( XPTR( parent_cxy , &parent_ptr->ctx ) ); 1222 1223 // get parent inode FS type 1224 fs_type = hal_remote_lw( XPTR( parent_cxy , &ctx_ptr->type ) ); 1225 1226 // get child inode type 1227 if( (last == false) || (mode & VFS_LOOKUP_DIR) ) inode_type = INODE_TYPE_DIR; 1228 else inode_type = INODE_TYPE_FILE; 1229 1230 // select a cluster for child inode 1231 cxy_t child_cxy = vfs_cluster_random_select(); 1267 ctx_ptr = (vfs_ctx_t *)hal_remote_lpt( XPTR( parent_cxy , 1268 &parent_ptr->ctx ) ); 1269 fs_type = hal_remote_lw( XPTR( parent_cxy , &ctx_ptr->type ) ); 1270 1271 // select a cluster for missing inode 1272 child_cxy = vfs_cluster_random_select(); 1232 1273 1233 printk("\n@@@ name not found : <%s>\n", name );1234 1235 1274 // insert a new child dentry/inode in parent inode 1236 1275 error = vfs_add_child_in_parent( child_cxy, 1237 inode_type,1276 INODE_TYPE_DIR, 1238 1277 fs_type, 1239 1278 parent_xp, 1240 1279 name, 1241 NULL, 1280 NULL, // fs_type_specific inode extend 1242 1281 &child_xp ); 1243 1282 if( error ) 1283 { 1284 printk("\n[ERROR] in %s : no memory for inode %s in path %s\n", 1285 __FUNCTION__ , name , pathname ); 1286 return ENOMEM; 1287 } 1288 1289 // scan parent mapper to complete the missing inode 1290 if( parent_cxy == local_cxy ) 1291 { 1292 error = vfs_inode_load( parent_ptr, 1293 name, 1294 child_xp ); 1295 } 1296 else 1297 { 1298 rpc_vfs_inode_load_client( parent_cxy, 1299 parent_ptr, 1300 name, 1301 child_xp, 1302 &error ); 1303 } 1304 1305 if ( error ) 1244 1306 { 1245 1307 printk("\n[ERROR] in %s : node %s not found in path %s\n", … … 1248 1310 } 1249 1311 1312 // get child inode type 1313 child_ptr = (vfs_inode_t *)GET_PTR( child_xp ); 1314 child_type = hal_remote_lw( XPTR( child_cxy , &child_ptr->type ) ); 1315 1316 // load child mapper from device if it is a directory 1317 if( child_type == INODE_TYPE_DIR ) 1318 { 1319 if( child_cxy == local_cxy ) 1320 { 1321 error = vfs_mapper_load_all( child_ptr ); 1322 } 1323 else 1324 { 1325 rpc_vfs_mapper_load_all_client( child_cxy, 1326 child_ptr, 1327 &error ); 1328 } 1329 1330 if ( error ) 1331 { 1332 printk("\n[ERROR] in %s : cannot access device for node %s in path %s\n", 1333 __FUNCTION__ , name , pathname ); 1334 return EIO; 1335 } 1336 } 1337 1338 // TODO handle lookup mode here [AG] 1339 1250 1340 // take lock on parent inode 1251 1341 vfs_inode_lock( parent_xp ); 1252 1342 } 1253 1343 1254 vfs_inode_display( child_xp );1255 1256 vfs_display( parent_xp );1257 1258 1344 vfs_dmsg("\n[INFO] %s : found <%s> / parent = %l / child = %l / last = %d\n", 1259 __FUNCTION__ , name , parent_xp , child_xp , last );1345 __FUNCTION__ , name , parent_xp , child_xp , last ); 1260 1346 1261 1347 // TODO check access rights … … 1269 1355 // } 1270 1356 1271 // TODO TODO TODO access device and load inode mapper if required... 1272 1273 // take lock on child inode if not last 1274 if( last == false ) vfs_inode_lock( child_xp ); 1275 1276 // release lock on parent inode 1357 // take lock on child inode and release lock on parent 1358 vfs_inode_lock( child_xp ); 1277 1359 vfs_inode_unlock( parent_xp ); 1278 1360 … … 1280 1362 parent_xp = child_xp; 1281 1363 current = next; 1282 1283 vfs_dmsg("\n[INFO] %s : complete node <%s> / last = %d\n",1284 __FUNCTION__ , name , last );1285 1286 1364 } 1287 1365 while( last == false ); 1288 1366 1289 vfs_dmsg("\n[INFO] in %s : searched inode found for %s\n", 1290 __FUNCTION__ , pathname ); 1291 1292 // get cluster and local pointer on child inode 1293 child_cxy = GET_CXY( child_xp ); 1294 child_ptr = (vfs_inode_t *)GET_PTR( child_xp ); 1295 1296 // return searched pointers 1367 // release lock 1368 vfs_inode_unlock( parent_xp ); 1369 1370 vfs_dmsg("\n[INFO] in %s : exit / %s found / inode = %l\n", 1371 __FUNCTION__ , pathname , child_xp ); 1372 1373 // return searched pointer 1297 1374 *inode_xp = child_xp; 1298 1375 … … 1385 1462 cxy_t parent_cxy; // parent inode cluster identifier 1386 1463 vfs_inode_t * parent_ptr; // parent inode local pointer 1387 vfs_ctx_t * parent_ctx; // parent inode context local pointer1388 1464 1389 1465 // get parent inode cluster and local pointer … … 1471 1547 } // end vfs_add_child_in_parent() 1472 1548 1473 1474 1475 1476 1549 ////////////////////////////////////////////////////////////////////////////////////////// 1477 1550 // Mapper related functions 1478 1551 ////////////////////////////////////////////////////////////////////////////////////////// 1479 1552 1480 //////////////////////////////////////////////// 1481 error_t vfs_move_page_to_mapper( page_t * page ) 1553 //////////////////////////////////////////// 1554 error_t vfs_mapper_move_page( page_t * page, 1555 bool_t to_mapper ) 1482 1556 { 1483 1557 error_t error = 0; … … 1492 1566 vfs_fs_type_t fs_type = mapper->inode->ctx->type; 1493 1567 1494 // update mapper if permitted by file system type1568 // call relevant FS function 1495 1569 if( fs_type == FS_TYPE_FATFS ) 1496 1570 { 1497 // get mapper lock in WRITE_MODE1498 1571 rwlock_wr_lock( &mapper->lock ); 1499 1500 error = fatfs_read_page( page ); 1501 1502 // release mapper lock 1572 error = fatfs_move_page( page , to_mapper ); 1503 1573 rwlock_wr_unlock( &mapper->lock ); 1504 1574 } … … 1518 1588 return error; 1519 1589 1520 } // end vfs_move_page _to_mapper()1590 } // end vfs_move_page() 1521 1591 1522 1592 ////////////////////////////////////////////////// 1523 error_t vfs_move_page_from_mapper( page_t * page ) 1524 { 1525 error_t error = 0; 1526 1527 assert( (page != NULL) , __FUNCTION__ , "page pointer is NULL\n" ); 1528 1529 mapper_t * mapper = page->mapper; 1593 error_t vfs_mapper_load_all( vfs_inode_t * inode ) 1594 { 1595 assert( (inode != NULL) , __FUNCTION__ , "page pointer is NULL\n" ); 1596 1597 uint32_t index; 1598 page_t * page; 1599 1600 mapper_t * mapper = inode->mapper; 1601 uint32_t size = inode->size; 1530 1602 1531 1603 assert( (mapper != NULL) , __FUNCTION__ , "no mapper for page\n" ); 1532 1604 1533 // get FS type 1534 vfs_fs_type_t fs_type = mapper->inode->ctx->type; 1535 1536 // update file system if permitted by file system type 1537 if( fs_type == FS_TYPE_FATFS ) 1538 { 1539 if( page_is_flag( page , PG_DIRTY ) ) 1540 { 1541 // get mapper lock in READ_MODE 1542 rwlock_rd_lock( &mapper->lock ); 1543 1544 error = fatfs_write_page( page ); 1545 1546 // release mapper lock from READ_MODE 1547 rwlock_rd_unlock( &mapper->lock ); 1548 1549 // clear dirty bit if success 1550 if( error == 0 ) page_undo_dirty( page ); 1551 } 1552 } 1553 else if( fs_type == FS_TYPE_RAMFS ) 1554 { 1555 assert( false , __FUNCTION__ , "should not be called for RAMFS\n" ); 1556 } 1557 else if( fs_type == FS_TYPE_DEVFS ) 1558 { 1559 assert( false , __FUNCTION__ , "should not be called for DEVFS\n" ); 1560 } 1561 else 1562 { 1563 assert( false , __FUNCTION__ , "undefined file system type\n" ); 1564 } 1565 1566 return error; 1567 1568 } // end vfs_move_page_from_mapper() 1569 1570 1605 assert( (size != 0) , __FUNCTION__ , "size cannot be 0\n"); 1606 1607 uint32_t npages = size >> CONFIG_PPM_PAGE_SHIFT; 1608 if( size & CONFIG_PPM_PAGE_MASK ) npages++; 1609 1610 // loop on all pages 1611 for( index = 0 ; index < npages ; index ++ ) 1612 { 1613 // this function allocates the missing page in mapper, 1614 // and call the vfs_mapper_move_page() to load the page from device 1615 page = mapper_get_page( mapper , index ); 1616 1617 if( page == NULL ) return EIO; 1618 } 1619 1620 return 0; 1621 1622 } // end vfs_mapper_load_all() 1623
Note: See TracChangeset
for help on using the changeset viewer.