Changeset 459 for trunk/kernel/fs
- Timestamp:
- Aug 13, 2018, 1:43:20 PM (6 years ago)
- Location:
- trunk/kernel/fs
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/kernel/fs/vfs.c
r457 r459 247 247 } // end vfs_inode_create() 248 248 249 ///////////////////////////////////////////// 250 void vfs_inode_destroy( vfs_inode_t * inode ) 251 { 252 if( inode->refcount ) 253 { 254 assert( false , __FUNCTION__ , "inode refcount non zero\n" ); 255 } 249 //////////////////////////////////////////////// 250 error_t vfs_inode_destroy( vfs_inode_t * inode ) 251 { 252 assert( (inode->refcount == 0), __FUNCTION__ , "inode refcount non zero\n" ); 256 253 257 254 // release memory allocated for mapper … … 264 261 kmem_free( &req ); 265 262 263 return 0; 264 266 265 } // end vfs_inode_destroy() 267 266 … … 315 314 return error; 316 315 317 } // end vfs_ load_inode()316 } // end vfs_inode_load() 318 317 319 318 //////////////////////////////////////////// … … 432 431 vfs_dentry_t * dentry; // dentry descriptor (to be allocated) 433 432 kmem_req_t req; // request to kernel memory allocator 433 error_t error; 434 434 435 435 #if DEBUG_VFS_DENTRY_CREATE 436 436 uint32_t cycle = (uint32_t)hal_get_cycles(); 437 437 if( DEBUG_VFS_DENTRY_CREATE < cycle ) 438 printk("\n[DBG] %s : thread %x enter for <%s> / parent_inode %x / cycle %d\n",439 __FUNCTION__, CURRENT_THREAD , name , parent, cycle );438 printk("\n[DBG] %s : thread %x in process %x enter for <%s> / parent_inode %x / cycle %d\n", 439 __FUNCTION__, CURRENT_THREAD->trdid, CURRENT_THREAD->process->pid, name, parent, cycle ); 440 440 #endif 441 441 … … 444 444 else if( fs_type == FS_TYPE_RAMFS ) ctx = &fs_context[FS_TYPE_RAMFS]; 445 445 else if( fs_type == FS_TYPE_DEVFS ) ctx = &fs_context[FS_TYPE_DEVFS]; 446 else 446 else 447 447 { 448 448 ctx = NULL; 449 assert( false , __FUNCTION__ , "undefined file system type\n" );449 return EINVAL; 450 450 } 451 451 … … 453 453 uint32_t length = strlen( name ); 454 454 455 if( length >= CONFIG_VFS_MAX_NAME_LENGTH ) 456 { 457 458 #if DEBUG_SYSCALLS_ERROR 459 printk("\n[ERROR] in %s : name <name> too long\n", __FUNCTION__ , name ); 460 #endif 461 return EINVAL; 462 } 455 if( length >= CONFIG_VFS_MAX_NAME_LENGTH ) return EINVAL; 463 456 464 457 // allocate memory for dentry descriptor … … 468 461 dentry = (vfs_dentry_t *)kmem_alloc( &req ); 469 462 470 if( dentry == NULL ) 471 { 472 473 #if DEBUG_SYSCALLS_ERROR 474 printk("\n[ERROR] in %s : cannot allocate dentry\n", __FUNCTION__ ); 475 #endif 476 return ENOMEM; 477 } 463 if( dentry == NULL ) return ENOMEM; 478 464 479 465 // initialize dentry descriptor … … 491 477 492 478 // register dentry in hash table rooted in parent inode 493 xhtab_insert( XPTR( local_cxy , &parent->children ), 494 name, 495 XPTR( local_cxy , &dentry->list ) ); 479 error = xhtab_insert( XPTR( local_cxy , &parent->children ), 480 name, 481 XPTR( local_cxy , &dentry->list ) ); 482 483 if( error ) return EINVAL; 496 484 497 485 #if( DEBUG_VFS_DENTRY_CREATE & 1 ) … … 507 495 cycle = (uint32_t)hal_get_cycles(); 508 496 if( DEBUG_VFS_DENTRY_CREATE < cycle ) 509 printk("\n[DBG] %s : thread %x exit for <%s> / dentry %x / cycle %d\n",510 __FUNCTION__, CURRENT_THREAD , name , dentry, cycle );497 printk("\n[DBG] %s : thread %x in process %x exit for <%s> / dentry %x / cycle %d\n", 498 __FUNCTION__, CURRENT_THREAD->trdid, CURRENT_THREAD->process->pid, name, dentry, cycle ); 511 499 #endif 512 500 … … 515 503 } // end vfs_dentry_create() 516 504 517 //////////////////////////////////////////////// 518 void vfs_dentry_destroy( vfs_dentry_t * dentry ) 519 { 520 if( dentry->refcount ) 521 { 522 assert( false , __FUNCTION__ , "dentry refcount non zero\n" ); 523 } 524 505 /////////////////////////////////////////////////// 506 error_t vfs_dentry_destroy( vfs_dentry_t * dentry ) 507 { 508 error_t error; 509 510 assert( (dentry->refcount == 0) , __FUNCTION__ , "dentry refcount non zero\n" ); 511 512 // get pointer on parent inode 513 vfs_inode_t * parent = dentry->parent; 514 515 // remove this dentry from parent inode htab 516 error = xhtab_remove( XPTR( local_cxy , &parent->children ), 517 dentry->name, 518 XPTR( local_cxy , &dentry->list ) ); 519 520 if( error ) return EINVAL; 521 522 // release memory allocated to dentry 525 523 kmem_req_t req; 526 524 req.ptr = dentry; 527 525 req.type = KMEM_VFS_DENTRY; 528 526 kmem_free( &req ); 527 528 return 0; 529 529 } 530 530 … … 564 564 565 565 *file_xp = XPTR( local_cxy , file ); 566 567 #if DEBUG_VFS_OPEN 568 uint32_t cycle = (uint32_t)hal_get_cycles(); 569 if( DEBUG_VFS_OPEN < cycle ) 570 printk("\n[DBG] %s : thread %x in process %x created file %x in cluster %x / cycle %d\n", 571 __FUNCTION__, CURRENT_THREAD->trdid, CURRENT_THREAD->process->pid, file, local_cxy, cycle ); 572 #endif 573 566 574 return 0; 567 575 … … 581 589 kmem_free( &req ); 582 590 591 #if DEBUG_VFS_CLOSE 592 uint32_t cycle = (uint32_t)hal_get_cycles(); 593 if( DEBUG_VFS_CLOSE < cycle ) 594 printk("\n[DBG] %s : thread %x in process %x deleted file %x in cluster %x / cycle %d\n", 595 __FUNCTION__, CURRENT_THREAD->trdid, CURRENT_THREAD->process->pid, file, local_cxy, cycle ); 596 #endif 597 583 598 } // end vfs_file_destroy() 584 599 … … 589 604 // get file cluster and local pointer 590 605 cxy_t file_cxy = GET_CXY( file_xp ); 591 vfs_file_t * file_ptr = (vfs_file_t *)GET_PTR( file_xp );606 vfs_file_t * file_ptr = GET_PTR( file_xp ); 592 607 593 608 // atomically increment count … … 600 615 // get file cluster and local pointer 601 616 cxy_t file_cxy = GET_CXY( file_xp ); 602 vfs_file_t * file_ptr = (vfs_file_t *)GET_PTR( file_xp );617 vfs_file_t * file_ptr = GET_PTR( file_xp ); 603 618 604 619 // atomically decrement count … … 630 645 uint32_t cycle = (uint32_t)hal_get_cycles(); 631 646 if( DEBUG_VFS_OPEN < cycle ) 632 printk("\n[DBG] %s : thread %x enter for <%s> / cycle %d\n",633 __FUNCTION__, CURRENT_THREAD , path, cycle );647 printk("\n[DBG] %s : thread %x in process %x enter for <%s> / cycle %d\n", 648 __FUNCTION__, CURRENT_THREAD->trdid, CURRENT_THREAD->process->pid, path, cycle ); 634 649 #endif 635 650 … … 677 692 cycle = (uint32_t)hal_get_cycles(); 678 693 if( DEBUG_VFS_OPEN < cycle ) 679 printk("\n[DBG] %s : thread %x exit for <%s> / file %x in cluster %x / cycle %d\n", 680 __FUNCTION__, CURRENT_THREAD, path, GET_PTR(file_xp), GET_CXY(file_xp), cycle ); 694 printk("\n[DBG] %s : thread %x in process %x exit for <%s> / fdid %d / cluster %x / cycle %d\n", 695 __FUNCTION__, CURRENT_THREAD->trdid, CURRENT_THREAD->process->pid, path, 696 file_id, GET_CXY( file_xp ), cycle ); 681 697 #endif 682 698 … … 868 884 uint32_t file_id ) 869 885 { 886 cluster_t * cluster; // local pointer on local cluster 887 cxy_t file_cxy; // cluster containing the file descriptor. 888 vfs_file_t * file_ptr; // local ponter on file descriptor 889 cxy_t owner_cxy; // process owner cluster 890 lpid_t lpid; // process local index 891 xptr_t root_xp; // root of list of process copies 892 xptr_t lock_xp; // lock protecting the list of copies 893 xptr_t iter_xp; // iterator on list of process copies 894 xptr_t process_xp; // extended pointer on one process copy 895 cxy_t process_cxy; // process copy cluster 896 process_t * process_ptr; // process copy local pointer 897 870 898 assert( (file_xp != XPTR_NULL) , __FUNCTION__ , "file_xp == XPTR_NULL" ); 871 899 … … 875 903 process_t * process = this->process; 876 904 877 // get cluster and local pointer on remote file descriptor 878 cxy_t file_cxy = GET_CXY( file_xp ); 879 vfs_file_t * file_ptr = (vfs_file_t *)GET_PTR( file_xp ); 905 #if DEBUG_VFS_CLOSE 906 uint32_t cycle = (uint32_t)hal_get_cycles(); 907 if( DEBUG_VFS_CLOSE < cycle ) 908 printk("\n[DBG] %s : thread %x in process %x enter / fdid %d / cycle %d\n", 909 __FUNCTION__, this->trdid, process->pid, file_id, cycle ); 910 #endif 880 911 881 912 // get local pointer on local cluster manager 882 cluster _t * cluster= LOCAL_CLUSTER;913 cluster = LOCAL_CLUSTER; 883 914 884 915 // get owner process cluster and lpid 885 cxy_towner_cxy = CXY_FROM_PID( process->pid );886 lpid _t lpid= LPID_FROM_PID( process->pid );916 owner_cxy = CXY_FROM_PID( process->pid ); 917 lpid = LPID_FROM_PID( process->pid ); 887 918 888 919 // get extended pointers on copies root and lock 889 xptr_t root_xp = XPTR( owner_cxy , &cluster->pmgr.copies_root[lpid] ); 890 xptr_t lock_xp = XPTR( owner_cxy , &cluster->pmgr.copies_lock[lpid] ); 891 892 // take the lock protecting the copies 920 root_xp = XPTR( owner_cxy , &cluster->pmgr.copies_root[lpid] ); 921 lock_xp = XPTR( owner_cxy , &cluster->pmgr.copies_lock[lpid] ); 922 923 // 1) loop on the process descriptor copies to reset all fd_array[file_id] entries 924 925 // take the lock protecting the list of copies 893 926 remote_spinlock_lock( lock_xp ); 894 927 895 // 1) loop on the process descriptor copies to cancel all fd_array[file_id] entries896 xptr_t iter_xp;897 928 XLIST_FOREACH( root_xp , iter_xp ) 898 929 { 899 xptr_t process_xp = XLIST_ELEMENT( iter_xp , process_t , copies_list ); 900 cxy_t process_cxy = GET_CXY( process_xp ); 901 process_t * process_ptr = (process_t *)GET_PTR( process_xp ); 902 903 xptr_t lock_xp = XPTR( process_cxy , &process_ptr->fd_array.lock ); 904 xptr_t entry_xp = XPTR( process_cxy , &process_ptr->fd_array.array[file_id] ); 905 906 // lock is required for atomic write of a 64 bits word 907 remote_rwlock_wr_lock( lock_xp ); 930 process_xp = XLIST_ELEMENT( iter_xp , process_t , copies_list ); 931 process_cxy = GET_CXY( process_xp ); 932 process_ptr = GET_PTR( process_xp ); 933 934 #if (DEBUG_VFS_CLOSE & 1 ) 935 if( DEBUG_VFS_CLOSE < cycle ) 936 printk("\n[DBG] %s : reset fd_array[%d] for process %x in cluster %x\n", 937 __FUNCTION__, file_id, process_ptr, process_cxy ); 938 #endif 939 940 // fd_array lock is required for atomic write of a 64 bits word 941 // xptr_t fd_array_lock_xp = XPTR( process_cxy , &process_ptr->fd_array.lock ); 942 943 xptr_t entry_xp = XPTR( process_cxy , &process_ptr->fd_array.array[file_id] ); 944 945 // remote_rwlock_wr_lock( fd_array_lock_xp ); 946 908 947 hal_remote_swd( entry_xp , XPTR_NULL ); 909 remote_rwlock_wr_unlock( lock_xp ); 948 949 // remote_rwlock_wr_unlock( fd_array_lock_xp ); 950 951 vfs_file_count_down( file_xp ); 910 952 911 953 hal_fence(); 912 954 } 913 955 956 // release the lock protecting the list of copies 957 remote_spinlock_unlock( lock_xp ); 958 959 #if (DEBUG_VFS_CLOSE & 1) 960 if( DEBUG_VFS_CLOSE < cycle ) 961 printk("\n[DBG] %s : thread %x in process %x reset all fd-array copies\n", 962 __FUNCTION__, this->trdid, process->pid ); 963 #endif 964 914 965 // 2) release memory allocated to file descriptor in remote cluster 966 967 // get cluster and local pointer on remote file descriptor 968 file_cxy = GET_CXY( file_xp ); 969 file_ptr = GET_PTR( file_xp ); 970 915 971 if( file_cxy == local_cxy ) // file cluster is local 916 972 { … … 921 977 rpc_vfs_file_destroy_client( file_cxy , file_ptr ); 922 978 } 979 980 #if DEBUG_VFS_CLOSE 981 cycle = (uint32_t)hal_get_cycles(); 982 if( DEBUG_VFS_CLOSE < cycle ) 983 printk("\n[DBG] %s : thread %x in process %x exit / fdid %d closed / cycle %d\n", 984 __FUNCTION__, this->trdid, process->pid, file_id, cycle ); 985 #endif 923 986 924 987 return 0; … … 1351 1414 cxy_t child_cxy; // cluster for child inode 1352 1415 vfs_inode_t * child_ptr; // local pointer on child inode 1353 vfs_inode_type_t child_type; // child inode type1354 1416 vfs_fs_type_t fs_type; // File system type 1355 1417 vfs_ctx_t * ctx_ptr; // local pointer on FS context … … 1358 1420 bool_t last; // true when the name is the last in path 1359 1421 bool_t found; // true when a child has been found 1422 bool_t dir; // searched inode is a directory 1423 bool_t create; // searched inode must be created if not found 1424 bool_t excl; // searched inode must not exist 1360 1425 thread_t * this; // pointer on calling thread descriptor 1361 1426 process_t * process; // pointer on calling process descriptor … … 1368 1433 uint32_t cycle = (uint32_t)hal_get_cycles(); 1369 1434 if( DEBUG_VFS_LOOKUP < cycle ) 1370 printk("\n[DBG] %s : thread %x enter for <%s> / cycle %d\n", 1371 __FUNCTION__, CURRENT_THREAD, pathname, cycle ); 1372 #endif 1373 1435 printk("\n[DBG] %s : thread %x in process %x enter for <%s> / cycle %d\n", 1436 __FUNCTION__, this->trdid, process->pid, pathname, cycle ); 1437 #endif 1438 1439 // compute lookup flags 1440 dir = mode & VFS_LOOKUP_DIR; 1441 create = mode & VFS_LOOKUP_CREATE; 1442 excl = mode & VFS_LOOKUP_EXCL; 1443 1374 1444 // get extended pointer on first inode to search 1375 1445 if( pathname[0] == '/' ) parent_xp = process->vfs_root_xp; … … 1386 1456 1387 1457 // sequencially loop on nodes in pathname 1388 // load from device if one node not found in inode tree1458 // load from device if one node in path not found in inode tree 1389 1459 // exit loop when last name found (i.e. last == true) 1390 1460 do … … 1395 1465 #if (DEBUG_VFS_LOOKUP & 1) 1396 1466 if( DEBUG_VFS_LOOKUP < cycle ) 1397 printk("\n[DBG] %s : look for <%s> / last = %d\n", __FUNCTION__ , name , last ); 1467 printk("\n[DBG] %s : look for <%s> / last = %d\n", 1468 __FUNCTION__ , name , last ); 1398 1469 #endif 1399 1470 … … 1403 1474 &child_xp ); 1404 1475 1405 // if a child inode is not found in the inode tree: 1406 // - we create the missing inode/dentry couple in the inode tree, 1407 // - we scan the parent mapper to complete the child inode (type and extension), 1408 // - we return an error if child not found on device. 1409 // - if the missing child is a directory, we load the child mapper from device 1410 1411 // for the last name, the behaviour depends on the "mode" argument: 1412 1413 if (found == false ) // child node not found in inode tree 1476 if (found == false ) // child not found in inode tree 1414 1477 { 1415 1478 1416 1479 #if (DEBUG_VFS_LOOKUP & 1) 1417 1480 if( DEBUG_VFS_LOOKUP < cycle ) 1418 printk("\n[DBG] %s : miss <%s> => load it\n", __FUNCTION__ , name ); 1419 #endif 1481 printk("\n[DBG] %s : miss <%s> node => try to create it\n", 1482 __FUNCTION__ , name ); 1483 #endif 1484 // if a child node is not found in the inode tree, 1485 // we introduce a new (dentry/inode) in inode tree, 1486 // and try to find it by scanning the parent directory mapper. 1487 // . if it is found in parent mapper: 1488 // - if the child is a directory, the child mapper is loaded from device 1489 // - if the child is not a directory, the search is completed 1490 // . if it is not found in the parent mapper: 1491 // - if ( not last or not create ) an error is reported 1492 // - if (last and create and dir) a new directory is created 1493 // - if (last and create and not dir) a new file is created 1420 1494 1421 1495 // release lock on parent inode 1422 1496 vfs_inode_unlock( parent_xp ); 1423 1497 1424 1498 // get parent inode FS type 1425 1499 parent_cxy = GET_CXY( parent_xp ); 1426 parent_ptr = (vfs_inode_t *)GET_PTR( parent_xp );1427 ctx_ptr = (vfs_ctx_t *)hal_remote_lpt( XPTR( parent_cxy ,&parent_ptr->ctx ) );1500 parent_ptr = GET_PTR( parent_xp ); 1501 ctx_ptr = (vfs_ctx_t *)hal_remote_lpt( XPTR( parent_cxy,&parent_ptr->ctx ) ); 1428 1502 fs_type = hal_remote_lw( XPTR( parent_cxy , &ctx_ptr->type ) ); 1429 1503 … … 1431 1505 child_cxy = vfs_cluster_random_select(); 1432 1506 1433 // insert a new child dentry/inode in parent inode1507 // insert a new child dentry/inode in inode tree 1434 1508 error = vfs_add_child_in_parent( child_cxy, 1435 INODE_TYPE_DIR,1509 0, // type will be updated later 1436 1510 fs_type, 1437 1511 parent_xp, 1438 1512 name, 1439 NULL, // fs_type_specific inode extend1513 NULL, // fs_type_specific inode extend 1440 1514 &child_xp ); 1441 1515 if( error ) 1442 1516 { 1443 printk("\n[ERROR] in %s : thread %x cannot allocate inodefor path <%s>\n",1444 __FUNCTION__ , this, pathname );1517 printk("\n[ERROR] in %s : cannot create node %s for path <%s>\n", 1518 __FUNCTION__ , name, pathname ); 1445 1519 return ENOMEM; 1446 1520 } 1447 1521 1448 // scan parent mapper to complete the missing inode 1522 // get child inode cluster and local pointer 1523 child_cxy = GET_CXY( child_xp ); 1524 child_ptr = GET_PTR( child_xp ); 1525 1526 #if (DEBUG_VFS_LOOKUP & 1) 1527 if( DEBUG_VFS_LOOKUP < cycle ) 1528 printk("\n[DBG] %s : missing <%s> inode speculatively created / cxy %x / ptr %x\n", 1529 __FUNCTION__ , name , child_cxy, child_ptr ); 1530 #endif 1531 // scan parent mapper to complete the missing inode 1449 1532 if( parent_cxy == local_cxy ) 1450 1533 { … … 1462 1545 } 1463 1546 1464 if ( error ) 1547 if ( error ) // child not found in parent mapper 1465 1548 { 1466 printk("\n[ERROR] in %s : thread %x / <%s> node not found in <%s>\n", 1467 __FUNCTION__ , this , name , pathname ); 1468 return ENOENT; 1469 } 1470 1471 // get child inode type 1472 child_ptr = (vfs_inode_t *)GET_PTR( child_xp ); 1473 child_type = hal_remote_lw( XPTR( child_cxy , &child_ptr->type ) ); 1474 1475 // load child mapper from device if it is a directory 1476 if( child_type == INODE_TYPE_DIR ) 1477 { 1478 if( child_cxy == local_cxy ) 1549 if( last && create && dir ) // new directory => update inode type 1479 1550 { 1480 error = vfs_mapper_load_all( child_ptr ); 1551 hal_remote_sw( XPTR( child_cxy, &child_ptr->type ), INODE_TYPE_DIR ); 1552 1553 #if (DEBUG_VFS_LOOKUP & 1) 1554 if( DEBUG_VFS_LOOKUP < cycle ) 1555 printk("\n[DBG] %s : created node <%s> in path %s / type DIR\n", 1556 __FUNCTION__ , name, pathname ); 1557 #endif 1481 1558 } 1482 else 1559 else if ( last && create ) // new file => update inode type 1483 1560 { 1484 rpc_vfs_mapper_load_all_client( child_cxy, 1485 child_ptr, 1486 &error ); 1561 hal_remote_sw( XPTR( child_cxy, &child_ptr->type ), INODE_TYPE_FILE ); 1562 1563 #if (DEBUG_VFS_LOOKUP & 1) 1564 if( DEBUG_VFS_LOOKUP < cycle ) 1565 printk("\n[DBG] %s : created node <%s> in path %s / type FILE\n", 1566 __FUNCTION__ , name, pathname ); 1567 #endif 1487 1568 } 1488 1489 if ( error )1490 {1491 printk("\n[ERROR] in %s : thread %x / cannot access device for <%s>\n",1492 __FUNCTION__ , this , name);1493 return EIO;1569 else // not last or not create => remove created node 1570 { 1571 printk("\n[ERROR] in %s : <%s> node not found in parent for <%s>\n", 1572 __FUNCTION__ , name , pathname ); 1573 vfs_remove_child_from_parent( child_xp ); 1574 return ENOENT; 1494 1575 } 1495 1576 } 1496 1497 // TODO handle lookup mode here [AG] 1577 else // child found in parent 1578 { 1579 // load child mapper from device if child is a directory (prefetch) 1580 if( hal_remote_lw( XPTR( child_cxy , &child_ptr->type ) ) == INODE_TYPE_DIR ) 1581 { 1582 if( child_cxy == local_cxy ) 1583 { 1584 error = vfs_mapper_load_all( child_ptr ); 1585 } 1586 else 1587 { 1588 rpc_vfs_mapper_load_all_client( child_cxy, 1589 child_ptr, 1590 &error ); 1591 } 1592 if ( error ) 1593 { 1594 printk("\n[ERROR] in %s : cannot load <%s> from device\n", 1595 __FUNCTION__ , name ); 1596 vfs_remove_child_from_parent( child_xp ); 1597 return EIO; 1598 } 1599 1600 #if (DEBUG_VFS_LOOKUP & 1) 1601 if( DEBUG_VFS_LOOKUP < cycle ) 1602 printk("\n[DBG] %s : load mapper from device for node <%s> in path %s\n", 1603 __FUNCTION__ , name, pathname ); 1604 #endif 1605 } 1606 } 1498 1607 1499 1608 // take lock on parent inode 1500 1609 vfs_inode_lock( parent_xp ); 1501 1502 #if (DEBUG_VFS_LOOKUP & 1)1503 if( DEBUG_VFS_LOOKUP < cycle )1504 printk("\n[DBG] %s : created node <%s>\n", __FUNCTION__ , name );1505 #endif1506 1507 1610 } 1508 1611 else // child found in inode tree 1612 { 1613 1509 1614 #if (DEBUG_VFS_LOOKUP & 1) 1510 1615 if( DEBUG_VFS_LOOKUP < cycle ) … … 1512 1617 __FUNCTION__ , name , GET_PTR(child_xp) , GET_CXY(child_xp) ); 1513 1618 #endif 1619 child_ptr = GET_PTR( child_xp ); 1620 child_cxy = GET_CXY( child_xp ); 1621 parent_cxy = GET_CXY( parent_xp ); 1622 parent_ptr = GET_PTR( parent_xp ); 1623 1624 if( last && (mode & VFS_LOOKUP_CREATE) && (mode & VFS_LOOKUP_EXCL) ) 1625 { 1626 printk("\n[ERROR] in %s : node already exist <%s>\n", __FUNCTION__, name ); 1627 return EINVAL; 1628 } 1629 } 1514 1630 1515 1631 // TODO check access rights here [AG] … … 1540 1656 cycle = (uint32_t)hal_get_cycles(); 1541 1657 if( DEBUG_VFS_LOOKUP < cycle ) 1542 printk("\n[DBG] %s : thread %x exit for <%s> / inode %x in cluster %x / cycle %d\n", 1543 __FUNCTION__, CURRENT_THREAD, pathname, GET_PTR(child_xp), GET_CXY(child_xp), cycle ); 1658 printk("\n[DBG] %s : thread %x in process %x exit for <%s>\n" 1659 " parent %x in cluster %x / child %x in cluster %x / cycle %d\n", 1660 __FUNCTION__ , this->trdid, process->pid, pathname, 1661 parent_ptr, parent_cxy, child_ptr, child_cxy, cycle ); 1544 1662 #endif 1545 1663 1546 1664 // return searched pointer 1547 *inode_xp = child_xp; 1665 if( mode & VFS_LOOKUP_PARENT ) *inode_xp = parent_xp; 1666 else *inode_xp = child_xp; 1548 1667 1549 1668 return 0; … … 1638 1757 // get parent inode cluster and local pointer 1639 1758 parent_cxy = GET_CXY( parent_xp ); 1640 parent_ptr = (vfs_inode_t *)GET_PTR( parent_xp );1759 parent_ptr = GET_PTR( parent_xp ); 1641 1760 1642 1761 #if DEBUG_VFS_ADD_CHILD 1643 1762 uint32_t cycle = (uint32_t)hal_get_cycles(); 1644 1763 if( DEBUG_VFS_ADD_CHILD < cycle ) 1645 printk("\n[DBG] %s : thread %x enter for <%s> / child_cxy = %x / parent_cxy = %x\n", 1646 __FUNCTION__ , CURRENT_THREAD , name , child_cxy , parent_cxy ); 1764 printk("\n[DBG] %s : thread %x enter for <%s> / child_cxy = %x / parent_cxy = %x / cycle %d\n", 1765 __FUNCTION__, CURRENT_THREAD->trdid, CURRENT_THREAD->process->pid, name, 1766 child_cxy, parent_cxy, (uint32_t)hal_get_cycles() ); 1647 1767 #endif 1648 1768 … … 1736 1856 __FUNCTION__ , child_cxy ); 1737 1857 1738 vfs_dentry_t * dentry = (vfs_dentry_t *)GET_PTR( dentry_xp );1858 vfs_dentry_t * dentry = GET_PTR( dentry_xp ); 1739 1859 if( parent_cxy == local_cxy ) vfs_dentry_destroy( dentry ); 1740 else rpc_vfs_dentry_destroy_client( parent_cxy , dentry );1860 else rpc_vfs_dentry_destroy_client( parent_cxy , dentry , &error ); 1741 1861 return ENOMEM; 1742 1862 } … … 1750 1870 cycle = (uint32_t)hal_get_cycles(); 1751 1871 if( DEBUG_VFS_ADD_CHILD < cycle ) 1752 printk("\n[DBG] %s : thread %x exit for <%s>\n",1753 __FUNCTION__ , CURRENT_THREAD, name );1872 printk("\n[DBG] %s : thread %x in process %x exit for <%s>\n", 1873 __FUNCTION__, CURRENT_THREAD, CURRENT_THREAD->process->pid, name ); 1754 1874 #endif 1755 1875 … … 1758 1878 return 0; 1759 1879 1880 // FIXME update the refcount fields in both inode and dentry 1881 1760 1882 } // end vfs_add_child_in_parent() 1883 1884 /////////////////////////////////////////////////////// 1885 error_t vfs_remove_child_from_parent( xptr_t inode_xp ) 1886 { 1887 cxy_t inode_cxy; 1888 vfs_inode_t * inode_ptr; 1889 xptr_t dentry_xp; 1890 cxy_t dentry_cxy; 1891 vfs_dentry_t * dentry_ptr; 1892 error_t error; 1893 1894 // get inode cluster and local pointer 1895 inode_cxy = GET_CXY( inode_xp ); 1896 inode_ptr = GET_PTR( inode_xp ); 1897 1898 // get cluster and pointers of associated dentry 1899 dentry_xp = hal_remote_lwd( XPTR( inode_cxy , &inode_ptr->parent_xp ) ); 1900 dentry_cxy = GET_CXY( dentry_xp ); 1901 dentry_ptr = GET_PTR( dentry_xp ); 1902 1903 // FIXME update the refcount fields in both inode and dentry 1904 1905 // delete dentry 1906 if( dentry_cxy == local_cxy ) 1907 { 1908 error = vfs_dentry_destroy( dentry_ptr ); 1909 } 1910 else 1911 { 1912 rpc_vfs_dentry_destroy_client( dentry_cxy, 1913 dentry_ptr, 1914 &error ); 1915 } 1916 if( error ) return EINVAL; 1917 1918 // delete inode 1919 if( inode_cxy == local_cxy ) 1920 { 1921 vfs_inode_destroy( inode_ptr ); 1922 } 1923 else 1924 { 1925 rpc_vfs_inode_destroy_client( inode_cxy, 1926 inode_ptr, 1927 &error ); 1928 } 1929 if( error ) return EINVAL; 1930 1931 return 0; 1932 1933 } // end vfs_remove_child_from_parent() 1761 1934 1762 1935 ////////////////////////////////////////////////////////////////////////////////////////// -
trunk/kernel/fs/vfs.h
r457 r459 227 227 * It is not replicated, and is dynamically allocated in the cluster that contains 228 228 * the inode, when a thread makes an open() or opendir() system call. 229 * It cannot exist a file structure without an inode structure .229 * It cannot exist a file structure without an inode structure in same cluster. 230 230 * As the fd_array (containing extended pointers on the open file descriptors) 231 231 * is replicated in all process descriptors, we need a references counter. … … 338 338 * @ gid : group owner ID. 339 339 * @ inode_xp : [out] buffer for extended pointer on created inode. 340 * #return 0 if success / return ENOMEM or EINVAL if error.340 * @ return 0 if success / return ENOMEM or EINVAL if error. 341 341 *****************************************************************************************/ 342 342 error_t vfs_inode_create( xptr_t dentry_xp, … … 353 353 * This function releases memory allocated to an inode descriptor. 354 354 * It must be executed by a thread running in the cluster containing the inode, 355 * and the inode refcount must be zero. 356 * If the client thread is not running in the owner cluster, it must use the 357 * rpc_vfs_inode_destroy_client() function. 355 * and the inode refcount must be zero. If the client thread is not running in the owner 356 * cluster, you must use the rpc_vfs_inode_destroy_client() function. 358 357 ****************************************************************************************** 359 358 * @ inode : local pointer on inode descriptor. 360 *****************************************************************************************/ 361 void vfs_inode_destroy( vfs_inode_t * inode ); 359 * @ return 0 if success / return EINVAL if error. 360 *****************************************************************************************/ 361 error_t vfs_inode_destroy( vfs_inode_t * inode ); 362 362 363 363 /****************************************************************************************** … … 432 432 433 433 434 435 436 437 438 /******************************************************************************************439 * This function TODO440 *****************************************************************************************/441 error_t vfs_inode_trunc( vfs_inode_t * inode );442 443 /******************************************************************************************444 * This function TODO445 *****************************************************************************************/446 error_t vfs_inode_link( vfs_inode_t * inode,447 uint32_t igc );448 449 /******************************************************************************************450 * This function TODO451 *****************************************************************************************/452 error_t vfs_inode_unlink( vfs_inode_t * inode );453 454 455 434 /*****************************************************************************************/ 456 435 /***************** Dentry related functions **********************************************/ … … 478 457 * This function releases memory allocated to a dentry descriptor. 479 458 * It must be executed by a thread running in the cluster containing the dentry, 480 * and the dentry refcount must be zero. 481 * If the client thread is not running in the owner cluster, it must use the 482 * rpc_dentry_destroy_client() function. 459 * and the dentry refcount must be zero. If the client thread is not running in the owner 460 * cluster, you must use the rpc_dentry_destroy_client() function. 483 461 ****************************************************************************************** 484 462 * @ dentry : local pointer on dentry descriptor. 485 *****************************************************************************************/ 486 void vfs_dentry_destroy( vfs_dentry_t * dentry ); 463 * @ return 0 if success / return EINVAL if error. 464 *****************************************************************************************/ 465 error_t vfs_dentry_destroy( vfs_dentry_t * dentry ); 487 466 488 467 /****************************************************************************************** … … 562 541 * This function takes a pathname (absolute or relative to cwd) and returns an extended 563 542 * pointer on the associated inode. 564 * - If a given name in the path is not found in the inode tree, it try to load the missing565 * dentry/inode couple, from informations found in the parent directory.543 * - If a given directory name in the path is not found in the inode tree, it try to load 544 * the missing dentry/inode couple, from informations found in the parent directory. 566 545 * - If this directory entry does not exist on device, it returns an error. 567 546 * - If the the file identified by the pathname does not exist on device but the … … 613 592 * This function removes a couple dentry/inode from the Inode-Tree, and remove it from 614 593 * the external device. 615 * TODO616 594 ****************************************************************************************** 617 595 * @ child_xp : extended pointer on removed inode. 618 596 *****************************************************************************************/ 619 error_t vfs_remove_child_from_parent( xptr_t child_xp );597 error_t vfs_remove_child_from_parent( xptr_t inode_xp ); 620 598 621 599 /****************************************************************************************** … … 716 694 717 695 /****************************************************************************************** 718 * This function close an open file descriptor: 719 * 1) All entries in fd_array copies are directly cancelled by the calling thread, 696 * This function close the -non-replicated- file descriptor identified by the <file_xp> 697 * and <file_id> arguments. 698 * 1) All entries in the fd_array copies are directly reset by the calling thread, 720 699 * using remote accesses. 721 700 * 2) The memory allocated to file descriptor in cluster containing the inode is released. 722 701 * It requires a RPC if cluster containing the file descriptor is remote. 723 702 ****************************************************************************************** 724 * @ file_xp : extended pointer on the file descriptor .703 * @ file_xp : extended pointer on the file descriptor in owner cluster. 725 704 * @ file_id : file descriptor index in fd_array. 726 705 * @ returns 0 if success / -1 if error. … … 848 827 849 828 /****************************************************************************************** 850 * This function makes I/O operations to move, from device to mapper, all pages covering 851 * a given inode, identified by the <inode> argument. Inode be a directory or a file, 852 * but this function is mainly used to load (prefetch) a complete directory to the mapper. 829 * This function makes the I/O operations required to move, from device to mapper, 830 * all pages covering a given inode, identified by the <inode> argument. The target 831 * inode can be a directory or a file, but this function is mainly used to load (prefetch) 832 * a complete directory to the mapper. 853 833 * Depending on the file system type, it calls the proper, FS specific function. 854 834 * It must be executed by a thread running in the cluster containing the mapper. … … 862 842 863 843 864 865 /* deprecated [AG]866 867 typedef error_t (lookup_inode_t) ( vfs_inode_t * parent ,868 vfs_dentry_t * dentry );869 870 typedef error_t (write_inode_t) ( vfs_inode_t * inode );871 872 typedef error_t (release_inode_t) ( vfs_inode_t * inode );873 874 typedef error_t (unlink_inode_t) ( vfs_inode_t * parent,875 vfs_dentry_t * dentry,876 uint32_t flags );877 878 typedef error_t (stat_inode_t) ( vfs_inode_t * inode );879 880 typedef error_t (trunc_inode_t) ( vfs_inode_t * inode );881 882 typedef error_t (delete_inode_t) ( vfs_inode_t * inode );883 884 typedef struct vfs_inode_op_s885 {886 init_inode_t * init;887 create_inode_t * create;888 lookup_inode_t * lookup;889 write_inode_t * write;890 release_inode_t * release;891 unlink_inode_t * unlink;892 delete_inode_t * delete;893 stat_inode_t * stat;894 trunc_inode_t * trunc; // change the size of a file895 }896 vfs_inode_op_t;897 898 ******************************************************************************************899 * These typedef define the set of FS specific operations on a VFS DENTRY descriptor.900 * They must be implemented by any specific file system to be supported by ALMOS_MKH.901 * This code is not actually used, and is only defined for documentation902 ******************************************************************************************903 904 905 typedef error_t (vfs_compare_dentry_t) ( char * first , char * second );906 907 typedef struct vfs_dentry_op_s908 {909 vfs_compare_dentry_t * compare;910 }911 vfs_dentry_op_t;912 913 914 ******************************************************************************************915 * These typedef define the set of FS specific operations on FILE descriptors916 * They must be implemented by any specific file system to be supported by ALMOS_MKH.917 * This code is not actually used, and is only defined for documentation918 ******************************************************************************************919 920 921 typedef error_t (open_file_t ) ( vfs_file_t * file,922 void * extend );923 924 typedef error_t (read_file_t ) ( vfs_file_t * file,925 char * buffer,926 uint32_t count );927 928 typedef error_t (write_file_t ) ( vfs_file_t * file,929 char * buffer,930 uint32_t count );931 932 typedef error_t (lseek_file_t ) ( vfs_file_t * file );933 934 typedef error_t (close_file_t ) ( vfs_file_t * file );935 936 typedef error_t (release_file_t) ( vfs_file_t * file );937 938 typedef error_t (read_dir_t ) ( vfs_file_t * file );939 940 typedef error_t (mmap_file_t ) ( vfs_file_t * file ,941 struct vseg_s * vseg );942 943 typedef error_t (munmap_file_t ) ( vfs_file_t * file,944 struct vseg_s * vseg );945 946 typedef struct vfs_file_op_s947 {948 open_file_t * open;949 read_file_t * read;950 write_file_t * write;951 lseek_file_t * lseek;952 read_dir_t * readdir;953 close_file_t * close;954 release_file_t * release;955 mmap_file_t * mmap;956 munmap_file_t * munmap;957 }958 vfs_file_op_t;959 960 */961 962 844 #endif /* _VFS_H_ */
Note: See TracChangeset
for help on using the changeset viewer.