Changeset 610 for trunk/kernel/fs
- Timestamp:
- Dec 27, 2018, 7:38:58 PM (6 years ago)
- Location:
- trunk/kernel/fs
- Files:
-
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/kernel/fs/devfs.c
r602 r610 93 93 xptr_t unused_xp; // required by vfs_add_child_in_parent() 94 94 95 // create sDEVFS "dev" inode in cluster 095 // create DEVFS "dev" inode in cluster 0 96 96 error = vfs_add_child_in_parent( 0, // cxy 97 97 INODE_TYPE_DIR, … … 102 102 devfs_dev_inode_xp ); 103 103 104 assert( (error == 0) , "cannot create <dev>\n" ); 104 // check success 105 assert( (error == 0) , "cannot create <dev>\n" ); 105 106 106 107 #if DEBUG_DEVFS_INIT … … 149 150 // create "internal" directory 150 151 snprintf( node_name , 16 , "internal_%x" , local_cxy ); 152 151 153 vfs_add_child_in_parent( local_cxy, 152 154 INODE_TYPE_DIR, … … 169 171 { 170 172 chdev_ptr = GET_PTR( chdev_xp ); 173 chdev_cxy = GET_CXY( chdev_xp ); 174 175 assert( (chdev_cxy == local_cxy ), 176 "illegal MMC chdev_xp in cluster %x\n", local_cxy ); 177 171 178 vfs_add_child_in_parent( local_cxy, 172 179 INODE_TYPE_DEV, … … 198 205 { 199 206 chdev_ptr = GET_PTR( chdev_xp ); 207 chdev_cxy = GET_CXY( chdev_xp ); 208 209 assert( (chdev_cxy == local_cxy ), 210 "illegal DMA[%d] chdev_xp in cluster %x\n", channel, local_cxy ); 211 200 212 vfs_add_child_in_parent( local_cxy, 201 213 INODE_TYPE_DEV, … … 226 238 chdev_cxy = GET_CXY( chdev_xp ); 227 239 chdev_ptr = GET_PTR( chdev_xp ); 240 228 241 if( chdev_cxy == local_cxy ) 229 242 { … … 256 269 chdev_cxy = GET_CXY( chdev_xp ); 257 270 chdev_ptr = GET_PTR( chdev_xp ); 271 258 272 if( chdev_cxy == local_cxy ) 259 273 { … … 288 302 chdev_cxy = GET_CXY( chdev_xp ); 289 303 chdev_ptr = GET_PTR( chdev_xp ); 304 290 305 if( chdev_cxy == local_cxy ) 291 306 { … … 321 336 chdev_cxy = GET_CXY( chdev_xp ); 322 337 chdev_ptr = GET_PTR( chdev_xp ); 338 323 339 if( chdev_cxy == local_cxy ) 324 340 { … … 354 370 chdev_cxy = GET_CXY( chdev_xp ); 355 371 chdev_ptr = GET_PTR( chdev_xp ); 372 356 373 if( chdev_cxy == local_cxy ) 357 374 { … … 387 404 chdev_cxy = GET_CXY( chdev_xp ); 388 405 chdev_ptr = GET_PTR( chdev_xp ); 406 389 407 if( chdev_cxy == local_cxy ) 390 408 { … … 419 437 { 420 438 chdev_cxy = GET_CXY( chdev_xp ); 421 chdev_ptr = (chdev_t *)GET_PTR( chdev_xp ); 439 chdev_ptr = GET_PTR( chdev_xp ); 440 422 441 if( chdev_cxy == local_cxy ) 423 442 { … … 447 466 chdev_cxy = GET_CXY( chdev_xp ); 448 467 chdev_ptr = GET_PTR( chdev_xp ); 468 449 469 if( chdev_cxy == local_cxy ) 450 470 { -
trunk/kernel/fs/fatfs.c
r602 r610 1246 1246 vfs_inode_get_name( XPTR( local_cxy , inode ) , dir_name ); 1247 1247 if( DEBUG_FATFS_REMOVE_DENTRY < cycle ) 1248 printk("\n[%s] 1248 printk("\n[%s] thread[%x,%x] enter / parent <%s> / child <%s> / cycle %d\n", 1249 1249 __FUNCTION__, this->process->pid, this->trdid, dir_name, dentry->name, cycle ); 1250 1250 #endif … … 1280 1280 uint32_t page_id = dentry_id >> 7; 1281 1281 uint32_t offset = (dentry_id & 0x7F)<<5; 1282 1283 #if DEBUG_FATFS_REMOVE_DENTRY & 1 1284 if( DEBUG_FATFS_REMOVE_DENTRY < cycle ) 1285 printk("\n[%s] dentry_id %x / page_id %x / offset %x\n", 1286 __FUNCTION__, dentry_id, page_id, offset ); 1287 #endif 1282 1288 1283 1289 // get extended pointer on page descriptor from parent directory mapper … … 1345 1351 cycle = (uint32_t)hal_get_cycles(); 1346 1352 if( DEBUG_FATFS_REMOVE_DENTRY < cycle ) 1347 printk("\n[%s] 1353 printk("\n[%s] thread[%x,%x] exit / parent %s / child %s / cycle %d\n", 1348 1354 __FUNCTION__, this->process->pid, this->trdid, dir_name, dentry->name, cycle ); 1349 1355 #endif … … 1358 1364 xptr_t child_inode_xp ) 1359 1365 { 1360 // Two embedded loops :1366 // Two embedded loops to scan the directory mapper: 1361 1367 // - scan the parent directory mapper pages 1362 1368 // - scan the directory entries in each 4 Kbytes page … … 1512 1518 // get child inode cluster and local pointer 1513 1519 cxy_t inode_cxy = GET_CXY( child_inode_xp ); 1514 vfs_inode_t * inode_ptr = (vfs_inode_t *)GET_PTR( child_inode_xp ); 1520 vfs_inode_t * inode_ptr = GET_PTR( child_inode_xp ); 1521 1522 // build extended pointer on parent dentried root 1523 xptr_t parents_root_xp = XPTR( inode_cxy , &inode_ptr->parents ); 1524 1525 // check child inode has at least one parent 1526 assert( (xlist_is_empty( parents_root_xp ) == false ), "child inode must have one parent\n"); 1515 1527 1516 1528 // get dentry pointers and cluster 1517 xptr_t dentry_xp = hal_remote_l64( XPTR( inode_cxy , &inode_ptr->parent_xp ) );1529 xptr_t dentry_xp = XLIST_FIRST( parents_root_xp , vfs_dentry_t , parents ); 1518 1530 vfs_dentry_t * dentry_ptr = GET_PTR( dentry_xp ); 1519 1531 cxy_t dentry_cxy = GET_CXY( dentry_xp ); 1520 1532 1521 // dentry descriptor must bein same cluster as parent inode1533 // check dentry descriptor in same cluster as parent inode 1522 1534 assert( (dentry_cxy == local_cxy) , "illegal dentry cluster\n" ); 1523 1535 -
trunk/kernel/fs/fatfs.h
r602 r610 311 311 * This function implements the generic vfs_fs_child_init() function for the FATFS. 312 312 ***************************************************************************************** 313 * It scan the mapper of an existing parent directory, identified by the <parent> 314 * argument, to find a directory entry identified by the <name> argument. 315 * It updates the existing remote child inode, identified by the <child_xp> argument, 313 * It tries to initialise a new child (new inode/dentry couple in Inode Tree), identified 314 * by the <child_inode_xp> argument, from the parent directory mapper, identified by the 315 * <parent_inode> argument. 316 * - It scan the parent mapper to find the <name> argument. 316 317 * - it set the "type", "size", and "extend" fields in inode descriptor. 317 318 * - it set the " extend" field in dentry descriptor. -
trunk/kernel/fs/vfs.c
r602 r610 141 141 } 142 142 143 ////////////////////////////////////////////////////// 144 error_t vfs_inode_create( xptr_t dentry_xp, 145 vfs_fs_type_t fs_type, 143 //////////////////////////////////////////////////// 144 error_t vfs_inode_create( vfs_fs_type_t fs_type, 146 145 vfs_inode_type_t inode_type, 147 146 uint32_t attr, … … 212 211 vfs_ctx_inum_release( ctx , inum ); 213 212 mapper_destroy( mapper ); 214 return ENOMEM;213 return -1; 215 214 } 216 215 217 216 // initialize inode descriptor 218 inode->gc = 0;219 217 inode->type = inode_type; 220 218 inode->inum = inum; … … 223 221 inode->uid = uid; 224 222 inode->gid = gid; 225 inode->refcount = 0;226 inode->parent_xp = dentry_xp;227 223 inode->ctx = ctx; 228 224 inode->mapper = mapper; 229 225 inode->extend = NULL; 226 inode->links = 0; 230 227 231 228 // initialise inode field in mapper … … 233 230 234 231 // initialise threads waiting queue 235 xlist_root_init( XPTR( local_cxy , &inode->wait_root ) );236 237 // initialize dentries hash table232 // xlist_root_init( XPTR( local_cxy , &inode->wait_root ) ); 233 234 // initialize chidren dentries xhtab 238 235 xhtab_init( &inode->children , XHTAB_DENTRY_TYPE ); 239 236 240 // initialize inode lock 241 remote_rwlock_init( XPTR( local_cxy , &inode->data_lock ), LOCK_VFS_INODE ); 242 243 // initialise lock protecting inode three traversal 244 remote_busylock_init( XPTR( local_cxy , &inode->main_lock ), LOCK_VFS_MAIN ); 237 // initialize parents dentries xlist 238 xlist_root_init( XPTR( local_cxy , &inode->parents ) ); 239 240 // initialize lock protecting size 241 remote_rwlock_init( XPTR( local_cxy , &inode->size_lock ), LOCK_VFS_SIZE ); 242 243 // initialise lock protecting inode tree traversal 244 remote_rwlock_init( XPTR( local_cxy , &inode->main_lock ), LOCK_VFS_MAIN ); 245 246 // return extended pointer on inode 247 *inode_xp = XPTR( local_cxy , inode ); 245 248 246 249 #if DEBUG_VFS_INODE_CREATE … … 251 254 #endif 252 255 253 // return extended pointer on inode254 *inode_xp = XPTR( local_cxy , inode );255 256 return 0; 256 257 … … 260 261 void vfs_inode_destroy( vfs_inode_t * inode ) 261 262 { 262 263 // check inode refcount264 assert( (inode->refcount == 0) , "inode refcount non zero\n" );265 266 263 // release memory allocated for mapper 267 264 mapper_destroy( inode->mapper ); … … 275 272 } // end vfs_inode_destroy() 276 273 277 ////////////////////////////////////////////278 void vfs_inode_remote_up( xptr_t inode_xp )279 {280 // get inode cluster and local pointer281 cxy_t inode_cxy = GET_CXY( inode_xp );282 vfs_inode_t * inode_ptr = GET_PTR( inode_xp );283 284 hal_remote_atomic_add( XPTR( inode_cxy , &inode_ptr->refcount ) , 1 );285 }286 287 //////////////////////////////////////////////288 void vfs_inode_remote_down( xptr_t inode_xp )289 {290 // get inode cluster and local pointer291 cxy_t inode_cxy = GET_CXY( inode_xp );292 vfs_inode_t * inode_ptr = GET_PTR( inode_xp );293 294 hal_remote_atomic_add( XPTR( inode_cxy , &inode_ptr->refcount ) , -1 );295 }296 297 274 ////////////////////////////////////////////// 298 275 uint32_t vfs_inode_get_size( xptr_t inode_xp ) … … 303 280 304 281 // get size 305 remote_rwlock_rd_acquire( XPTR( cxy , &ptr-> data_lock ) );282 remote_rwlock_rd_acquire( XPTR( cxy , &ptr->size_lock ) ); 306 283 uint32_t size = hal_remote_l32( XPTR( cxy , &ptr->size ) ); 307 remote_rwlock_rd_release( XPTR( cxy , &ptr-> data_lock ) );284 remote_rwlock_rd_release( XPTR( cxy , &ptr->size_lock ) ); 308 285 return size; 309 286 } … … 318 295 319 296 // set size 320 remote_rwlock_wr_release( XPTR( cxy , &ptr-> data_lock ) );297 remote_rwlock_wr_release( XPTR( cxy , &ptr->size_lock ) ); 321 298 hal_remote_s32( XPTR( cxy , &ptr->size ) , size ); 322 remote_rwlock_wr_release( XPTR( cxy , &ptr-> data_lock ) );299 remote_rwlock_wr_release( XPTR( cxy , &ptr->size_lock ) ); 323 300 } 324 301 … … 345 322 } 346 323 347 ///////////////////////////////////////// 348 void vfs_inode_get_name( xptr_t inode_xp, 349 char * name ) 350 { 351 cxy_t inode_cxy; 352 vfs_inode_t * inode_ptr; 353 xptr_t dentry_xp; 354 cxy_t dentry_cxy; 355 vfs_dentry_t * dentry_ptr; 324 /////////////////////////////////////////// 325 void vfs_inode_get_name( xptr_t inode_xp, 326 char * name ) 327 { 328 cxy_t inode_cxy; // inode cluster identifier 329 vfs_inode_t * inode_ptr; // local pointer on inode 330 xptr_t parents_root_xp; // extended pointer on inode parents root 356 331 357 332 // get inode cluster and local pointer … … 359 334 inode_ptr = GET_PTR( inode_xp ); 360 335 361 // get parent dentry362 dentry_xp = hal_remote_l64( XPTR( inode_cxy , &inode_ptr->parent_xp ));363 364 // get local copy of name365 if( dentry_xp == XPTR_NULL ) // itis the VFS root336 // build extended pointer on parents dentries root 337 parents_root_xp = XPTR( inode_cxy , &inode_ptr->parents ); 338 339 // check VFS root 340 if( xlist_is_empty( parents_root_xp ) ) // inode is the VFS root 366 341 { 367 342 strcpy( name , "/" ); 368 343 } 369 else // not the VFS root 370 { 344 else // not the VFS root 345 { 346 xptr_t dentry_xp; 347 cxy_t dentry_cxy; 348 vfs_dentry_t * dentry_ptr; 349 350 // get first name in list of parents 351 dentry_xp = XLIST_FIRST( parents_root_xp , vfs_dentry_t , parents ); 371 352 dentry_cxy = GET_CXY( dentry_xp ); 372 353 dentry_ptr = GET_PTR( dentry_xp ); 373 354 374 355 hal_remote_strcpy( XPTR( local_cxy , name ) , 375 XPTR( dentry_cxy , &dentry_ptr->name ) ); 376 } 356 XPTR( dentry_cxy , dentry_ptr->name ) ); 357 } 358 377 359 } // end vfs_inode_get_name() 378 360 … … 433 415 error_t vfs_dentry_create( vfs_fs_type_t fs_type, 434 416 char * name, 435 vfs_inode_t * parent,436 417 xptr_t * dentry_xp ) 437 418 { … … 439 420 vfs_dentry_t * dentry; // dentry descriptor (to be allocated) 440 421 kmem_req_t req; // request to kernel memory allocator 441 error_t error;442 422 443 423 #if DEBUG_VFS_DENTRY_CREATE … … 456 436 { 457 437 ctx = NULL; 458 return EINVAL;438 return -1; 459 439 } 460 440 … … 470 450 dentry = (vfs_dentry_t *)kmem_alloc( &req ); 471 451 472 if( dentry == NULL ) return ENOMEM; 452 if( dentry == NULL ) 453 { 454 printk("\n[ERROR] in %s : cannot allocate dentry descriptor\n", 455 __FUNCTION__ ); 456 return -1; 457 } 473 458 474 459 // initialize dentry descriptor 475 476 460 dentry->ctx = ctx; 477 461 dentry->length = length; 478 dentry->parent = parent;479 462 dentry->extend = NULL; 480 463 strcpy( dentry->name , name ); 481 482 #if( DEBUG_VFS_DENTRY_CREATE & 1 )483 cycle = (uint32_t)hal_get_cycles();484 if( DEBUG_VFS_DENTRY_CREATE < cycle )485 printk("\n[%s] thread[%x,%x] / dentry <%s> initialised / cycle %d\n",486 __FUNCTION__, this->process->pid, this->trdid, dentry->name, cycle );487 #endif488 489 // register dentry in hash table rooted in parent inode490 error = xhtab_insert( XPTR( local_cxy , &parent->children ),491 name,492 XPTR( local_cxy , &dentry->list ) );493 494 if( error ) return EINVAL;495 496 #if( DEBUG_VFS_DENTRY_CREATE & 1 )497 cycle = (uint32_t)hal_get_cycles();498 if( DEBUG_VFS_DENTRY_CREATE < cycle )499 printk("\n[%s] thread[%x,%x] / dentry <%s> registered / cycle %d\n",500 __FUNCTION__, this->process->pid, this->trdid, dentry->name, cycle );501 #endif502 464 503 465 // return extended pointer on dentry … … 518 480 void vfs_dentry_destroy( vfs_dentry_t * dentry ) 519 481 { 520 521 // check dentry refcount522 assert( (dentry->refcount == 0) , "dentry refcount non zero\n" );523 524 // get pointer on parent inode525 vfs_inode_t * parent = dentry->parent;526 527 // remove this dentry from parent inode htab528 xhtab_remove( XPTR( local_cxy , &parent->children ),529 dentry->name,530 XPTR( local_cxy , &dentry->list ) );531 532 482 // release memory allocated to dentry 533 483 kmem_req_t req; … … 537 487 538 488 } // end vfs_dentry_destroy() 539 540 //////////////////////////////////////////////541 void vfs_dentry_remote_up( xptr_t dentry_xp )542 {543 // get dentry cluster and local pointer544 cxy_t dentry_cxy = GET_CXY( dentry_xp );545 vfs_dentry_t * dentry_ptr = GET_PTR( dentry_xp );546 547 hal_remote_atomic_add( XPTR( dentry_cxy , &dentry_ptr->refcount ) , 1 );548 }549 550 ////////////////////////////////////////////////551 void vfs_dentry_remote_down( xptr_t dentry_xp )552 {553 // get dentry cluster and local pointer554 cxy_t dentry_cxy = GET_CXY( dentry_xp );555 vfs_dentry_t * dentry_ptr = GET_PTR( dentry_xp );556 557 hal_remote_atomic_add( XPTR( dentry_cxy , &dentry_ptr->refcount ) , -1 );558 }559 560 489 561 490 … … 616 545 void vfs_file_destroy( vfs_file_t * file ) 617 546 { 618 if( file->refcount ) 619 { 620 assert( false , "refcount non zero\n" ); 621 } 547 548 // check refcount 549 assert( (file->refcount == 0) , "refcount non zero\n" ); 622 550 623 551 kmem_req_t req; … … 664 592 665 593 ////////////////////////////////////// 666 error_t vfs_open( process_t * process,594 error_t vfs_open( xptr_t root_xp, 667 595 char * path, 596 xptr_t process_xp, 668 597 uint32_t flags, 669 598 uint32_t mode, … … 671 600 uint32_t * new_file_id ) 672 601 { 673 error_t error; 674 xptr_t inode_xp; // extended pointer on target inode 675 cxy_t inode_cxy; // inode cluster identifier 676 vfs_inode_t * inode_ptr; // inode local pointer 677 uint32_t file_attr; // file descriptor attributes 678 uint32_t lookup_mode; // lookup working mode 679 xptr_t file_xp; // extended pointer on created file descriptor 680 uint32_t file_id; // created file descriptor index in reference fd_array 681 602 error_t error; 603 xptr_t inode_xp; // extended pointer on target inode 604 cxy_t inode_cxy; // inode cluster identifier 605 vfs_inode_t * inode_ptr; // inode local pointer 606 uint32_t file_attr; // file descriptor attributes 607 uint32_t lookup_mode; // lookup working mode 608 xptr_t file_xp; // extended pointer on created file descriptor 609 uint32_t file_id; // created file descriptor index in reference fd_array 610 xptr_t vfs_root_xp; // extended pointer on VFS root inode 611 vfs_inode_t * vfs_root_ptr; // local pointer on VFS root inode 612 cxy_t vfs_root_cxy; // VFS root inode cluster identifier 613 xptr_t lock_xp; // extended pointer on Inode Tree lock 682 614 683 615 if( mode != 0 ) … … 687 619 } 688 620 621 thread_t * this = CURRENT_THREAD; 622 process_t * process = this->process; 623 689 624 #if DEBUG_VFS_OPEN 690 thread_t * this = CURRENT_THREAD;691 625 uint32_t cycle = (uint32_t)hal_get_cycles(); 692 626 if( DEBUG_VFS_OPEN < cycle ) 693 printk("\n[%s] thread[%x,%x] enter for <%s>/ cycle %d\n",694 __FUNCTION__, this->process->pid, this->trdid, path, cycle );627 printk("\n[%s] thread[%x,%x] enter for <%s> / root_inode (%x,%x) / cycle %d\n", 628 __FUNCTION__, process->pid, this->trdid, path, GET_CXY(root_xp), GET_PTR(root_xp), cycle ); 695 629 #endif 696 630 … … 709 643 if( (flags & O_CLOEXEC) ) file_attr |= FD_ATTR_CLOSE_EXEC; 710 644 645 // build extended pointer on lock protecting Inode Tree 646 vfs_root_xp = process->vfs_root_xp; 647 vfs_root_ptr = GET_PTR( vfs_root_xp ); 648 vfs_root_cxy = GET_CXY( vfs_root_xp ); 649 lock_xp = XPTR( vfs_root_cxy , &vfs_root_ptr->main_lock ); 650 651 // take lock protecting Inode Tree in read mode 652 remote_rwlock_rd_acquire( lock_xp ); 653 711 654 // get extended pointer on target inode 712 error = vfs_lookup( process->vfs_cwd_xp , path , lookup_mode , &inode_xp ); 713 714 if( error ) return error; 655 error = vfs_lookup( root_xp, 656 path, 657 lookup_mode, 658 &inode_xp, 659 NULL ); 660 661 // release lock protecting Inode Tree 662 remote_rwlock_rd_release( lock_xp ); 663 664 if( error ) 665 { 666 printk("\n[ERROR] in %s : cannot get inode <%s>\n", 667 __FUNCTION__ , path ); 668 return -1; 669 } 715 670 716 671 // get target inode cluster and local pointer … … 718 673 inode_ptr = GET_PTR( inode_xp ); 719 674 675 #if (DEBUG_VFS_OPEN & 1) 676 cycle = (uint32_t)hal_get_cycles(); 677 if( DEBUG_VFS_OPEN < cycle ) 678 printk("\n[%s] thread[%x,%x] found inode(%x,%x) for <%s>\n", 679 __FUNCTION__, process->pid, this->trdid, inode_cxy, inode_ptr, path ); 680 #endif 681 720 682 // create a new file descriptor in cluster containing inode 721 683 if( inode_cxy == local_cxy ) // target cluster is local … … 730 692 if( error ) return error; 731 693 694 #if (DEBUG_VFS_OPEN & 1) 695 cycle = (uint32_t)hal_get_cycles(); 696 if( DEBUG_VFS_OPEN < cycle ) 697 printk("\n[%s] thread[%x,%x] created file descriptor (%x,%x) for <%s>\n", 698 __FUNCTION__, process->pid, this->trdid, GET_CXY(file_xp), GET_PTR(file_xp), path ); 699 #endif 700 732 701 // allocate and register a new file descriptor index in reference process 733 error = process_fd_register( process , file_xp , &file_id );702 error = process_fd_register( process_xp , file_xp , &file_id ); 734 703 735 704 if( error ) return error; … … 738 707 cycle = (uint32_t)hal_get_cycles(); 739 708 if( DEBUG_VFS_OPEN < cycle ) 740 printk("\n[%s] 741 __FUNCTION__, this->process->pid, this->trdid, path, file_id, GET_CXY( file_xp ), cycle );709 printk("\n[%s] thread[%x,%x] exit for <%s> / fdid %d / cluster %x / cycle %d\n", 710 __FUNCTION__, process->pid, this->trdid, path, file_id, GET_CXY( file_xp ), cycle ); 742 711 #endif 743 712 … … 780 749 781 750 // move data between mapper and buffer 782 if( file_cxy == local_cxy ) 783 { 784 error = mapper_move_user( mapper, 785 to_buffer, 786 file_offset, 787 buffer, 788 size ); 789 } 790 else 791 { 792 rpc_mapper_move_user_client( file_cxy, 793 mapper, 794 to_buffer, 795 file_offset, 796 buffer, 797 size, 798 &error ); 799 } 751 error = mapper_move_user( XPTR( file_cxy , mapper ), 752 to_buffer, 753 file_offset, 754 buffer, 755 size ); 800 756 801 757 // update file offset in file descriptor … … 834 790 // get inode type from remote file descriptor 835 791 inode_type = hal_remote_l32( XPTR( file_cxy , &file_ptr->type ) ); 836 792 837 793 // action depends on inode type 838 794 if( inode_type == INODE_TYPE_FILE ) … … 1044 1000 1045 1001 //////////////////////////////////// 1046 error_t vfs_unlink( xptr_t cwd_xp, 1002 error_t vfs_mkdir( xptr_t root_xp, 1003 char * path, 1004 uint32_t rights ) 1005 { 1006 error_t error; 1007 xptr_t vfs_root_xp; // extended pointer on VFS root inode 1008 vfs_inode_t * vfs_root_ptr; // local pointer on VFS root inode 1009 cxy_t vfs_root_cxy; // VFS root inode cluster identifier 1010 xptr_t lock_xp; // extended pointer on lock protecting Inode Tree 1011 xptr_t inode_xp; // extended pointer on target inode 1012 vfs_inode_t * inode_ptr; // local pointer on target inode 1013 cxy_t inode_cxy; // target inode cluster identifier 1014 xptr_t dentry_xp; // extended pointer on new dentry 1015 vfs_dentry_t * dentry_ptr; // target dentry local pointer 1016 xptr_t parent_xp; // extended pointer on new parent inode 1017 vfs_inode_t * parent_ptr; // local pointer on new parent inode 1018 cxy_t parent_cxy; // new parent inode cluster identifier 1019 vfs_ctx_t * parent_ctx_ptr; // local pointer on target inode context 1020 uint32_t parent_fs_type; // target inode file system type 1021 1022 xptr_t parents_root_xp; // extended pointer on parents field in inode (root) 1023 xptr_t parents_entry_xp; // extended pointer on parents field in dentry 1024 xptr_t children_xhtab_xp; // extended pointer on children field in inode (root) 1025 xptr_t children_entry_xp; // extended pointer on children field in dentry 1026 1027 char last_name[CONFIG_VFS_MAX_NAME_LENGTH]; 1028 1029 thread_t * this = CURRENT_THREAD; 1030 process_t * process = this->process; 1031 1032 #if DEBUG_VFS_MKDIR 1033 char root_name[CONFIG_VFS_MAX_NAME_LENGTH]; 1034 vfs_inode_get_name( root_xp , root_name ); 1035 uint32_t cycle = (uint32_t)hal_get_cycles(); 1036 if( DEBUG_VFS_MKDIR < cycle ) 1037 printk("\n[%s] thread[%x,%x] enter / root <%s> / path <%s> / cycle %d\n", 1038 __FUNCTION__, process->pid, this->trdid, root_name, path, cycle ); 1039 #endif 1040 1041 // build extended pointer on lock protecting Inode Tree (in VFS root inode) 1042 vfs_root_xp = process->vfs_root_xp; 1043 vfs_root_ptr = GET_PTR( vfs_root_xp ); 1044 vfs_root_cxy = GET_CXY( vfs_root_xp ); 1045 lock_xp = XPTR( vfs_root_cxy , &vfs_root_ptr->main_lock ); 1046 1047 // take the lock protecting Inode Tree in write mode 1048 remote_rwlock_wr_acquire( lock_xp ); 1049 1050 // 1. get pointers on parent inode 1051 error = vfs_lookup( root_xp, 1052 path, 1053 VFS_LOOKUP_DIR | VFS_LOOKUP_PARENT, 1054 &parent_xp, 1055 last_name ); 1056 if( error ) 1057 { 1058 remote_rwlock_wr_release( lock_xp ); 1059 printk("\n[ERROR] in %s : cannot get parent inode for <%s>\n", 1060 __FUNCTION__, path ); 1061 return -1; 1062 } 1063 1064 // get parent inode cluster and local pointer 1065 parent_cxy = GET_CXY( parent_xp ); 1066 parent_ptr = GET_PTR( parent_xp ); 1067 1068 #if( DEBUG_VFS_MKDIR & 1 ) 1069 if( DEBUG_VFS_MKDIR < cycle ) 1070 printk("\n[%s] thread[%x,%x] get parent inode (%x,%x) for <%s>\n", 1071 __FUNCTION__, process->pid, this->trdid, parent_cxy, parent_ptr, path ); 1072 #endif 1073 1074 // get parent inode context, and FS type 1075 parent_ctx_ptr = hal_remote_lpt( XPTR( parent_cxy , &parent_ptr->ctx ) ); 1076 parent_fs_type = hal_remote_l32( XPTR( parent_cxy , &parent_ctx_ptr->type ) ); 1077 1078 // 2. create one new dentry in parent cluster 1079 if( parent_cxy == local_cxy ) 1080 { 1081 error = vfs_dentry_create( parent_fs_type, 1082 last_name, 1083 &dentry_xp ); 1084 } 1085 else 1086 { 1087 rpc_vfs_dentry_create_client( parent_cxy, 1088 parent_fs_type, 1089 last_name, 1090 &dentry_xp, 1091 &error ); 1092 } 1093 1094 if( error ) 1095 { 1096 remote_rwlock_wr_release( lock_xp ); 1097 printk("\n[ERROR] in %s : cannot create new dentry in cluster %x for <%s>\n", 1098 __FUNCTION__, parent_cxy, path ); 1099 return -1; 1100 } 1101 1102 // get local pointer on dentry 1103 dentry_ptr = GET_PTR( dentry_xp ); 1104 1105 #if( DEBUG_VFS_MKDIR & 1 ) 1106 if( DEBUG_VFS_MKDIR < cycle ) 1107 printk("\n[%s] thread[%x,%x] created new dentry (%x,%x) for <%s>\n", 1108 __FUNCTION__, process->pid, this->trdid, parent_cxy, dentry_ptr, path ); 1109 #endif 1110 1111 // 3. create new directory inode in child cluster 1112 // TODO : define attr / uid / gid 1113 uint32_t attr = 0; 1114 uint32_t uid = 0; 1115 uint32_t gid = 0; 1116 1117 // select a target cluster for new inode 1118 inode_cxy = cluster_random_select(); 1119 1120 if( inode_cxy == local_cxy ) // child cluster is local 1121 { 1122 error = vfs_inode_create( parent_fs_type, 1123 INODE_TYPE_DIR, 1124 attr, 1125 rights, 1126 uid, 1127 gid, 1128 &inode_xp ); 1129 } 1130 else // child cluster is remote 1131 { 1132 rpc_vfs_inode_create_client( inode_cxy, 1133 parent_fs_type, 1134 INODE_TYPE_DIR, 1135 attr, 1136 rights, 1137 uid, 1138 gid, 1139 &inode_xp, 1140 &error ); 1141 } 1142 1143 if( error ) 1144 { 1145 printk("\n[ERROR] in %s : cannot create new inode in cluster %x for <%s>\n", 1146 __FUNCTION__ , inode_cxy , path ); 1147 1148 if( parent_cxy == local_cxy ) vfs_dentry_destroy( dentry_ptr ); 1149 else rpc_vfs_dentry_destroy_client( parent_cxy , dentry_ptr ); 1150 return -1; 1151 } 1152 1153 // get new inode local pointer 1154 inode_ptr = GET_PTR( inode_xp ); 1155 1156 #if(DEBUG_VFS_MKDIR & 1) 1157 if( DEBUG_VFS_MKDIR < cycle ) 1158 printk("\n[%s] thread[%x,%x] created new inode (%x,%x) for <%s>\n", 1159 __FUNCTION__ , process->pid, this->trdid, inode_cxy, inode_ptr, path ); 1160 #endif 1161 1162 // 4. register dentry in new inode list of parents 1163 parents_root_xp = XPTR( inode_cxy , &inode_ptr->parents ); 1164 parents_entry_xp = XPTR( parent_cxy , &dentry_ptr->parents ); 1165 xlist_add_first( parents_root_xp , parents_entry_xp ); 1166 hal_remote_atomic_add( XPTR( inode_cxy , &inode_ptr->links ) , 1 ); 1167 1168 // 5. register dentry in parent inode 1169 children_xhtab_xp = XPTR( parent_cxy , &parent_ptr->children ); 1170 children_entry_xp = XPTR( parent_cxy , &dentry_ptr->children ); 1171 xhtab_insert( children_xhtab_xp , last_name , children_entry_xp ); 1172 1173 // 6. update "parent" and "child_xp" fields in dentry 1174 hal_remote_s64( XPTR( parent_cxy , &dentry_ptr->child_xp ) , inode_xp ); 1175 hal_remote_spt( XPTR( parent_cxy , &dentry_ptr->parent ) , parent_ptr ); 1176 1177 #if(DEBUG_VFS_MKDIR & 1) 1178 if( DEBUG_VFS_MKDIR < cycle ) 1179 printk("\n[%s] thread[%x,%x] updated Inode Tree for <%s>\n", 1180 __FUNCTION__, process->pid, this->trdid, path ); 1181 #endif 1182 1183 // release the lock protecting Inode Tree 1184 remote_rwlock_wr_release( lock_xp ); 1185 1186 // 5. update parent directory mapper 1187 // and synchronize the parent directory on IOC device 1188 if (parent_cxy == local_cxy) 1189 { 1190 error = vfs_fs_add_dentry( parent_ptr, 1191 dentry_ptr ); 1192 } 1193 else 1194 { 1195 rpc_vfs_fs_add_dentry_client( parent_cxy, 1196 parent_ptr, 1197 dentry_ptr, 1198 &error ); 1199 } 1200 1201 if( error ) 1202 { 1203 printk("\n[ERROR] in %s : cannot update parent directory for <%s>\n", 1204 __FUNCTION__, path ); 1205 return -1; 1206 } 1207 1208 #if(DEBUG_VFS_MKDIR & 1) 1209 if( DEBUG_VFS_MKDIR < cycle ) 1210 printk("\n[%s] thread[%x,%x] updated parent dir (mapper and IOC) for <%s>\n", 1211 __FUNCTION__, process->pid, this->trdid, path ); 1212 #endif 1213 1214 return 0; 1215 1216 } // end vfs_mkdir() 1217 1218 /////////////////////////////////////// 1219 error_t vfs_link( xptr_t old_root_xp, 1220 char * old_path, 1221 xptr_t new_root_xp, 1222 char * new_path ) 1223 { 1224 error_t error; 1225 xptr_t vfs_root_xp; // extended pointer on VFS root inode 1226 vfs_inode_t * vfs_root_ptr; // local pointer on VFS root inode 1227 cxy_t vfs_root_cxy; // VFS root inode cluster identifier 1228 xptr_t lock_xp; // extended pointer on lock protecting Inode Tree 1229 xptr_t inode_xp; // extended pointer on target inode 1230 vfs_inode_t * inode_ptr; // local pointer on target inode 1231 cxy_t inode_cxy; // target inode cluster identifier 1232 uint32_t inode_type; // target inode type 1233 vfs_ctx_t * inode_ctx_ptr; // local pointer on target inode context 1234 uint32_t inode_fs_type; // target inode file system type 1235 xptr_t dentry_xp; // extended pointer on new dentry 1236 vfs_dentry_t * dentry_ptr; // target dentry local pointer 1237 xptr_t new_parent_xp; // extended pointer on new parent inode 1238 vfs_inode_t * new_parent_ptr; // local pointer on new parent inode 1239 cxy_t new_parent_cxy; // new parent inode cluster identifier 1240 1241 xptr_t parents_root_xp; // extended pointer on parents field in inode (root) 1242 xptr_t parents_entry_xp; // extended pointer on parents field in dentry 1243 xptr_t children_xhtab_xp; // extended pointer on children field in inode (root) 1244 xptr_t children_entry_xp; // extended pointer on children field in dentry 1245 1246 char new_name[CONFIG_VFS_MAX_NAME_LENGTH]; 1247 1248 thread_t * this = CURRENT_THREAD; 1249 process_t * process = this->process; 1250 1251 #if DEBUG_VFS_LINK 1252 char old_root_name[CONFIG_VFS_MAX_NAME_LENGTH]; 1253 char new_root_name[CONFIG_VFS_MAX_NAME_LENGTH]; 1254 vfs_inode_get_name( old_root_xp , old_root_name ); 1255 vfs_inode_get_name( new_root_xp , new_root_name ); 1256 uint32_t cycle = (uint32_t)hal_get_cycles(); 1257 if( DEBUG_VFS_LINK < cycle ) 1258 printk("\n[%s] thread[%x,%x] enter / old_root <%s> / old_path <%s> / " 1259 "new_root <%s> / new_path <%s> / cycle %d\n", 1260 __FUNCTION__, process->pid, this->trdid, 1261 old_root_name, old_path, new_root_name, new_path, cycle ); 1262 #endif 1263 1264 // build extended pointer on lock protecting Inode Tree (in VFS root inode) 1265 vfs_root_xp = process->vfs_root_xp; 1266 vfs_root_ptr = GET_PTR( vfs_root_xp ); 1267 vfs_root_cxy = GET_CXY( vfs_root_xp ); 1268 lock_xp = XPTR( vfs_root_cxy , &vfs_root_ptr->main_lock ); 1269 1270 // take the lock protecting Inode Tree in write mode 1271 remote_rwlock_wr_acquire( lock_xp ); 1272 1273 // get extended pointer on target inode 1274 error = vfs_lookup( old_root_xp, 1275 old_path, 1276 0, 1277 &inode_xp, 1278 NULL ); 1279 if( error ) 1280 { 1281 remote_rwlock_wr_release( lock_xp ); 1282 printk("\n[ERROR] in %s : cannot get target inode for <%s>\n", 1283 __FUNCTION__, old_path ); 1284 return -1; 1285 } 1286 1287 #if( DEBUG_VFS_LINK & 1 ) 1288 if( DEBUG_VFS_LINK < cycle ) 1289 printk("\n[%s] thread[%x,%x] get child inode (%x,%x) for <%s>\n", 1290 __FUNCTION__, process->pid, this->trdid, 1291 GET_CXY(inode_xp), GET_PTR(inode_xp), old_path, cycle ); 1292 #endif 1293 1294 // get extended pointer on parent inode in new path 1295 error = vfs_lookup( new_root_xp, 1296 new_path, 1297 VFS_LOOKUP_PARENT, 1298 &new_parent_xp, 1299 new_name ); 1300 if( error ) 1301 { 1302 remote_rwlock_wr_release( lock_xp ); 1303 printk("\n[ERROR] in %s : cannot get parent inode for <%s>\n", 1304 __FUNCTION__, new_path ); 1305 return -1; 1306 } 1307 1308 #if( DEBUG_VFS_LINK & 1 ) 1309 if( DEBUG_VFS_LINK < cycle ) 1310 printk("\n[%s] thread[%x,%x] get parent inode (%x,%x) for <%s>\n", 1311 __FUNCTION__, process->pid, this->trdid, 1312 GET_CXY(new_parent_xp), GET_PTR(new_parent_xp), new_path ); 1313 #endif 1314 1315 // get target inode cluster and local pointer 1316 inode_cxy = GET_CXY( inode_xp ); 1317 inode_ptr = GET_PTR( inode_xp ); 1318 1319 // get target inode type, context, and FS type 1320 inode_type = hal_remote_l32( XPTR( inode_cxy , &inode_ptr->type ) ); 1321 inode_ctx_ptr = hal_remote_lpt( XPTR( inode_cxy , &inode_ptr->ctx ) ); 1322 inode_fs_type = hal_remote_l32( XPTR( inode_cxy , &inode_ctx_ptr->type ) ); 1323 1324 // get new parent inode cluster an local pointer 1325 new_parent_ptr = GET_PTR( new_parent_xp ); 1326 new_parent_cxy = GET_CXY( new_parent_xp ); 1327 1328 /////////////////////////////////////////////////////////////////////// 1329 if( (inode_type == INODE_TYPE_FILE) || (inode_type == INODE_TYPE_DIR) ) 1330 { 1331 // 1. create one new dentry 1332 if( new_parent_cxy == local_cxy ) 1333 { 1334 error = vfs_dentry_create( inode_fs_type, 1335 new_name, 1336 &dentry_xp ); 1337 } 1338 else 1339 { 1340 rpc_vfs_dentry_create_client( new_parent_cxy, 1341 inode_fs_type, 1342 new_name, 1343 &dentry_xp, 1344 &error ); 1345 } 1346 1347 if( error ) 1348 { 1349 remote_rwlock_wr_release( lock_xp ); 1350 printk("\n[ERROR] in %s : cannot create new dentry for <%s>\n", 1351 __FUNCTION__, new_path ); 1352 return -1; 1353 } 1354 1355 // get local pointer on dentry 1356 dentry_ptr = GET_PTR( dentry_xp ); 1357 1358 // 2. register dentry in target inode 1359 parents_root_xp = XPTR( inode_cxy , &inode_ptr->parents ); 1360 parents_entry_xp = XPTR( new_parent_cxy , &dentry_ptr->parents ); 1361 xlist_add_first( parents_root_xp , parents_entry_xp ); 1362 hal_remote_atomic_add( XPTR( inode_cxy , &inode_ptr->links ) , 1 ); 1363 1364 // 3. register dentry in parent inode 1365 children_xhtab_xp = XPTR( new_parent_cxy , &new_parent_ptr->children ); 1366 children_entry_xp = XPTR( new_parent_cxy , &dentry_ptr->children ); 1367 xhtab_insert( children_xhtab_xp , new_name , children_entry_xp ); 1368 1369 // 4. update "parent" and "child_xp" fields in dentry 1370 hal_remote_s64( XPTR( new_parent_cxy , &dentry_ptr->child_xp ) , inode_xp ); 1371 hal_remote_spt( XPTR( new_parent_cxy , &dentry_ptr->parent ) , new_parent_ptr ); 1372 1373 #if(DEBUG_VFS_LINK & 1) 1374 if( DEBUG_VFS_LINK < cycle ) 1375 printk("\n[%s] thread[%x,%x] updated Inode Tree / old <%s> / new <%s>\n", 1376 __FUNCTION__, process->pid, this->trdid, old_path, new_path ); 1377 vfs_display( new_parent_xp ); 1378 #endif 1379 1380 // release the lock protecting Inode Tree 1381 remote_rwlock_wr_release( lock_xp ); 1382 1383 // 5. update new parent directory mapper in Inode Tree 1384 // and synchronize the parent directory on IOC device 1385 if (new_parent_cxy == local_cxy) 1386 { 1387 error = vfs_fs_add_dentry( new_parent_ptr, 1388 dentry_ptr ); 1389 } 1390 else 1391 { 1392 rpc_vfs_fs_add_dentry_client( new_parent_cxy, 1393 new_parent_ptr, 1394 dentry_ptr, 1395 &error ); 1396 } 1397 if( error ) 1398 { 1399 printk("\n[ERROR] in %s : cannot update new parent directory for <%s>\n", 1400 __FUNCTION__, new_path ); 1401 return -1; 1402 } 1403 1404 #if(DEBUG_VFS_LINK & 1) 1405 if( DEBUG_VFS_LINK < cycle ) 1406 printk("\n[%s] thread[%x,%x] updated new parent dir (mapper and IOC) / old <%s> / new <%s>\n", 1407 __FUNCTION__, process->pid, this->trdid, old_path, new_path ); 1408 #endif 1409 return 0; 1410 } 1411 else 1412 { 1413 // release the lock protecting Inode Tree 1414 remote_rwlock_wr_release( lock_xp ); 1415 1416 printk("\n[ERROR] in %s : unsupported inode type %s\n", 1417 __FUNCTION__ , vfs_inode_type_str( inode_type ) ); 1418 return -1; 1419 } 1420 1421 } // end vfs_link() 1422 1423 ///////////////////////////////////// 1424 error_t vfs_unlink( xptr_t root_xp, 1047 1425 char * path ) 1048 1426 { 1049 1427 error_t error; 1428 xptr_t vfs_root_xp; // extended pointer on VFS root inode 1429 vfs_inode_t * vfs_root_ptr; // local_pointer on VFS root inode 1430 cxy_t vfs_root_cxy; // VFS root inode cluster identifier 1431 xptr_t lock_xp; // extended pointer on lock protecting Inode Tree 1432 xptr_t parent_xp; // extended pointer on target inode 1433 cxy_t parent_cxy; // target inode cluster identifier 1434 vfs_inode_t * parent_ptr; // target inode local pointer 1050 1435 xptr_t inode_xp; // extended pointer on target inode 1051 1436 cxy_t inode_cxy; // target inode cluster identifier 1052 1437 vfs_inode_t * inode_ptr; // target inode local pointer 1053 uint32_t inode_refcount; // target inode refcount 1054 vfs_inode_type_t type; // target inode type 1055 mapper_t * mapper; // pointer on target inode mapper 1056 xptr_t dentry_xp; // extended pointer on target dentry 1057 cxy_t dentry_cxy; // target dentry cluster identifier 1058 vfs_dentry_t * dentry_ptr; // target dentry local pointer 1059 uint32_t dentry_refcount; // target dentry refcount 1060 vfs_inode_t * dentry_parent_ptr; // parent inode local pointer 1438 uint32_t inode_links; // target inode links count 1439 vfs_inode_type_t inode_type; // target inode type 1440 uint32_t inode_children; // target inode number of children 1441 xptr_t dentry_xp; // extended pointer on dentry to unlink 1442 vfs_dentry_t * dentry_ptr; // local pointer on dentry to unlink 1443 1444 char name[CONFIG_VFS_MAX_NAME_LENGTH]; // name of link to remove 1445 1446 thread_t * this = CURRENT_THREAD; 1447 process_t * process = this->process; 1061 1448 1062 1449 #if DEBUG_VFS_UNLINK 1063 thread_t * this = CURRENT_THREAD;1064 1450 uint32_t cycle = (uint32_t)hal_get_cycles(); 1451 char root_name[CONFIG_VFS_MAX_NAME_LENGTH]; 1452 vfs_inode_get_name( root_xp , root_name ); 1065 1453 if( DEBUG_VFS_UNLINK < cycle ) 1066 printk("\n[%s] thread[%x,%x] enter for <%s> / cycle %d\n", 1067 __FUNCTION__, this->process->pid, this->trdid, path, cycle ); 1068 #endif 1069 1070 // get extended pointer on target inode 1071 error = vfs_lookup( cwd_xp , path , 0 , &inode_xp ); 1072 1073 if( error ) return error; 1074 1075 // get inode cluster and local pointer 1454 printk("\n[%s] thread[%x,%x] enter / root <%s> / path <%s> / cycle %d\n", 1455 __FUNCTION__, process->pid, this->trdid, root_name, path, cycle ); 1456 #endif 1457 1458 // build extended pointer on lock protecting Inode Tree (in VFS root inode) 1459 vfs_root_xp = process->vfs_root_xp; 1460 vfs_root_ptr = GET_PTR( root_xp ); 1461 vfs_root_cxy = GET_CXY( root_xp ); 1462 lock_xp = XPTR( vfs_root_cxy , &vfs_root_ptr->main_lock ); 1463 1464 // take the lock protecting Inode Tree 1465 remote_rwlock_wr_acquire( lock_xp ); 1466 1467 // get extended pointer on parent inode 1468 error = vfs_lookup( root_xp, 1469 path, 1470 VFS_LOOKUP_PARENT, 1471 &parent_xp, 1472 name ); 1473 if( error ) 1474 { 1475 remote_rwlock_wr_release( lock_xp ); 1476 printk("\n[ERROR] in %s : cannot get parent inode for <%s> in <%s>\n", 1477 __FUNCTION__, name, path ); 1478 return -1; 1479 } 1480 1481 // get parent inode cluster and local pointer 1482 parent_cxy = GET_CXY( parent_xp ); 1483 parent_ptr = GET_PTR( parent_xp ); 1484 1485 #if( DEBUG_VFS_UNLINK & 1 ) 1486 char parent_name[CONFIG_VFS_MAX_NAME_LENGTH]; 1487 vfs_inode_get_name( parent_xp , parent_name ); 1488 if( DEBUG_VFS_UNLINK < cycle ) 1489 printk("\n[%s] thread[%x,%x] parent inode <%s> is (%x,%x)\n", 1490 __FUNCTION__, process->pid, this->trdid, parent_name, parent_cxy, parent_ptr ); 1491 #endif 1492 1493 // build extended pointer on parent inode "children" xhtab 1494 xptr_t children_xp = XPTR( parent_cxy , &parent_ptr->children ); 1495 1496 // get extended pointer on dentry to unlink 1497 dentry_xp = xhtab_lookup( children_xp , name ); 1498 1499 if( dentry_xp == XPTR_NULL ) 1500 { 1501 remote_rwlock_wr_release( lock_xp ); 1502 printk("\n[ERROR] in %s : cannot get target dentry <%s> in <%s>\n", 1503 __FUNCTION__, name, path ); 1504 return -1; 1505 } 1506 1507 // get local pointer on dentry to unlink 1508 dentry_ptr = GET_PTR( dentry_xp ); 1509 1510 #if( DEBUG_VFS_UNLINK & 1 ) 1511 if( DEBUG_VFS_UNLINK < cycle ) 1512 printk("\n[%s] thread[%x,%x] dentry <%s> to unlink is (%x,%x)\n", 1513 __FUNCTION__, process->pid, this->trdid, name, parent_cxy, dentry_ptr ); 1514 #endif 1515 1516 // get pointer on target inode 1517 inode_xp = hal_remote_l64( XPTR( parent_cxy , &dentry_ptr->child_xp ) ); 1076 1518 inode_cxy = GET_CXY( inode_xp ); 1077 1519 inode_ptr = GET_PTR( inode_xp ); 1078 1079 // get inode type, refcount, mapper, dentry_xp 1080 type = hal_remote_l32( XPTR( inode_cxy , &inode_ptr->type ) ); 1081 inode_refcount = hal_remote_l32( XPTR( inode_cxy , &inode_ptr->refcount ) ); 1082 mapper = hal_remote_lpt( XPTR( inode_cxy , &inode_ptr->mapper ) ); 1083 dentry_xp = hal_remote_l64( XPTR( inode_cxy , &inode_ptr->parent_xp ) ); 1084 1085 // get dentry cluster, local pointer, refcount, and pointers on parent inode 1086 dentry_ptr = GET_PTR( dentry_xp ); 1087 dentry_cxy = GET_CXY( dentry_xp ); 1088 dentry_refcount = hal_remote_l32( XPTR( dentry_cxy , &dentry_ptr->refcount ) ); 1089 dentry_parent_ptr = hal_remote_lpt( XPTR( dentry_cxy , &dentry_ptr->parent ) ); 1090 1091 // check inode & dentry refcount 1092 assert( (inode_refcount == 1), "illegal inode refcount for <%s>\n", path ); 1093 assert( (dentry_refcount == 1), "illegal dentry refcount for <%s>\n", path ); 1094 1095 ///////////////////////////// 1096 if( type == INODE_TYPE_FILE ) 1097 { 1098 // 1. release clusters allocated to file in the FAT mapper 1099 // synchronize the FAT on IOC device 1100 error = vfs_fs_release_inode( inode_xp ); 1101 if( error ) 1520 1521 #if( DEBUG_VFS_UNLINK & 1 ) 1522 char inode_name[CONFIG_VFS_MAX_NAME_LENGTH]; 1523 vfs_inode_get_name( inode_xp , inode_name ); 1524 if( DEBUG_VFS_UNLINK < cycle ) 1525 printk("\n[%s] thread[%x,%x] target inode <%s> is (%x,%x) / cycle %d\n", 1526 __FUNCTION__, process->pid, this->trdid, inode_name, inode_cxy, inode_ptr, cycle ); 1527 #endif 1528 1529 // get target inode "type" and "links" 1530 inode_type = hal_remote_l32( XPTR( inode_cxy , &inode_ptr->type ) ); 1531 inode_links = hal_remote_l32( XPTR( inode_cxy , &inode_ptr->links ) ); 1532 1533 // check target inode links counter 1534 assert( (inode_links >= 1), "illegal inode links count %d for <%s>\n", inode_links, path ); 1535 1536 /////////////////////////////////////////////////////////////////////// 1537 if( (inode_type == INODE_TYPE_FILE) || (inode_type == INODE_TYPE_DIR) ) 1538 { 1539 // 1. Release clusters allocated to target inode 1540 // and synchronize the FAT on IOC device if last link. 1541 if( inode_links == 1 ) 1102 1542 { 1103 printk("\n[ERROR] in %s : cannot update FAT mapper <%s>\n", path ); 1104 return -1; 1105 } 1543 // build extended pointer on target inode "children" number 1544 xptr_t inode_children_xp = XPTR( inode_cxy , &inode_ptr->children.items ); 1545 1546 // get target inode number of children 1547 inode_children = hal_remote_l32( inode_children_xp ); 1548 1549 // check no children 1550 if( inode_children != 0 ) 1551 { 1552 remote_rwlock_wr_release( lock_xp ); 1553 printk("\n[ERROR] in %s : cannot remove <%s> inode that has children\n", 1554 __FUNCTION__, path ); 1555 return -1; 1556 } 1557 1558 // release clusters on IOC device 1559 error = vfs_fs_release_inode( inode_xp ); 1560 1561 if( error ) 1562 { 1563 remote_rwlock_wr_release( lock_xp ); 1564 printk("\n[ERROR] in %s : cannot update FAT mapper to remove <%s> inode\n", 1565 __FUNCTION__ , path ); 1566 return -1; 1567 } 1106 1568 1107 1569 #if(DEBUG_VFS_UNLINK & 1) 1108 1570 if( DEBUG_VFS_UNLINK < cycle ) 1109 1571 printk("\n[%s] thread[%x,%x] removed <%s> inode from FAT (mapper and IOC device)\n", 1110 __FUNCTION__, this->process->pid, this->trdid, path ); 1111 #endif 1112 1113 // 2. update parent directory in Inode Tree 1114 // synchronize the parent directory on IOC device 1115 if (dentry_cxy == local_cxy) // dentry is local 1572 __FUNCTION__, process->pid, this->trdid, path ); 1573 #endif 1574 } 1575 1576 // 2. update parent directory mapper 1577 // and synchronize the parent directory on IOC device 1578 if (parent_cxy == local_cxy) 1116 1579 { 1117 error = vfs_fs_remove_dentry( dentry_parent_ptr,1580 error = vfs_fs_remove_dentry( parent_ptr, 1118 1581 dentry_ptr ); 1119 1582 } 1120 else // dentry is remote1583 else 1121 1584 { 1122 rpc_vfs_fs_remove_dentry_client( dentry_cxy,1123 dentry_parent_ptr,1585 rpc_vfs_fs_remove_dentry_client( parent_cxy, 1586 parent_ptr, 1124 1587 dentry_ptr, 1125 1588 &error ); 1126 1589 } 1590 1127 1591 if( error ) 1128 1592 { 1129 printk("\n[ERROR] in %s : cannot update dentry on device for <%s>\n", path ); 1593 remote_rwlock_wr_release( lock_xp ); 1594 printk("\n[ERROR] in %s : cannot update dentry on device for <%s>\n", 1595 __FUNCTION__ , path ); 1130 1596 return -1; 1131 1597 } … … 1134 1600 if( DEBUG_VFS_UNLINK < cycle ) 1135 1601 printk("\n[%s] thread[%x,%x] removed <%s> inode from parent dir (mapper and IOC device)\n", 1136 __FUNCTION__, this->process->pid, this->trdid, path ); 1137 #endif 1138 // 3. remove inode (including mapper & dentry) from Inode Tree 1139 vfs_remove_child_from_parent( inode_xp ); 1602 __FUNCTION__, process->pid, this->trdid, path ); 1603 #endif 1604 // 3. remove dentry from Inode Tree (and associated chils inode when last link) 1605 vfs_remove_child_from_parent( dentry_xp ); 1606 1607 // release the lock protecting Inode Tree 1608 remote_rwlock_wr_release( lock_xp ); 1140 1609 1141 1610 #if DEBUG_VFS_UNLINK 1142 1611 if( DEBUG_VFS_UNLINK < cycle ) 1143 1612 printk("\n[%s] thread[%x,%x] exit / removed <%s> inode from Inode Tree / cycle %d\n", 1144 __FUNCTION__, this->process->pid, this->trdid, path, cycle );1613 __FUNCTION__, process->pid, this->trdid, path, cycle ); 1145 1614 #endif 1146 1615 return 0; 1147 1616 } 1148 ///////////////////////////////// 1149 else if( type == INODE_TYPE_DIR ) 1150 { 1151 printk("\n[ERROR] in %s : unsupported type %s\n", vfs_inode_type_str( type ) ); 1617 else 1618 { 1619 remote_rwlock_wr_release( lock_xp ); 1620 printk("\n[ERROR] in %s : unsupported inode type %s\n", 1621 __FUNCTION__ , vfs_inode_type_str( inode_type ) ); 1152 1622 return -1; 1153 1623 } 1154 //// 1155 else 1156 { 1157 printk("\n[ERROR] in %s : unsupported type %s\n", vfs_inode_type_str( type ) ); 1624 1625 } // end vfs_unlink() 1626 1627 /////////////////////////////////////////// 1628 error_t vfs_stat( xptr_t root_inode_xp, 1629 char * path, 1630 stat_t * st ) 1631 { 1632 error_t error; 1633 xptr_t inode_xp; // extended pointer on target inode 1634 vfs_inode_t * inode_ptr; // local pointer on target inode 1635 cxy_t inode_cxy; // target inode cluster identifier 1636 xptr_t vfs_root_xp; // extended pointer on VFS root inode 1637 vfs_inode_t * vfs_root_ptr; // local_pointer on VFS root inode 1638 cxy_t vfs_root_cxy; // VFS root inode cluster identifier 1639 xptr_t lock_xp; // extended pointer on lock protecting Inode Tree 1640 1641 thread_t * this = CURRENT_THREAD; 1642 process_t * process = this->process; 1643 1644 // build extended pointer on lock protecting Inode Tree (in VFS root inode) 1645 vfs_root_xp = process->vfs_root_xp; 1646 vfs_root_ptr = GET_PTR( vfs_root_xp ); 1647 vfs_root_cxy = GET_CXY( vfs_root_xp ); 1648 lock_xp = XPTR( vfs_root_cxy , &vfs_root_ptr->main_lock ); 1649 1650 // get the lock protecting Inode Tree in read mode 1651 remote_rwlock_rd_acquire( lock_xp ); 1652 1653 // get extended pointer on target inode 1654 error = vfs_lookup( root_inode_xp, 1655 path, 1656 0, 1657 &inode_xp, 1658 NULL ); 1659 1660 // release the lock protecting Inode Tree 1661 remote_rwlock_rd_release( lock_xp ); 1662 1663 if( error ) 1664 { 1665 printk("\n[ERROR] in %s : cannot found inode <%s>\n", 1666 __FUNCTION__ , path ); 1158 1667 return -1; 1159 1668 } 1160 1669 1161 } // end vfs_unlink()1162 1163 //////////////////////////////////////1164 error_t vfs_stat( xptr_t inode_xp,1165 stat_t * st )1166 {1167 1670 // get cluster and local pointer on inode descriptor 1168 vfs_inode_t *inode_ptr = GET_PTR( inode_xp );1169 cxy_tinode_cxy = GET_CXY( inode_xp );1671 inode_ptr = GET_PTR( inode_xp ); 1672 inode_cxy = GET_CXY( inode_xp ); 1170 1673 1171 1674 // get relevant infos from inode descriptor … … 1186 1689 #if DEBUG_VFS_STAT 1187 1690 uint32_t cycle = (uint32_t)hal_get_cycles(); 1188 thread_t * this = CURRENT_THREAD;1189 1691 if( DEBUG_VFS_STAT < cycle ) 1190 1692 printk("\n[%s] thread[%x,%x] set stat %x for inode %x in cluster %x / cycle %d\n" 1191 1693 " %s / inum %d / size %d\n", 1192 __FUNCTION__, this->process->pid, this->trdid, st, inode_ptr, inode_cxy, cycle,1694 __FUNCTION__, process->pid, this->trdid, st, inode_ptr, inode_cxy, cycle, 1193 1695 vfs_inode_type_str( type ), inum, size ); 1194 1696 #endif … … 1207 1709 } 1208 1710 1209 //////////////////////////////////////1210 error_t vfs_mkdir( xptr_t file_xp,1211 char * path,1212 uint32_t mode )1213 {1214 assert( false , "not implemented file_xp: %x, path <%s>, mode: %x\n",1215 file_xp, path, mode );1216 return 0;1217 }1218 1219 1711 //////////////////////////////////// 1220 1712 error_t vfs_rmdir( xptr_t file_xp, … … 1226 1718 } 1227 1719 1228 /////////////////////////////////// 1229 error_t vfs_chdir( xptr_t cwd_xp,1720 //////////////////////////////////// 1721 error_t vfs_chdir( xptr_t root_xp, 1230 1722 char * path ) 1231 1723 { 1232 1724 error_t error; 1233 xptr_t inode_xp; // extended pointer on target inode 1234 cxy_t inode_cxy; // target inode cluster identifier 1235 vfs_inode_t * inode_ptr; // target inode local pointer 1236 uint32_t mode; // lookup working mode 1237 vfs_inode_type_t inode_type; // target inode type 1238 1239 // set lookup working mode 1240 mode = 0; 1725 xptr_t inode_xp; // extended pointer on target inode 1726 cxy_t inode_cxy; // target inode cluster identifier 1727 vfs_inode_t * inode_ptr; // target inode local pointer 1728 vfs_inode_type_t inode_type; // target inode type 1729 xptr_t vfs_root_xp; // extended pointer on VFS root inode 1730 vfs_inode_t * vfs_root_ptr; // local_pointer on VFS root inode 1731 cxy_t vfs_root_cxy; // VFS root inode cluster identifier 1732 xptr_t main_lock_xp; // extended pointer on lock protecting Inode Tree 1733 xptr_t ref_xp; // extended pointer on reference process 1734 process_t * ref_ptr; // local pointer on reference process 1735 cxy_t ref_cxy; // reference process cluster 1736 xptr_t cwd_lock_xp; // extended pointer on lock protecting CWD change 1737 xptr_t cwd_xp_xp; // extended pointer on cwd_xp in reference process 1738 1739 thread_t * this = CURRENT_THREAD; 1740 process_t * process = this->process; 1741 1742 #if DEBUG_VFS_CHDIR 1743 uint32_t cycle = (uint32_t)hal_get_cycles(); 1744 if( DEBUG_VFS_CHDIR < cycle ) 1745 printk("\n[%s] thread[%x,%x] enter for path <%s> / cycle %d\n", 1746 __FUNCTION__, process->pid, this->trdid, path, cycle ); 1747 #endif 1748 1749 // build extended pointer on lock protecting Inode Tree (in VFS root inode) 1750 vfs_root_xp = process->vfs_root_xp; 1751 vfs_root_ptr = GET_PTR( vfs_root_xp ); 1752 vfs_root_cxy = GET_CXY( vfs_root_xp ); 1753 main_lock_xp = XPTR( vfs_root_cxy , &vfs_root_ptr->main_lock ); 1754 1755 // take lock protecting Inode Tree in read mode 1756 remote_rwlock_rd_acquire( main_lock_xp ); 1241 1757 1242 1758 // get extended pointer on target inode 1243 error = vfs_lookup( cwd_xp , path , mode , &inode_xp ); 1244 1245 if( error ) return error; 1246 1247 // get inode cluster and local pointer 1759 error = vfs_lookup( root_xp, 1760 path, 1761 VFS_LOOKUP_DIR, 1762 &inode_xp, 1763 NULL ); 1764 1765 // release lock protecting Inode Tree in read mode 1766 remote_rwlock_rd_release( main_lock_xp ); 1767 1768 if( error ) 1769 { 1770 printk("\n[ERROR] in %s : <%s> not found\n", 1771 __FUNCTION__, path ); 1772 return -1; 1773 } 1774 1775 // get inode type from remote file 1248 1776 inode_cxy = GET_CXY( inode_xp ); 1249 1777 inode_ptr = GET_PTR( inode_xp ); 1250 1251 // get inode type from remote file1252 1778 inode_type = hal_remote_l32( XPTR( inode_cxy , &inode_ptr->type ) ); 1253 1779 1254 1780 if( inode_type != INODE_TYPE_DIR ) 1255 1781 { 1256 CURRENT_THREAD->errno = ENOTDIR; 1782 printk("\n[ERROR] in %s : <%s> is not a directory\n", 1783 __FUNCTION__, path ); 1257 1784 return -1; 1258 1785 } 1259 1786 1260 // TODO implement this function using process CWD lock 1261 1262 assert( false , "not implemented\n" ); 1787 // build extended pointer on cwd_lock and cwd_xp 1788 ref_xp = process->ref_xp; 1789 ref_ptr = GET_PTR( ref_xp ); 1790 ref_cxy = GET_CXY( ref_xp ); 1791 cwd_lock_xp = XPTR( ref_cxy , &ref_ptr->cwd_lock ); 1792 cwd_xp_xp = XPTR( ref_cxy , &ref_ptr->cwd_xp ); 1793 1794 // take lock protecting CWD changes 1795 remote_busylock_acquire( cwd_lock_xp ); 1796 1797 // update cwd_xp field in reference process descriptor 1798 hal_remote_s64( cwd_xp_xp , inode_xp ); 1799 1800 // release lock protecting CWD changes 1801 remote_busylock_release( cwd_lock_xp ); 1802 1803 #if DEBUG_VFS_CHDIR 1804 cycle = (uint32_t)hal_get_cycles(); 1805 if( DEBUG_VFS_CHDIR < cycle ) 1806 printk("\n[%s] thread[%x,%x] exit : inode (%x,%x) / &cwd_xp (%x,%x) / cycle %d\n", 1807 __FUNCTION__, process->pid, this->trdid, inode_cxy, inode_ptr, 1808 GET_CXY(cwd_xp_xp), GET_PTR(cwd_xp_xp), cycle ); 1809 #endif 1263 1810 1264 1811 return 0; 1265 } 1812 1813 } // end vfs_chdir() 1266 1814 1267 1815 /////////////////////////////////// … … 1281 1829 1282 1830 // get extended pointer on target inode 1283 error = vfs_lookup( cwd_xp , path , 0 , &inode_xp ); 1831 error = vfs_lookup( cwd_xp, 1832 path, 1833 0, 1834 &inode_xp, 1835 NULL ); 1284 1836 1285 1837 if( error ) return error; … … 1292 1844 inode_type = hal_remote_l32( XPTR( inode_cxy , &inode_ptr->type ) ); 1293 1845 1294 1295 assert( false , "not implemented\n" ); 1846 // TODO implement this function 1847 1848 assert( false , "not implemented\n" ); 1849 1296 1850 return 0; 1297 1851 } … … 1360 1914 assert( (indent < 16) , "depth cannot be larger than 15\n" ); 1361 1915 1362 // get inode cluster and local pointer1916 // get current inode cluster and local pointer 1363 1917 inode_cxy = GET_CXY( inode_xp ); 1364 1918 inode_ptr = GET_PTR( inode_xp ); … … 1428 1982 cxy_t dentry_cxy; 1429 1983 vfs_dentry_t * dentry_ptr; 1984 xptr_t parents_root_xp; // root of parent dentries xlist 1430 1985 1431 1986 // get target inode cluster and local pointer … … 1433 1988 vfs_inode_t * inode_ptr = GET_PTR( inode_xp ); 1434 1989 1435 // get extended pointer on associated dentry1436 dentry_xp = hal_remote_l64( XPTR( inode_cxy , &inode_ptr->parent_xp ));1437 1438 // check if target inode is the File System root1439 if( dentry_xp == XPTR_NULL )1990 // build extended pointer on parents dentries root 1991 parents_root_xp = XPTR( inode_cxy , &inode_ptr->parents ); 1992 1993 // check VFS root 1994 if( xlist_is_empty( parents_root_xp ) ) // inode is the VFS root 1440 1995 { 1441 1996 // build extended pointer on root name … … 1444 1999 else 1445 2000 { 1446 // get dentry cluster and local pointer 2001 // get first parent dentry cluster and pointers 2002 dentry_xp = XLIST_FIRST( parents_root_xp , vfs_dentry_t , parents ); 1447 2003 dentry_cxy = GET_CXY( dentry_xp ); 1448 2004 dentry_ptr = GET_PTR( dentry_xp ); … … 1520 2076 xptr_t * child_xp ) 1521 2077 { 1522 xptr_t xhtab_xp; // extended pointer on hash table containing children dentries 1523 xptr_t dentry_xp; // extended pointer on children dentry 2078 xptr_t xhtab_xp; // extended pointer on hash table for children dentries 2079 xptr_t dentry_xp; // extended pointer on children dentry 2080 cxy_t dentry_cxy; 2081 vfs_dentry_t * dentry_ptr; 1524 2082 1525 2083 // get parent inode cluster and local pointer … … 1530 2088 xhtab_xp = XPTR( parent_cxy , &parent_ptr->children ); 1531 2089 1532 // search extended pointer on matching dentry 1533 dentry_xp = xhtab_lookup( xhtab_xp , name ); 1534 1535 if( dentry_xp == XPTR_NULL ) return false; 1536 1537 // get dentry cluster and local pointer 1538 cxy_t dentry_cxy = GET_CXY( dentry_xp ); 1539 vfs_dentry_t * dentry_ptr = GET_PTR( dentry_xp ); 1540 1541 // return child inode 1542 *child_xp = (xptr_t)hal_remote_l64( XPTR( dentry_cxy , &dentry_ptr->child_xp ) ); 1543 return true; 2090 // get pointers on matching dentry 2091 dentry_xp = xhtab_lookup( xhtab_xp , name ); 2092 dentry_cxy = GET_CXY( dentry_xp ); 2093 dentry_ptr = GET_PTR( dentry_xp ); 2094 2095 if( dentry_xp == XPTR_NULL ) 2096 { 2097 return false; 2098 } 2099 else 2100 { 2101 *child_xp = (xptr_t)hal_remote_l64( XPTR( dentry_cxy , &dentry_ptr->child_xp ) ); 2102 return true; 2103 } 1544 2104 1545 2105 } // end vfs_get_child() … … 1553 2113 // last name in the path. The names are supposed to be separated by one or several '/' 1554 2114 // characters, that are not written in the <name> buffer. 2115 // 2116 // WARNING: the leading characters '/' in the path are skiped before analysis. 2117 // The path "/" identifies the VFS root, and is therefore anaysed as an empty 2118 // string. This empty string is dignaled by the (-1) return value. 1555 2119 ////////////////////////////////////////////////////////////////////////////////////////// 1556 2120 // @ current : pointer on first character to analyse in buffer containing the path. … … 1558 2122 // @ next : [out] pointer on next character to analyse in buffer containing the path. 1559 2123 // @ last : [out] true if the returned name is the last (NUL character found). 1560 // @ return 0 if success / return EINVALif string empty (first chracter is NUL).2124 // @ return 0 if success / return -1 if string empty (first chracter is NUL). 1561 2125 ////////////////////////////////////////////////////////////////////////////////////////// 1562 2126 static error_t vfs_get_name_from_path( char * current, … … 1570 2134 while( *ptr == '/' ) ptr++; 1571 2135 1572 // return EINVAL if string empty 1573 if( *ptr == 0 ) return EINVAL; 2136 // signal empty string 2137 if( *ptr == 0 ) 2138 { 2139 *last = true; 2140 return -1; 2141 } 1574 2142 1575 2143 // copy all characters in name until NUL or '/' … … 1594 2162 } // end vfs_get name_from_path() 1595 2163 1596 ////////////////////////////////////////////// 1597 error_t vfs_lookup( xptr_t cwd_xp,2164 /////////////////////////////////////////////// 2165 error_t vfs_lookup( xptr_t root_xp, 1598 2166 char * pathname, 1599 uint32_t mode, 1600 xptr_t * inode_xp ) 2167 uint32_t lookup_mode, 2168 xptr_t * inode_xp, 2169 char * last_name ) 1601 2170 { 1602 2171 char name[CONFIG_VFS_MAX_NAME_LENGTH]; // one name in path … … 1619 2188 bool_t create; // searched inode must be created if not found 1620 2189 bool_t excl; // searched inode must not exist 2190 bool_t par; // searched inode is the parent 1621 2191 thread_t * this; // pointer on calling thread descriptor 1622 2192 process_t * process; // pointer on calling process descriptor … … 1626 2196 process = this->process; 1627 2197 2198 // check pathname / root_xp consistency 2199 assert( ((pathname[0] != '/') || (root_xp == process->vfs_root_xp)), 2200 "root inode must be VFS root for path <%s>\n", pathname ); 2201 1628 2202 #if DEBUG_VFS_LOOKUP 1629 2203 uint32_t cycle = (uint32_t)hal_get_cycles(); 2204 char root_name[CONFIG_VFS_MAX_NAME_LENGTH]; 2205 vfs_inode_get_name( root_xp , root_name ); 1630 2206 if( DEBUG_VFS_LOOKUP < cycle ) 1631 printk("\n[%s] thread[%x,%x] enter for <%s>/ cycle %d\n",1632 __FUNCTION__, process->pid, this->trdid, pathname, cycle );2207 printk("\n[%s] thread[%x,%x] enter / root <%s> / path <%s> / mode %x / cycle %d\n", 2208 __FUNCTION__, process->pid, this->trdid, root_name, pathname, lookup_mode, cycle ); 1633 2209 #endif 1634 2210 1635 2211 // compute lookup flags 1636 dir = mode & VFS_LOOKUP_DIR; 1637 create = mode & VFS_LOOKUP_CREATE; 1638 excl = mode & VFS_LOOKUP_EXCL; 1639 1640 // get extended pointer on first inode to search 1641 if( pathname[0] == '/' ) parent_xp = process->vfs_root_xp; 1642 else parent_xp = cwd_xp; 1643 1644 // initialise other loop variables 1645 current = pathname; 1646 next = NULL; 1647 last = false; 1648 child_xp = XPTR_NULL; 1649 1650 // take lock on parent inode 1651 vfs_inode_lock( parent_xp ); 1652 1653 // sequencially loop on nodes in pathname 1654 // load from device if one node in path not found in inode tree 2212 dir = (lookup_mode & VFS_LOOKUP_DIR) == VFS_LOOKUP_DIR; 2213 create = (lookup_mode & VFS_LOOKUP_CREATE) == VFS_LOOKUP_CREATE; 2214 excl = (lookup_mode & VFS_LOOKUP_EXCL) == VFS_LOOKUP_EXCL; 2215 par = (lookup_mode & VFS_LOOKUP_PARENT) == VFS_LOOKUP_PARENT; 2216 2217 // initialise loop variables 2218 parent_xp = root_xp; 2219 current = pathname; 2220 next = NULL; 2221 last = false; 2222 child_xp = XPTR_NULL; 2223 2224 // loop on nodes in pathname 2225 // load from device if one node in path not found in Inode Tree 1655 2226 // exit loop when last name found (i.e. last == true) 1656 do 1657 { 1658 // get one name from path, and "last" flag 1659 vfs_get_name_from_path( current , name , &next , &last ); 2227 while( 1 ) 2228 { 2229 // get parent inode cluster and local pointer 2230 parent_cxy = GET_CXY( parent_xp ); 2231 parent_ptr = GET_PTR( parent_xp ); 2232 2233 // get one "name" from path, and "last" flag 2234 error = vfs_get_name_from_path( current , name , &next , &last ); 2235 2236 // VFS root case 2237 if ( error ) 2238 { 2239 2240 #if DEBUG_VFS_LOOKUP 2241 cycle = (uint32_t)hal_get_cycles(); 2242 if( DEBUG_VFS_LOOKUP < cycle ) 2243 printk("\n[%s] thread[%x,%x] exit / parent inode(%x,%x) / <%s> / cycle %d\n", 2244 __FUNCTION__ , process->pid, this->trdid, parent_cxy, parent_ptr, pathname, cycle ); 2245 #endif 2246 *inode_xp = process->vfs_root_xp; 2247 break; 2248 } 1660 2249 1661 2250 #if (DEBUG_VFS_LOOKUP & 1) … … 1665 2254 #endif 1666 2255 1667 // search achild dentry matching name in parent inode2256 // search the child dentry matching name in parent inode 1668 2257 found = vfs_get_child( parent_xp, 1669 2258 name, 1670 2259 &child_xp ); 1671 2260 1672 if (found == false ) // child not found in inode tree 2261 // analyse found & last, depending on lookup_mode 2262 if( found == false ) // not found in Inode Tree 1673 2263 { 2264 // when a inode is not found in the Inode Tree: 2265 // - if (last and par) the Inode Tree is not modified 2266 // - else we speculatively introduce a new (dentry/inode) in inode tree, 2267 // and scan the parent directory mapper to initialise it. 2268 // . if it is not found in the parent mapper: 2269 // - if(last and create), a brand new file or directory is created 2270 // - else, an error is reported 2271 // . if it is found in parent mapper: 2272 // - if( last and excl ), an error is reported 2273 // - else the new child (inode & dentry) is initialised in Inode Tree 2274 // - if the child is a directory, the child mapper is loaded from device 2275 2276 if( last && par ) // does nothing 2277 { 1674 2278 1675 2279 #if (DEBUG_VFS_LOOKUP & 1) 1676 2280 if( DEBUG_VFS_LOOKUP < cycle ) 1677 printk("\n[%s] thread[%x,%x] miss <%s> node => try to create it\n", 2281 printk("\n[%s] thread[%x,%x] child not found but only parent requested in <%s>\n", 2282 __FUNCTION__, process->pid, this->trdid, pathname ); 2283 #endif 2284 } 2285 else // try to get it from parent mapper 2286 { 2287 2288 #if (DEBUG_VFS_LOOKUP & 1) 2289 if( DEBUG_VFS_LOOKUP < cycle ) 2290 printk("\n[%s] thread[%x,%x] miss <%s> inode in Inode Tree => build from parent mapper\n", 1678 2291 __FUNCTION__, process->pid, this->trdid, name ); 1679 2292 #endif 1680 // if a child node is not found in the inode tree, 1681 // we introduce a new (dentry/inode) in inode tree, 1682 // and try to find it by scanning the parent directory mapper. 1683 // . if it is found in parent mapper: 1684 // - if the child is a directory, the child mapper is loaded from device 1685 // - if the child is not a directory, the search is completed 1686 // . if it is not found in the parent mapper: 1687 // - if ( not last or not create ) an error is reported 1688 // - if (last and create) a new file or directory is created 1689 1690 // release lock on parent inode 1691 vfs_inode_unlock( parent_xp ); 2293 // get parent inode FS type 2294 ctx_ptr = hal_remote_lpt( XPTR( parent_cxy,&parent_ptr->ctx ) ); 2295 fs_type = hal_remote_l32( XPTR( parent_cxy , &ctx_ptr->type ) ); 2296 2297 // select a cluster for new inode 2298 child_cxy = cluster_random_select(); 2299 2300 // define child inode type 2301 if( dir ) child_type = INODE_TYPE_DIR; 2302 else child_type = INODE_TYPE_FILE; 1692 2303 1693 // get parent inode cluster and local pointer 1694 parent_cxy = GET_CXY( parent_xp ); 1695 parent_ptr = GET_PTR( parent_xp ); 1696 1697 // get parent inode FS type 1698 ctx_ptr = hal_remote_lpt( XPTR( parent_cxy,&parent_ptr->ctx ) ); 1699 fs_type = hal_remote_l32( XPTR( parent_cxy , &ctx_ptr->type ) ); 1700 1701 // select a cluster for missing inode 1702 child_cxy = cluster_random_select(); 1703 1704 // define child inode type 1705 if( dir ) child_type = INODE_TYPE_DIR; 1706 else child_type = INODE_TYPE_FILE; 1707 1708 // insert a new child dentry/inode in inode tree 1709 error = vfs_add_child_in_parent( child_cxy, 1710 child_type, 1711 fs_type, 1712 parent_xp, 1713 name, 1714 &dentry_xp, 1715 &child_xp ); 1716 if( error ) 1717 { 1718 printk("\n[ERROR] in %s : cannot create node <%s> in path <%s>\n", 1719 __FUNCTION__ , name, pathname ); 1720 return -1; 1721 } 1722 1723 // get child inode local pointer 1724 child_ptr = GET_PTR( child_xp ); 2304 // insert (speculatively) a new child dentry/inode in inode tree 2305 error = vfs_add_child_in_parent( child_cxy, 2306 child_type, 2307 fs_type, 2308 parent_xp, 2309 name, 2310 &dentry_xp, 2311 &child_xp ); 2312 if( error ) 2313 { 2314 printk("\n[ERROR] in %s : cannot create inode <%s> in path <%s>\n", 2315 __FUNCTION__ , name, pathname ); 2316 return -1; 2317 } 2318 2319 // get child inode local pointer 2320 child_ptr = GET_PTR( child_xp ); 1725 2321 1726 2322 #if (DEBUG_VFS_LOOKUP & 1) … … 1729 2325 __FUNCTION__, process->pid, this->trdid, name, child_cxy ); 1730 2326 #endif 1731 // scan parent mapper to find the missing dentry, and complete 1732 // the initialisation of dentry and child inode desciptors 1733 if( parent_cxy == local_cxy ) 1734 1735 { 1736 error = vfs_fs_child_init( parent_ptr, 1737 name, 1738 child_xp ); 1739 } 1740 else 1741 { 1742 rpc_vfs_fs_child_init_client( parent_cxy, 1743 parent_ptr, 1744 name, 1745 child_xp, 1746 &error ); 1747 } 1748 1749 if ( error ) // child not found in parent mapper 1750 { 1751 if ( last && create ) // add a new dentry in parent 2327 // scan parent mapper to find the missing dentry, and complete 2328 // the initialisation of dentry and child inode desciptors 2329 if( parent_cxy == local_cxy ) 2330 1752 2331 { 1753 error = vfs_new_child_init( parent_xp, 1754 dentry_xp, 1755 child_xp ); 1756 if ( error ) 2332 error = vfs_fs_child_init( parent_ptr, 2333 name, 2334 child_xp ); 2335 } 2336 else 2337 { 2338 rpc_vfs_fs_child_init_client( parent_cxy, 2339 parent_ptr, 2340 name, 2341 child_xp, 2342 &error ); 2343 } 2344 2345 if ( error ) // child not found in parent mapper 2346 { 2347 if ( last && create ) // add a brand new dentry in parent 1757 2348 { 1758 printk("\n[ERROR] in %s : cannot init inode <%s> in path <%s>\n", 1759 __FUNCTION__, name, pathname ); 1760 vfs_remove_child_from_parent( child_xp ); 2349 error = vfs_new_child_init( parent_xp, 2350 dentry_xp, 2351 child_xp ); 2352 if ( error ) 2353 { 2354 printk("\n[ERROR] in %s : cannot init inode <%s> in path <%s>\n", 2355 __FUNCTION__, name, pathname ); 2356 vfs_remove_child_from_parent( dentry_xp ); 2357 return -1; 2358 } 2359 2360 #if (DEBUG_VFS_LOOKUP & 1) 2361 if( DEBUG_VFS_LOOKUP < cycle ) 2362 printk("\n[%s] thread[%x,%x] child <%s> not found in parent mapper => create it\n", 2363 __FUNCTION__, process->pid, this->trdid, name ); 2364 #endif 2365 } 2366 else // not last or not create => error 2367 { 2368 printk("\n[ERROR] in %s : <%s> node not found in parent for <%s>\n", 2369 __FUNCTION__ , name , pathname ); 2370 vfs_remove_child_from_parent( dentry_xp ); 1761 2371 return -1; 1762 2372 } 2373 } 2374 else // child has been found in parent mapper 2375 { 2376 // check the excl 2377 if( last && create && excl ) 2378 { 2379 printk("\n[ERROR] in %s : node already exist <%s>\n", 2380 __FUNCTION__, name ); 2381 return -1; 2382 } 1763 2383 1764 2384 #if (DEBUG_VFS_LOOKUP & 1) 1765 2385 if( DEBUG_VFS_LOOKUP < cycle ) 1766 printk("\n[%s] thread[%x,%x] created inode <%s> in path\n",2386 printk("\n[%s] thread[%x,%x] initialised inode <%s> from parent mapper\n", 1767 2387 __FUNCTION__, process->pid, this->trdid, name ); 1768 2388 #endif 1769 } 1770 else // not last or not create => error 1771 { 1772 printk("\n[ERROR] in %s : <%s> node not found in parent for <%s>\n", 1773 __FUNCTION__ , name , pathname ); 1774 vfs_remove_child_from_parent( child_xp ); 1775 return ENOENT; 2389 // load child mapper from device if child is a directory (prefetch) 2390 uint32_t type = hal_remote_l32( XPTR( child_cxy , &child_ptr->type ) ); 2391 if( type == INODE_TYPE_DIR ) 2392 { 2393 if( child_cxy == local_cxy ) 2394 { 2395 error = vfs_inode_load_all_pages( child_ptr ); 2396 } 2397 else 2398 { 2399 rpc_vfs_inode_load_all_pages_client( child_cxy, 2400 child_ptr, 2401 &error ); 2402 } 2403 if ( error ) 2404 { 2405 printk("\n[ERROR] in %s : cannot load <%s> from device\n", 2406 __FUNCTION__ , name ); 2407 vfs_remove_child_from_parent( dentry_xp ); 2408 return -1; 2409 } 2410 2411 #if (DEBUG_VFS_LOOKUP & 1) 2412 if( DEBUG_VFS_LOOKUP < cycle ) 2413 printk("\n[%s] thread[%x,%x] loaded directory mapper for <%s> from IOC\n", 2414 __FUNCTION__ , process->pid, this->trdid, name ); 2415 #endif 2416 } 1776 2417 } 1777 2418 } 1778 else // child found in parent mapper1779 {1780 // load child mapper from device if child is a directory (prefetch)1781 if( hal_remote_l32( XPTR( child_cxy , &child_ptr->type ) ) == INODE_TYPE_DIR )1782 {1783 if( child_cxy == local_cxy )1784 {1785 error = vfs_inode_load_all_pages( child_ptr );1786 }1787 else1788 {1789 rpc_vfs_inode_load_all_pages_client( child_cxy,1790 child_ptr,1791 &error );1792 }1793 if ( error )1794 {1795 printk("\n[ERROR] in %s : cannot load <%s> from device\n",1796 __FUNCTION__ , name );1797 vfs_remove_child_from_parent( child_xp );1798 return EIO;1799 }1800 1801 #if (DEBUG_VFS_LOOKUP & 1)1802 if( DEBUG_VFS_LOOKUP < cycle )1803 printk("\n[%s] thread[%x,%x] loaded from IOC device mapper for <%s> in <%s>\n",1804 __FUNCTION__ , process->pid, this->trdid, name, pathname );1805 #endif1806 }1807 }1808 1809 // take lock on parent inode1810 vfs_inode_lock( parent_xp );1811 2419 } 1812 else // childfound in inode tree2420 else // child directly found in inode tree 1813 2421 { 1814 2422 1815 2423 #if (DEBUG_VFS_LOOKUP & 1) 1816 2424 if( DEBUG_VFS_LOOKUP < cycle ) 1817 printk("\n[%s] thread[%x,%x] found <%s> / inode %x in cluster %x\n", 1818 __FUNCTION__, process->pid, this->trdid, name, GET_PTR(child_xp), GET_CXY(child_xp) ); 1819 #endif 2425 printk("\n[%s] thread[%x,%x] found <%s> in Inode Tree / inode (%x,%x)\n", 2426 __FUNCTION__, process->pid, this->trdid, name, GET_CXY(child_xp), GET_PTR(child_xp) ); 2427 #endif 2428 // get child inode local pointer and cluster 1820 2429 child_ptr = GET_PTR( child_xp ); 1821 2430 child_cxy = GET_CXY( child_xp ); 1822 parent_cxy = GET_CXY( parent_xp ); 1823 parent_ptr = GET_PTR( parent_xp ); 1824 1825 if( last && (mode & VFS_LOOKUP_CREATE) && (mode & VFS_LOOKUP_EXCL) ) 2431 2432 // check the excl flag 2433 if( last && create && excl ) 1826 2434 { 1827 printk("\n[ERROR] in %s : node already exist <%s>\n", __FUNCTION__, name ); 1828 return EINVAL; 2435 printk("\n[ERROR] in %s : node <%s> already exist\n", 2436 __FUNCTION__, name ); 2437 return -1; 1829 2438 } 1830 2439 } … … 1842 2451 1843 2452 // take lock on child inode and release lock on parent 1844 vfs_inode_lock( child_xp ); 1845 vfs_inode_unlock( parent_xp ); 1846 1847 // update loop variables 1848 parent_xp = child_xp; 1849 current = next; 1850 } 1851 while( last == false ); 1852 1853 // release lock 1854 vfs_inode_unlock( parent_xp ); 2453 // vfs_inode_lock( child_xp ); 2454 // vfs_inode_unlock( parent_xp ); 2455 2456 // exit when last 2457 if ( last ) // last inode in path => return relevant info 2458 { 2459 if ( par ) // return parent inode and child name 2460 { 1855 2461 1856 2462 #if DEBUG_VFS_LOOKUP 1857 2463 cycle = (uint32_t)hal_get_cycles(); 1858 2464 if( DEBUG_VFS_LOOKUP < cycle ) 1859 printk("\n[%s] thread[%x,%x] exit for <%s> cycle %d\n", 1860 __FUNCTION__ , process->pid, this->trdid, pathname, cycle ); 1861 #endif 1862 1863 // return searched pointer 1864 if( mode & VFS_LOOKUP_PARENT ) *inode_xp = parent_xp; 1865 else *inode_xp = child_xp; 2465 printk("\n[%s] thread[%x,%x] exit / parent inode(%x,%x) / <%s> / cycle %d\n", 2466 __FUNCTION__ , process->pid, this->trdid, parent_cxy, parent_ptr, pathname, cycle ); 2467 #endif 2468 *inode_xp = parent_xp; 2469 strcpy( last_name , name ); 2470 break; 2471 } 2472 else // return child inode name 2473 { 2474 2475 #if DEBUG_VFS_LOOKUP 2476 cycle = (uint32_t)hal_get_cycles(); 2477 if( DEBUG_VFS_LOOKUP < cycle ) 2478 printk("\n[%s] thread[%x,%x] exit / child inode (%x,%x) / <%s> / cycle %d\n", 2479 __FUNCTION__ , process->pid, this->trdid, child_cxy, child_ptr, pathname, cycle ); 2480 #endif 2481 *inode_xp = child_xp; 2482 break; 2483 } 2484 } 2485 else // not the last inode in path => update loop variables 2486 { 2487 parent_xp = child_xp; 2488 current = next; 2489 } 2490 } 1866 2491 1867 2492 return 0; 1868 2493 1869 2494 } // end vfs_lookup() 1870 1871 1872 2495 1873 2496 /////////////////////////////////////////////// … … 1954 2577 cycle = (uint32_t)hal_get_cycles(); 1955 2578 if( DEBUG_VFS_NEW_CHILD_INIT < cycle ) 1956 printk("\n[%s] thread[%x,%x] exit / parent <%s> / child <% > / cycle %d\n",2579 printk("\n[%s] thread[%x,%x] exit / parent <%s> / child <%s> / cycle %d\n", 1957 2580 __FUNCTION__ , this->process->pid, this->trdid, parent_name, child_name, cycle ); 1958 2581 #endif … … 1962 2585 } // end vfs_new_child_init() 1963 2586 1964 //////////////////////////////////////////// 1965 error_t vfs_get_path( xptr_t searched_xp, 1966 char * buffer, 1967 uint32_t max_size ) 1968 { 1969 xptr_t dentry_xp; // extended pointer on current dentry 1970 char * name; // local pointer on current dentry name 1971 uint32_t length; // length of current dentry name 1972 uint32_t count; // number of characters written in buffer 1973 uint32_t index; // slot index in buffer 1974 xptr_t inode_xp; // extended pointer on 1975 1976 // implementation note: 1977 // we use two variables "index" and "count" because the buffer 1978 // is written in decreasing index order (from leaf to root) 1979 // TODO : handle conflict with a concurrent rename [AG] 1980 // FIXME : handle synchro in the loop [AG] 1981 1982 // set the NUL character in buffer / initialise buffer index and count 2587 ////////////////////////////////////////// 2588 error_t vfs_get_path( xptr_t inode_xp, 2589 char * buffer, 2590 char ** first, 2591 uint32_t max_size ) 2592 { 2593 xptr_t dentry_xp; // extended pointer on current dentry 2594 vfs_dentry_t * dentry_ptr; // local pointer on current dentry 2595 cxy_t dentry_cxy; // current dentry cluster identifier 2596 xptr_t name_xp; // extended pointer on current dentry name 2597 uint32_t length; // length of current dentry name 2598 int32_t index; // slot index in buffer 2599 xptr_t current_xp; // extended pointer on current inode 2600 vfs_inode_t * current_ptr; // local pointer on current inode 2601 cxy_t current_cxy; // current inode cluster identifier 2602 xptr_t vfs_root_xp; // extended pointer on VFS root inode 2603 vfs_inode_t * vfs_root_ptr; // local pointer on VFS root inode 2604 cxy_t vfs_root_cxy; // VFS root inode cluster identifier 2605 xptr_t lock_xp; // extended pointer on Inode Tree lock 2606 xptr_t parents_root_xp; // extended pointer on current inode parents root 2607 bool_t found; // condition to exit the while loop 2608 2609 thread_t * this = CURRENT_THREAD; 2610 process_t * process = this->process; 2611 2612 #if DEBUG_VFS_GET_PATH 2613 uint32_t cycle = (uint32_t)hal_get_cycles(); 2614 if( DEBUG_VFS_GET_PATH < cycle ) 2615 printk("\n[%s] thread[%x,%x] enter : inode (%x,%x) / cycle %d\n", 2616 __FUNCTION__ , process->pid, this->trdid, 2617 GET_CXY( inode_xp ), GET_PTR( inode_xp ), cycle ); 2618 #endif 2619 2620 // set the NUL character in buffer / initialise buffer index 1983 2621 buffer[max_size - 1] = 0; 1984 count = 1; 1985 index = max_size - 2; 2622 index = (int32_t)(max_size - 1); 1986 2623 1987 2624 // initialize current inode 1988 inode_xp = searched_xp; 1989 1990 // exit when root inode found (i.e. dentry_xp == XPTR_NULL) 2625 current_xp = inode_xp; 2626 2627 // build extended pointer on lock protecting Inode Tree 2628 vfs_root_xp = process->vfs_root_xp; 2629 vfs_root_ptr = GET_PTR( vfs_root_xp ); 2630 vfs_root_cxy = GET_CXY( vfs_root_xp ); 2631 lock_xp = XPTR( vfs_root_cxy , &vfs_root_ptr->main_lock ); 2632 2633 // take lock protecting Inode Tree in read mode 2634 remote_rwlock_rd_acquire( lock_xp ); 2635 2636 // traverse Inode Tree from target inode to VFS root 2637 // selecting always the first parent dentry 2638 // the buffer is written in "reverse order" (from target inode to root) 2639 // exit the while loop when the VFS root has been found 1991 2640 do 1992 2641 { 1993 // get inode cluster and local pointer 1994 cxy_t inode_cxy = GET_CXY( inode_xp ); 1995 vfs_inode_t * inode_ptr = GET_PTR( inode_xp ); 1996 1997 // get extended pointer on parent dentry 1998 dentry_xp = (xptr_t)hal_remote_l64( XPTR( inode_cxy , inode_ptr->parent_xp ) ); 1999 2000 // get dentry cluster and local pointer 2001 cxy_t dentry_cxy = GET_CXY( dentry_xp ); 2002 vfs_dentry_t * dentry_ptr = GET_PTR( dentry_xp ); 2003 2004 // get dentry name length and pointer 2005 length = hal_remote_l32( XPTR( dentry_cxy , &dentry_ptr->length ) ); 2006 name = (char *)hal_remote_lpt( XPTR( dentry_cxy , &dentry_ptr->name ) ); 2007 2008 // update index and count 2009 index -= (length + 1); 2010 count += (length + 1); 2011 2012 // check buffer overflow 2013 if( count >= max_size ) 2642 // get current inode cluster and local pointer 2643 current_cxy = GET_CXY( current_xp ); 2644 current_ptr = GET_PTR( current_xp ); 2645 2646 // build extended pointer on parents dentries root 2647 parents_root_xp = XPTR( current_cxy , ¤t_ptr->parents ); 2648 2649 // compute exit condition <=> current inode is VFS root 2650 found = xlist_is_empty( parents_root_xp ); 2651 2652 if( found ) // parent is the VFS root 2014 2653 { 2015 printk("\n[ERROR] in %s : kernel buffer too small\n", __FUNCTION__ ); 2016 return EINVAL; 2654 if( index == (int32_t)(max_size - 1) ) 2655 { 2656 // update index 2657 index--; 2658 2659 // set separator 2660 buffer[index] = '/'; 2661 2662 // check buffer overflow 2663 assert( (index >= 0) , "kernel buffer too small\n" ); 2664 2665 } 2017 2666 } 2018 2019 // update pathname 2020 hal_remote_memcpy( XPTR( local_cxy , &buffer[index + 1] ) , 2021 XPTR( dentry_cxy , name ) , length ); 2022 buffer[index] = '/'; 2023 2024 // get extended pointer on next inode 2025 inode_xp = (xptr_t)hal_remote_l64( XPTR( dentry_cxy , dentry_ptr->parent ) ); 2026 } 2027 while( (dentry_xp != XPTR_NULL) ); 2028 2667 else // not the VFS root 2668 { 2669 // get first parent dentry cluster and pointers 2670 dentry_xp = XLIST_FIRST( parents_root_xp , vfs_dentry_t , parents ); 2671 dentry_cxy = GET_CXY( dentry_xp ); 2672 dentry_ptr = GET_PTR( dentry_xp ); 2673 2674 // get extended pointer on dentry name and name length 2675 name_xp = XPTR( dentry_cxy , dentry_ptr->name ); 2676 length = hal_remote_l32( XPTR( dentry_cxy , &dentry_ptr->length ) ); 2677 2678 #if (DEBUG_VFS_GET_PATH & 1) 2679 char debug_name[CONFIG_VFS_MAX_NAME_LENGTH]; 2680 hal_remote_strcpy( XPTR( local_cxy , debug_name ) , name_xp ); 2681 if( DEBUG_VFS_GET_PATH < cycle ) 2682 printk("\n[%s] thread(%x,%s) get current dentry <%s> in cluster %x\n", 2683 __FUNCTION__ , process->pid, this->trdid, debug_name, current_cxy ); 2684 #endif 2685 // update index 2686 index -= (length + 1); 2687 2688 // check buffer overflow 2689 assert( (index >= 0) , "kernel buffer too small\n" ); 2690 2691 // update pathname 2692 hal_remote_memcpy( XPTR( local_cxy , &buffer[index + 1] ) , 2693 name_xp , length ); 2694 2695 // set separator 2696 buffer[index] = '/'; 2697 2698 // get extended pointer on parent inode 2699 current_xp = XPTR( dentry_cxy , 2700 hal_remote_lpt( XPTR( dentry_cxy , &dentry_ptr->parent ) ) ); 2701 } 2702 } 2703 while( found == false ); 2704 2705 // release lock protecting Inode Tree in read mode 2706 remote_rwlock_rd_release( lock_xp ); 2707 2708 #if DEBUG_VFS_GET_PATH 2709 cycle = (uint32_t)hal_get_cycles(); 2710 if( DEBUG_VFS_GET_PATH < cycle ) 2711 printk("\n[%s] thread[%x,%x] exit : path <%s> / cycle %d\n", 2712 __FUNCTION__ , process->pid, this->trdid, &buffer[index], cycle ); 2713 #endif 2714 2715 // return pointer on first character in buffer 2716 *first = &buffer[index]; 2029 2717 return 0; 2030 2718 … … 2033 2721 2034 2722 //////////////////////////////////////////////////////////////////// 2035 error_t vfs_add_child_in_parent( cxy_t child_ inode_cxy,2036 vfs_inode_type_t child_ inode_type,2723 error_t vfs_add_child_in_parent( cxy_t child_cxy, 2724 vfs_inode_type_t child_type, 2037 2725 vfs_fs_type_t fs_type, 2038 2726 xptr_t parent_inode_xp, 2039 2727 char * name, 2040 xptr_t * dentry_xp,2728 xptr_t * child_dentry_xp, 2041 2729 xptr_t * child_inode_xp ) 2042 2730 { 2043 error_t error; 2044 xptr_t new_dentry_xp; // extended pointer on created dentry 2045 vfs_dentry_t * new_dentry_ptr; // created dentry local pointer 2046 xptr_t new_inode_xp; // extended pointer on created child inode 2047 cxy_t parent_inode_cxy; // parent inode cluster identifier 2048 vfs_inode_t * parent_inode_ptr; // parent inode local pointer 2049 2050 // get parent inode cluster and local pointer 2051 parent_inode_cxy = GET_CXY( parent_inode_xp ); 2731 error_t error; 2732 cxy_t parent_cxy; // parent inode cluster identifier 2733 vfs_inode_t * parent_inode_ptr; // parent inode local pointer 2734 xptr_t new_dentry_xp; // extended pointer on created dentry 2735 vfs_dentry_t * new_dentry_ptr; // created dentry local pointer 2736 xptr_t new_inode_xp; // extended pointer on created child inode 2737 vfs_inode_t * new_inode_ptr; // local pointer on created child inode 2738 2739 xptr_t parents_root_xp; // extended pointer on child inode "parents" field 2740 xptr_t parents_entry_xp; // extended pointer on child dentry "parents" field 2741 xptr_t children_xhtab_xp; // extended pointer on parent inode "children" field 2742 xptr_t children_entry_xp; // extended pointer on child dentry "children" field 2743 2744 // get parent inode cluster and pointer 2745 parent_cxy = GET_CXY( parent_inode_xp ); 2052 2746 parent_inode_ptr = GET_PTR( parent_inode_xp ); 2053 2747 … … 2058 2752 thread_t * this = CURRENT_THREAD; 2059 2753 if( DEBUG_VFS_ADD_CHILD < cycle ) 2060 printk("\n[%s] thread[%x,%x] enter / child <%s> cxy %x / parent <%s> cxy %x/ cycle %d\n",2061 __FUNCTION__, this->process->pid, this->trdid, name, child_inode_cxy,2062 parent_name, parent_inode_cxy,(uint32_t)hal_get_cycles() );2063 #endif 2064 2065 // 1. create dentry 2066 if( parent_ inode_cxy == local_cxy ) // parent cluster is the local cluster2754 printk("\n[%s] thread[%x,%x] enter / child <%s> / parent <%s> / cycle %d\n", 2755 __FUNCTION__, this->process->pid, this->trdid, name, 2756 parent_name, (uint32_t)hal_get_cycles() ); 2757 #endif 2758 2759 // 1. create dentry in parent cluster 2760 if( parent_cxy == local_cxy ) // parent cluster is local 2067 2761 { 2068 2762 error = vfs_dentry_create( fs_type, 2069 2763 name, 2070 parent_inode_ptr,2071 2764 &new_dentry_xp ); 2072 2765 } 2073 else // parent cluster is remote2074 { 2075 rpc_vfs_dentry_create_client( parent_ inode_cxy,2766 else // parent cluster is remote 2767 { 2768 rpc_vfs_dentry_create_client( parent_cxy, 2076 2769 fs_type, 2077 2770 name, 2078 parent_inode_ptr,2079 2771 &new_dentry_xp, 2080 2772 &error ); … … 2084 2776 { 2085 2777 printk("\n[ERROR] in %s : cannot create dentry <%s> in cluster %x\n", 2086 __FUNCTION__ , name , parent_ inode_cxy );2778 __FUNCTION__ , name , parent_cxy ); 2087 2779 return -1; 2088 2780 } … … 2093 2785 #if(DEBUG_VFS_ADD_CHILD & 1) 2094 2786 if( DEBUG_VFS_ADD_CHILD < cycle ) 2095 printk("\n[%s] thread[%x,%x] / dentry <%s> created in cluster %x\n", 2096 __FUNCTION__, this->process->pid, this->trdid, name, parent_inode_cxy ); 2097 #endif 2098 2099 // 2. create child inode TODO : define attr / mode / uid / gid 2787 printk("\n[%s] thread[%x,%x] / dentry <%s> created (%x,%x)\n", 2788 __FUNCTION__, this->process->pid, this->trdid, name, parent_cxy, new_dentry_ptr ); 2789 #endif 2790 2791 // 2. create child inode in child cluster 2792 // TODO : define attr / mode / uid / gid 2100 2793 uint32_t attr = 0; 2101 2794 uint32_t mode = 0; … … 2103 2796 uint32_t gid = 0; 2104 2797 2105 if( child_inode_cxy == local_cxy ) // child cluster is the local cluster 2106 { 2107 error = vfs_inode_create( new_dentry_xp, 2108 fs_type, 2109 child_inode_type, 2798 if( child_cxy == local_cxy ) // child cluster is local 2799 { 2800 error = vfs_inode_create( fs_type, 2801 child_type, 2110 2802 attr, 2111 2803 mode, … … 2116 2808 else // child cluster is remote 2117 2809 { 2118 rpc_vfs_inode_create_client( child_inode_cxy, 2119 new_dentry_xp, 2810 rpc_vfs_inode_create_client( child_cxy, 2120 2811 fs_type, 2121 child_ inode_type,2812 child_type, 2122 2813 attr, 2123 2814 mode, … … 2131 2822 { 2132 2823 printk("\n[ERROR] in %s : cannot create inode in cluster %x\n", 2133 __FUNCTION__ , child_ inode_cxy );2824 __FUNCTION__ , child_cxy ); 2134 2825 2135 if( parent_ inode_cxy == local_cxy ) vfs_dentry_destroy( new_dentry_ptr );2136 else rpc_vfs_dentry_destroy_client( parent_ inode_cxy , new_dentry_ptr );2826 if( parent_cxy == local_cxy ) vfs_dentry_destroy( new_dentry_ptr ); 2827 else rpc_vfs_dentry_destroy_client( parent_cxy , new_dentry_ptr ); 2137 2828 return -1; 2138 2829 } 2139 2830 2831 // get new inode local pointer 2832 new_inode_ptr = GET_PTR( new_inode_xp ); 2833 2140 2834 #if(DEBUG_VFS_ADD_CHILD & 1) 2141 2835 if( DEBUG_VFS_ADD_CHILD < cycle ) 2142 printk("\n[%s] thread[%x,%x] / inode <%s> created in cluster %x\n", 2143 __FUNCTION__ , this->process->pid, this->trdid, name , child_inode_cxy ); 2144 #endif 2145 2146 // 3. update "child_xp" field in dentry and increment refcounts 2147 hal_remote_s64( XPTR( parent_inode_cxy , &new_dentry_ptr->child_xp ) , new_inode_xp ); 2148 vfs_inode_remote_up( new_inode_xp ); 2149 vfs_dentry_remote_up( new_dentry_xp ); 2836 printk("\n[%s] thread[%x,%x] / inode <%s> created (%x,%x)\n", 2837 __FUNCTION__ , this->process->pid, this->trdid, name , child_cxy, new_inode_ptr ); 2838 #endif 2839 2840 // 3. register new_dentry in new_inode xlist of parents 2841 parents_root_xp = XPTR( child_cxy , &new_inode_ptr->parents ); 2842 parents_entry_xp = XPTR( parent_cxy, &new_dentry_ptr->parents ); 2843 xlist_add_first( parents_root_xp , parents_entry_xp ); 2844 hal_remote_atomic_add( XPTR( child_cxy , &new_inode_ptr->links ) , 1 ); 2845 2846 #if(DEBUG_VFS_ADD_CHILD & 1) 2847 if( local_cxy == 1 ) 2848 // if( DEBUG_VFS_ADD_CHILD < cycle ) 2849 printk("\n[%s] thread[%x,%x] / dentry (%x,%x) registered in child inode (%x,%x)\n", 2850 __FUNCTION__, this->process->pid, this->trdid, 2851 parent_cxy, new_dentry_ptr, child_cxy, new_inode_ptr ); 2852 #endif 2853 2854 // 4. register new_dentry in parent_inode xhtab of children 2855 children_xhtab_xp = XPTR( parent_cxy , &parent_inode_ptr->children ); 2856 children_entry_xp = XPTR( parent_cxy , &new_dentry_ptr->children ); 2857 xhtab_insert( children_xhtab_xp , name , children_entry_xp ); 2858 2859 #if(DEBUG_VFS_ADD_CHILD & 1) 2860 if( DEBUG_VFS_ADD_CHILD < cycle ) 2861 printk("\n[%s] thread[%x,%x] / dentry (%x,%x) registered in parent inode (%x,%x)\n", 2862 __FUNCTION__, this->process->pid, this->trdid, 2863 parent_cxy, new_dentry_ptr, parent_cxy, parent_inode_ptr ); 2864 #endif 2865 2866 // 5. update "parent" and "child_xp" fields in new_dentry 2867 hal_remote_s64( XPTR( parent_cxy , &new_dentry_ptr->child_xp ) , new_inode_xp ); 2868 hal_remote_spt( XPTR( parent_cxy , &new_dentry_ptr->parent ) , parent_inode_ptr ); 2150 2869 2151 2870 #if DEBUG_VFS_ADD_CHILD … … 2157 2876 2158 2877 // return extended pointer on dentry & child inode 2159 * dentry_xp= new_dentry_xp;2160 *child_inode_xp = new_inode_xp;2878 *child_dentry_xp = new_dentry_xp; 2879 *child_inode_xp = new_inode_xp; 2161 2880 return 0; 2162 2881 2163 2882 } // end vfs_add_child_in_parent() 2164 2883 2165 //////////////////////////////////////////////////// 2166 void vfs_remove_child_from_parent( xptr_t inode_xp ) 2167 { 2168 cxy_t inode_cxy; 2169 vfs_inode_t * inode_ptr; 2170 xptr_t dentry_xp; 2171 cxy_t dentry_cxy; 2172 vfs_dentry_t * dentry_ptr; 2884 ///////////////////////////////////////////////////// 2885 void vfs_remove_child_from_parent( xptr_t dentry_xp ) 2886 { 2887 cxy_t parent_cxy; // parent inode cluster identifier 2888 cxy_t child_cxy; // child inode cluster identifier 2889 vfs_dentry_t * dentry_ptr; // local pointer on dentry 2890 xptr_t child_inode_xp; // extended pointer on child inode 2891 vfs_inode_t * child_inode_ptr; // local pointer on child inode 2892 vfs_inode_t * parent_inode_ptr; // local pointer on parent inode 2893 uint32_t links; // number of child inode parents 2894 2895 char dentry_name[CONFIG_VFS_MAX_NAME_LENGTH]; 2173 2896 2174 // get inode cluster and local pointer 2175 inode_cxy = GET_CXY( inode_xp ); 2176 inode_ptr = GET_PTR( inode_xp ); 2177 2178 // get associated dentry cluster and pointers 2179 dentry_xp = hal_remote_l64( XPTR( inode_cxy , &inode_ptr->parent_xp ) ); 2180 dentry_cxy = GET_CXY( dentry_xp ); 2897 // get parent cluster and dentry local pointer 2898 parent_cxy = GET_CXY( dentry_xp ); 2181 2899 dentry_ptr = GET_PTR( dentry_xp ); 2182 2900 2183 // check dentry refcount 2184 assert( ( hal_remote_l32( XPTR( dentry_cxy , &dentry_ptr->refcount ) ) == 1 ), 2185 "dentry refcount must be 1\n" ); 2186 2187 // check inode refcount 2188 assert( ( hal_remote_l32( XPTR( inode_cxy , &inode_ptr->refcount ) ) == 1 ), 2189 "inode refcount must be 1\n" ); 2190 2191 // decrement refcount for inode and dentry 2192 vfs_inode_remote_down( inode_xp ); 2193 vfs_dentry_remote_down( dentry_xp ); 2194 2195 // delete dentry 2196 if( dentry_cxy == local_cxy ) 2901 // get a local copy of dentry name 2902 hal_remote_strcpy( XPTR( local_cxy , dentry_name ), 2903 XPTR( parent_cxy , &dentry_ptr->name ) ); 2904 2905 // get parent_inode local pointer 2906 parent_inode_ptr = hal_remote_lpt( XPTR( parent_cxy , &dentry_ptr->parent ) ); 2907 2908 // get child cluster and child_inode pointers 2909 child_inode_xp = hal_remote_l64( XPTR( parent_cxy , &dentry_ptr->child_xp ) ); 2910 child_cxy = GET_CXY( child_inode_xp ); 2911 child_inode_ptr = GET_PTR( child_inode_xp ); 2912 2913 // remove dentry from parent_inode 2914 xhtab_remove( XPTR( parent_cxy , &parent_inode_ptr->children ), 2915 dentry_name, 2916 XPTR( parent_cxy , &dentry_ptr->children ) ); 2917 2918 // remove dentry from child_inode 2919 xlist_unlink( XPTR( parent_cxy , &dentry_ptr->parents ) ); 2920 links = hal_remote_atomic_add( XPTR( child_cxy , &child_inode_ptr->links ) , -1 ); 2921 2922 // delete dentry descriptor 2923 if( parent_cxy == local_cxy ) 2197 2924 { 2198 2925 vfs_dentry_destroy( dentry_ptr ); … … 2200 2927 else 2201 2928 { 2202 rpc_vfs_dentry_destroy_client( dentry_cxy,2929 rpc_vfs_dentry_destroy_client( parent_cxy, 2203 2930 dentry_ptr ); 2204 2931 } 2205 2932 2206 // delete inode 2207 if( inode_cxy == local_cxy ) 2208 { 2209 vfs_inode_destroy( inode_ptr ); 2210 } 2211 else 2212 { 2213 rpc_vfs_inode_destroy_client( inode_cxy, 2214 inode_ptr ); 2933 // delete child_inode descriptor if last link 2934 if( links == 1 ) 2935 { 2936 if( child_cxy == local_cxy ) 2937 { 2938 vfs_inode_destroy( child_inode_ptr ); 2939 } 2940 else 2941 { 2942 rpc_vfs_inode_destroy_client( child_cxy , child_inode_ptr ); 2943 } 2215 2944 } 2216 2945 … … 2374 3103 } // end vfs_fs_child_init() 2375 3104 3105 //////////////////////////////////////////////// 3106 error_t vfs_fs_sync_inode( vfs_inode_t * inode ) 3107 { 3108 error_t error = 0; 3109 3110 // check arguments 3111 assert( (inode != NULL) , "inode pointer is NULL\n"); 3112 3113 // get inode FS type 3114 vfs_fs_type_t fs_type = inode->ctx->type; 3115 3116 // call relevant FS function 3117 if( fs_type == FS_TYPE_FATFS ) 3118 { 3119 error = fatfs_sync_inode( inode ); 3120 } 3121 else if( fs_type == FS_TYPE_RAMFS ) 3122 { 3123 assert( false , "should not be called for RAMFS\n" ); 3124 } 3125 else if( fs_type == FS_TYPE_DEVFS ) 3126 { 3127 assert( false , "should not be called for DEVFS\n" ); 3128 } 3129 else 3130 { 3131 assert( false , "undefined file system type\n" ); 3132 } 3133 3134 return error; 3135 3136 } // end vfs_fs_sync_inode() 3137 3138 //////////////////////////////////////////////// 3139 error_t vfs_fs_sync_fat( vfs_fs_type_t fs_type ) 3140 { 3141 error_t error = 0; 3142 3143 // call relevant FS function 3144 if( fs_type == FS_TYPE_FATFS ) 3145 { 3146 error = fatfs_sync_fat(); 3147 } 3148 else if( fs_type == FS_TYPE_RAMFS ) 3149 { 3150 assert( false , "should not be called for RAMFS\n" ); 3151 } 3152 else if( fs_type == FS_TYPE_DEVFS ) 3153 { 3154 assert( false , "should not be called for DEVFS\n" ); 3155 } 3156 else 3157 { 3158 assert( false , "undefined file system type\n" ); 3159 } 3160 3161 return error; 3162 3163 } // end vfs_fs_sync_fat() 3164 3165 ////////////////////////////////////////////////////// 3166 error_t vfs_fs_sync_free_info( vfs_fs_type_t fs_type ) 3167 { 3168 error_t error = 0; 3169 3170 // call relevant FS function 3171 if( fs_type == FS_TYPE_FATFS ) 3172 { 3173 error = fatfs_sync_free_info(); 3174 } 3175 else if( fs_type == FS_TYPE_RAMFS ) 3176 { 3177 assert( false , "should not be called for RAMFS\n" ); 3178 } 3179 else if( fs_type == FS_TYPE_DEVFS ) 3180 { 3181 assert( false , "should not be called for DEVFS\n" ); 3182 } 3183 else 3184 { 3185 assert( false , "undefined file system type\n" ); 3186 } 3187 3188 return error; 3189 3190 } // end vfs_fs_sync_fat() 3191 2376 3192 ///////////////////////////////////////////////// 2377 3193 error_t vfs_fs_cluster_alloc( uint32_t fs_type, -
trunk/kernel/fs/vfs.h
r602 r610 69 69 *****************************************************************************************/ 70 70 71 #define VFS_LOOKUP_DIR 0x01 /* the searched inode is a directory*/71 #define VFS_LOOKUP_DIR 0x01 /* the searched inode must be a directory */ 72 72 #define VFS_LOOKUP_OPEN 0x02 /* the search is for an open/opendir */ 73 73 #define VFS_LOOKUP_PARENT 0x04 /* return the parent inode (not the inode itself) */ 74 74 #define VFS_LOOKUP_CREATE 0x10 /* file must be created if missing */ 75 #define VFS_LOOKUP_EXCL 0x20 /* file cannot previously exist */ 75 #define VFS_LOOKUP_EXCL 0x20 /* file cannot previously exist */ 76 76 77 77 /****************************************************************************************** … … 117 117 /****************************************************************************************** 118 118 * This structure define a VFS inode. 119 * It contains an extended pointer on the parent dentry, and (for directory only) 120 * an hash table (xhtab) registering all children dentries. 121 * The <parent> inode is unique for a directory (no hard links for directories). 122 * For a file, the parent field points to the first dentry who created this inode. 119 * An inode has several children dentries (if it is a directory), an can have several 120 * parents dentries (if it hass several aliases links): 121 * - The "parents" field is the root of the xlist of parents dentries, and the "links" 122 * fiels define the number of aliases parent dentries. only a FILE inode can have 123 * several parents (no hard links for directories). 124 * - The "children" field is an embedded xhtab containing pointers on all local children 125 * dentries. This set of children is empty for a FILE inode. 123 126 * Synchronisation: 124 * - the main_lock (remote_ busylock) is used during the inode tree traversal,125 * or for inode modification (add/remove children ).126 * - the data_lock (remote_rwlock) is used during read/write accesses to the data127 * stored in the mapper.128 * - the mapper lock (remote rwlock) is only used during the radix tree traversal129 * to return the relevant page for read/write.127 * - the main_lock (remote_rwlock) is used during the inode tree traversal, 128 * or for inode modification (add/remove children in xhtab). 129 * - the size_lock (remote_rwlock) is used during read/write accesses to the size 130 * field in the mapper. 131 * - access to the data stored in the associated mapper use the mapper remote_rwlock 132 * protecting radix tree traversal and modifications. 130 133 *****************************************************************************************/ 131 134 … … 158 161 { 159 162 struct vfs_ctx_s * ctx; /*! local pointer on FS context */ 160 uint32_t gc; /*! generation counter */161 163 uint32_t inum; /*! inode identifier (unique in file system) */ 162 164 uint32_t attr; /*! inode attributes (see above) */ 163 165 vfs_inode_type_t type; /*! inode type (see above) */ 164 166 uint32_t size; /*! number of bytes */ 165 uint32_t links; /*! number of alias dentry */166 167 uint32_t uid; /*! user owner identifier */ 167 168 uint32_t gid; /*! group owner identifier */ 168 169 uint32_t rights; /*! access rights */ 169 uint32_t refcount; /*! reference counter (all pointers)*/170 xptr_t parent_xp; /*! extended pointer on parent dentry*/170 xlist_entry_t parents; /*! root of list of parents dentries */ 171 uint32_t links; /*! number of parent dentries (hard links) */ 171 172 xhtab_t children; /*! embedded xhtab of children dentries */ 172 remote_rwlock_t data_lock; /*! protect read/write to data and to size*/173 remote_ busylock_tmain_lock; /*! protect inode tree traversal and modifs */174 175 xlist_entry_twait_root; /*! root of threads waiting on this inode */173 remote_rwlock_t size_lock; /*! protect read/write to size */ 174 remote_rwlock_t main_lock; /*! protect inode tree traversal and modifs */ 175 // list_entry_t list; /*! member of set of inodes in same cluster */ 176 // list_entry_t wait_root; /*! root of threads waiting on this inode */ 176 177 struct mapper_s * mapper; /*! associated file cache */ 177 178 void * extend; /*! fs_type_specific inode extension */ … … 183 184 #define VFS_ISUID 0x0004000 184 185 #define VFS_ISGID 0x0002000 185 #define VFS_ISVTX 0x0001000186 define VFS_ISVTX 0x0001000 186 187 187 188 #define VFS_IRWXU 0x0000700 … … 203 204 * This structure defines a directory entry. 204 205 * A dentry contains the name of a remote file/dir, an extended pointer on the 205 * inode representing this file/dir, a nd alocal pointer on the inode representing206 * inode representing this file/dir, a local pointer on the inode representing 206 207 * the parent directory. 208 * A dentry can be member of the set of children of a given directory inode (xhtab). 209 * A dentry can be member of the set of parents of a given inode (xlist). 207 210 *****************************************************************************************/ 208 211 … … 212 215 char name[CONFIG_VFS_MAX_NAME_LENGTH]; 213 216 uint32_t length; /*! name length (bytes) */ 214 uint32_t refcount; /*! reference counter (all pointers) */215 217 struct vfs_inode_s * parent; /*! local pointer on parent inode */ 216 218 xptr_t child_xp; /*! extended pointer on child inode */ 217 xlist_entry_t list; /*! member of list of dentries with same key */ 219 xlist_entry_t children; /*! member of set of children dentries */ 220 xlist_entry_t parents; /*! member of set of parent dentries */ 218 221 void * extend; /*! FS specific extension */ 219 222 } … … 301 304 302 305 303 304 306 /****************************************************************************************** 305 307 * These low-level functions access / modify a VFS inode descriptor … … 314 316 * This function allocates memory from local cluster for an inode descriptor and the 315 317 * associated mapper. It initialise these descriptors from arguments values. 316 * The parent dentry must have been previously created.317 318 * If the client thread is not running in the cluster containing this inode, 318 319 * it must use the rpc_vfs_inode_create_client() function. 319 320 ****************************************************************************************** 320 * @ dentry_xp : extended pointer on associated dentry (in parent inode cluster).321 321 * @ fs_type : file system type. 322 322 * @ inode_type : inode type. … … 328 328 * @ return 0 if success / return ENOMEM or EINVAL if error. 329 329 *****************************************************************************************/ 330 error_t vfs_inode_create( xptr_t dentry_xp, 331 vfs_fs_type_t fs_type, 330 error_t vfs_inode_create( vfs_fs_type_t fs_type, 332 331 vfs_inode_type_t inode_type, 333 332 uint32_t attr, … … 340 339 * This function releases memory allocated to an inode descriptor, including 341 340 * all memory allocated to the mapper (both mapper descriptor and radix tree). 342 * The mapper should not contain any dirty page (shold be synchronized before deletion), 343 * and the inode refcount must be zero. 341 * The mapper should not contain any dirty page (should be synchronized before deletion). 344 342 * It must be executed by a thread running in the cluster containing the inode. 345 343 * Use the rpc_vfs_inode_destroy_client() function if required. … … 348 346 *****************************************************************************************/ 349 347 void vfs_inode_destroy( vfs_inode_t * inode ); 350 351 /******************************************************************************************352 * This function atomically increment/decrement the inode refcount.353 * It can be called by any thread running in any cluster.354 *****************************************************************************************/355 void vfs_inode_remote_up( xptr_t inode_xp );356 void vfs_inode_remote_down( xptr_t inode_xp );357 348 358 349 /****************************************************************************************** … … 423 414 * This function allocates memory from local cluster for a dentry descriptor, 424 415 * initialises it from arguments values, and returns the extended pointer on dentry. 425 * The inode field is not initialized, because the inode does not exist yet.426 416 * If the client thread is not running in the target cluster for this inode, 427 417 * it must use the rpc_dentry_create_client() function. … … 429 419 * @ fs_type : file system type. 430 420 * @ name : directory entry file/dir name. 431 * @ parent : local pointer on parent inode.432 421 * @ dentry_xp : [out] buffer for extended pointer on created dentry. 433 422 * @ return 0 if success / return ENOMEM or EINVAL if error. … … 435 424 error_t vfs_dentry_create( vfs_fs_type_t fs_type, 436 425 char * name, 437 vfs_inode_t * parent,438 426 xptr_t * dentry_xp ); 439 427 440 428 /****************************************************************************************** 441 * This function re leases memory allocated to a dentry descriptor.442 * The dentry refcount must be zero.429 * This function removes the dentry from the parent inode xhtab, and releases the memory 430 * allocated to the dentry descriptor. 443 431 * It must be executed by a thread running in the cluster containing the dentry. 444 432 * Use the rpc_vfs_dentry_destroy_client() function if required. … … 447 435 *****************************************************************************************/ 448 436 void vfs_dentry_destroy( vfs_dentry_t * dentry ); 449 450 /******************************************************************************************451 * These functions atomically increment/decrement the dentry refcount.452 * It can be called by any thread running in any cluster.453 *****************************************************************************************/454 void vfs_dentry_remote_up( xptr_t dentry_xp );455 void vfs_dentry_remote_down( xptr_t dentry_xp );456 437 457 438 … … 496 477 497 478 /****************************************************************************************** 498 * These functions access / modify the distributed VFS Inode Tree e499 *****************************************************************************************/ 500 501 /****************************************************************************************** 502 * This function returns in a kernel bufferallocated by the caller function,503 * the pathname of a file/dir identified by an extended pointer on the inode.479 * These functions access / modify the distributed VFS Inode Tree 480 *****************************************************************************************/ 481 482 /****************************************************************************************** 483 * This function returns in a kernel <buffer> allocated by the caller function, 484 * the pathname of a file/dir identified by the <inode_xp> argument. 504 485 * It traverse the Inode Tree from the target node to the root. 505 486 * It can be called by any thread running in any cluster. 506 ****************************************************************************************** 507 * @ inode_xp : pointer on inode descriptor. 508 * @ buffer : kernel buffer for pathname (must be allocated by caller). 509 * @ size : max number of characters in buffer. 487 * As this buffer if filled in "reverse order" (i.e. from the target inode to the root), 488 * the pathname is stored in the higher part of the buffer. 489 * A pointer on the first character of the pathname is returned in <first> buffer. 490 * 491 * WARNING : This function takes & releases the remote_rwlock protecting the Inode Tree. 492 ****************************************************************************************** 493 * @ inode_xp : [in] extended pointer on target inode descriptor. 494 * @ buffer : [in] kernel buffer for pathname (allocated by caller). 495 * @ first : [out] pointer on first character in buffer. 496 * @ max_size : [in] max number of characters in buffer. 510 497 * @ return 0 if success / return EINVAL if buffer too small. 511 498 *****************************************************************************************/ 512 499 error_t vfs_get_path( xptr_t inode_xp, 513 500 char * buffer, 501 char ** first, 514 502 uint32_t max_size ); 515 503 516 504 /****************************************************************************************** 517 * This function takes a pathname (absolute or relative to cwd) and returns an extended 518 * pointer on the associated inode. 505 * This function traverses the the Inode Tree, from inode identified by the <root_xp> 506 * argument, and returns in <inode_xp> the inode identified by the < pathname> argument. 507 * It can be called by a thread running in any cluster. 508 * It supports the following flags that define the lookup modes : 509 * - VFS_LOOKUP_DIR : the searched inode must be a directory 510 * - VFS_LOOKUP_OPEN : the search is for an open/opendir 511 * - VFS_LOOKUP_PARENT : return the parent inode (not the inode itself) 512 * - VFS_LOOKUP_CREATE : file/directory must be created if missing on IOC 513 * - VFS_LOOKUP_EXCL : file cannot previously exist 514 * As the inode Tree is a cache, the search policy is the following : 519 515 * - If a given directory name in the path is not found in the inode tree, it try to load 520 516 * the missing dentry/inode couple, from informations found in the parent directory. 521 * - If this directory entry does not exist on device, it returns an error.522 * - If the the file identified by the pathname does not exist on devicebut the523 * flag CREATE is set, the inode is created. 524 * - If the the file identified by the pathname exist on device but both flags EXCL517 * - If this directory entry does not exist on IOC, it returns an error. 518 * - If the the file identified by the pathname does not exist on IOC but the 519 * flag CREATE is set, the inode is created. It returns an error otherwise. 520 * - If the the file identified by the pathname exist on device, but both flags EXCL 525 521 * and CREATE are set, an error is returned. 526 ****************************************************************************************** 527 * @ cwd_xp : extended pointer on current directory (for relative path). 528 * @ pathname : path in kernel space (can be relative or absolute). 529 * @ lookup_mode : flags defining the working mode (defined above in this file). 522 * - If the PARENT flag is set, it returns in <inode_xp> an extended pointer on the parent 523 * inode, and copies in <last_name> buffer a string containing the last name in path. 524 * 525 * WARNING : The remote_rwlock protecting the Inode Tree must be taken by the caller. 526 * 527 * TODO the access rights are not checked yet. 528 ****************************************************************************************** 529 * @ root_xp : [in] extended pointer on root inode (can be root of a subtree). 530 * @ pathname : [in] path (can be relative or absolute). 531 * @ lookup_mode : [in] flags defining the searching mode. 530 532 * @ inode_xp : [out] buffer for extended pointer on searched inode. 533 * @ last_name : [out] pointer on buffer for last name in path. 531 534 * @ return 0 if success / ENOENT if inode not found , EACCES if permisson denied, 532 * EAGAIN if a new complete lookup must be made 533 *****************************************************************************************/ 534 error_t vfs_lookup( xptr_t cwd_xp, 535 *****************************************************************************************/ 536 error_t vfs_lookup( xptr_t root_xp, 535 537 char * pathname, 536 538 uint32_t lookup_mode, 537 xptr_t * inode_xp ); 539 xptr_t * inode_xp, 540 char * last_name ); 538 541 539 542 /****************************************************************************************** 540 543 * This function creates a new couple dentry/inode, and insert it in the Inode-Tree. 544 * Only the distributed Inode Tree is modified: it does NOT modify the parent mapper, 545 * and does NOT update the FS on IOC device. 541 546 * It can be executed by any thread running in any cluster (can be different from both 542 * the child cluster and the parent cluster), as it uses RPCs if required. 543 * Only the distributed Inode Tree is modified: Even for a new file, this function 544 * does NOT modify the parent mapper, and does NOT update the FS on IOC device. 547 * the child cluster and the parent cluster). 545 548 * 546 549 * [Implementation] … … 563 566 * @ return 0 if success / -1 if dentry or inode cannot be created. 564 567 *****************************************************************************************/ 565 error_t vfs_add_child_in_parent( cxy_t child_inode cxy,566 vfs_inode_type_t chil g_inode_type,568 error_t vfs_add_child_in_parent( cxy_t child_inode_cxy, 569 vfs_inode_type_t child_inode_type, 567 570 vfs_fs_type_t fs_type, 568 571 xptr_t parent_inode_xp, … … 572 575 573 576 /****************************************************************************************** 574 * This function removes a couple dentry/inode from the Inode-Tree. 575 * Both the inode and dentry references counters must be 1. 577 * This function removes a remote dentry from the Inode-Tree. 578 * - It removes the dentry from the parent inode xhtab ("children" field), and from the 579 * child inode xlist ("parents" field). 580 * - It releases the memory allocated to the dentry descriptor. 581 * - If the number of parents of the child inode is one, it also releases the memory 582 * allocated to the child inode. 583 * Only the Inode Tree is modified: it does NOT modify the parent mapper, 584 * and does NOT update the FS on IOC device. 576 585 * It can be executed by any thread running in any cluster (can be different from both 577 * the inode cluster and the dentry cluster) , as it uses RPCs if required.578 ****************************************************************************************** 579 * @ child_xp : extended pointer on removed inode.580 *****************************************************************************************/ 581 void vfs_remove_child_from_parent( xptr_t inode_xp );586 * the inode cluster and the dentry cluster). 587 ****************************************************************************************** 588 * @ dentry_xp : extended pointer on removed dentry. 589 *****************************************************************************************/ 590 void vfs_remove_child_from_parent( xptr_t dentry_xp ); 582 591 583 592 /****************************************************************************************** … … 599 608 *****************************************************************************************/ 600 609 error_t vfs_new_child_init( xptr_t parent_xp, 601 xptr_t dentry_xp,602 xptr_t child_xp );610 xptr_t dentry_xp, 611 xptr_t child_xp ); 603 612 604 613 /****************************************************************************************** … … 661 670 /****************************************************************************************** 662 671 * This function allocates a vfs_file_t structure in the cluster containing the inode 663 * associated to the file identified by the <cwd_xp> & <path> arguments.672 * identified by the <root_xp> & <path> arguments. 664 673 * It initializes it, register it in the reference process fd_array identified by the 665 * <process > argument, and returns both the extended pointer on the file descriptor,666 * and the allocated index in the fd_array.674 * <process_xp> argument, and returns both the extended pointer on the file descriptor, 675 * and the allocated index in the <file_xp> and <file_id> buffers. 667 676 * The pathname can be relative to current directory or absolute. 668 * If the inode does not exist in the inode cache, it try to find the file on the mounted677 * If the inode does not exist in the inode cache, it try to find the file on the IOC 669 678 * device, and creates an inode on a pseudo randomly selected cluster if found. 670 679 * It the requested file does not exist on device, it creates a new inode if the 671 680 * O_CREAT flag is set, and return an error otherwise. 681 * 682 * WARNING : this function takes & releases the remote_rwlock protecting the Inode Tree. 672 683 ****************************************************************************************** 673 * @ process : local pointer on local process descriptor copy.684 * @ root_xp : extended pointer on path root inode. 674 685 * @ path : file pathname (absolute or relative to current directory). 686 * @ process_xp : extended pointer on client reference process. 675 687 * @ flags : defined in vfs_file_t structure. 676 688 * @ mode : access rights (as defined by chmod). … … 679 691 * @ return 0 if success / return non-zero if error. 680 692 *****************************************************************************************/ 681 error_t vfs_open( struct process_s * process,693 error_t vfs_open( xptr_t root_xp, 682 694 char * path, 695 xptr_t process_xp, 683 696 uint32_t flags, 684 697 uint32_t mode, … … 721 734 /****************************************************************************************** 722 735 * This function is called by the kernel to create in the file system a new directory 723 * entry identified by the <cwd_xp> & <path_1>, linked to the node identified by the 724 * <cwd_xp> & <path_2> arguments. It can be any type of node. 725 * If the link is successful, the link count of the target node is incremented. 726 * <path_1> and <path_2> share equal access rights to the underlying object. 736 * identified by the <root_xp> & <path> arguments, with the access permission defined 737 * by the <rights> argument. All nodes in the path - but the last - must exist. 738 * 739 * WARNING : this function takes & releases the remote_rwlock protecting the Inode Tree. 740 ****************************************************************************************** 741 * @ root_xp : extended pointer on path root inode (any inode in Inode Tree). 742 * @ path : pathname (absolute or relative to current directory). 743 * @ rights : access rights. 744 * @ returns 0 if success / -1 if error. 745 *****************************************************************************************/ 746 error_t vfs_mkdir( xptr_t root_xp, 747 char * path, 748 uint32_t rights ); 749 750 /****************************************************************************************** 751 * This function is called by the kernel to create in the file system a new directory 752 * entry identified by the <new_root_xp> & <new_path> arguments, to be linked to an 753 * existing inode, identified by the <old_root_xp> & <old_path> arguments. 754 * If the link is successful, the link count of the target inode is incremented. 755 * The <new_path> and <old_path> share equal access rights to the underlying inode. 727 756 * Both the IOC device and the Inode Tree are modified. 728 ****************************************************************************************** 729 * @ cwd_xp : extended pointer on current working directory file descriptor. 730 * @ path_1 : new pathname (absolute or relative to current directory). 731 * @ path_1 : existing pathname (absolute or relative to current directory). 757 $ 758 * TODO This function should handle any type of node, but the current implementation 759 * handles only the FILE and DIR types. 760 * 761 * WARNING : this function takes & releases the remote_rwlock protecting the Inode Tree. 762 ****************************************************************************************** 763 * @ old_root_xp : extended pointer on old path root inode (any inode in Inode Tree). 764 * @ old_path : old pathname (absolute or relative to current directory). 765 * @ nld_root_xp : extended pointer on new path root inode (any inode in Inode Tree). 766 * @ new_path : new pathname (absolute or relative to current directory). 732 767 * @ returns 0 if success / -1 if error. 733 768 *****************************************************************************************/ 734 error_t vfs_link( xptr_t cwd_xp, 735 char * path_1, 736 char * path_2 ); 769 error_t vfs_link( xptr_t old_root_xp, 770 char * old_path, 771 xptr_t new_root_xp, 772 char * new_path ); 737 773 738 774 /****************************************************************************************** 739 775 * This function is called by the kernel to remove from the file system a directory entry 740 * identified by the < cwd_xp> & <path> arguments. The target node can be any type of node.741 * The link count of the target node is decremented. If the removed link is the last,742 * the targetnode is deleted.776 * identified by the <root_xp> & <path> arguments. 777 * The link count of the target node is decremented. 778 * If the removed link is the last, the target inode is deleted. 743 779 * Both the IOC device and the Inode Tree are modified. 744 ****************************************************************************************** 745 * @ cwd_xp : extended pointer on the current working directory file descriptor. 780 * 781 * TODO This function should handle any type of node, but the current implementation 782 * handles only only the FILE and DIR types. 783 * 784 * WARNING : this function takes & releases the remote_rwlock protecting the Inode Tree. 785 ****************************************************************************************** 786 * @ root_xp : extended pointer on root inode (can be any inode in Inode Tree). 746 787 * @ path : pathname (absolute or relative to current directory). 747 788 * @ returns 0 if success / -1 if error. 748 789 *****************************************************************************************/ 749 error_t vfs_unlink( xptr_t cwd_xp,790 error_t vfs_unlink( xptr_t root_xp, 750 791 char * path ); 751 792 752 793 /****************************************************************************************** 753 * This function returns, in the structure pointed by the <st> pointer, 754 * various informations on the inode identified by the <inode_xp> argument. 755 * TODO : only partially implemented yet... 756 ****************************************************************************************** 757 * @ inode_xp : extended pointer on the remote inode. 794 * This function returns, in the structure pointed by the <st> pointer, various 795 * informations on the inode identified by the <root_inode_xp> and <patname> arguments. 796 * 797 * TODO : only partially implemented yet (only size and inum fields). 798 * 799 * WARNING : this function takes & releases the remote_rwlock protecting the Inode Tree. 800 ****************************************************************************************** 801 * @ root_xp : extended pointer on path root inode (any inode in Inode Tree) 802 * @ pathname : pathname to target inode. 758 803 * @ st : local pointer on the stat structure in kernel space. 759 804 * @ returns 0 if success / -1 if error. 760 805 *****************************************************************************************/ 761 error_t vfs_stat( xptr_t inode_xp, 806 error_t vfs_stat( xptr_t root_xp, 807 char * pathname, 762 808 struct stat * st ); 763 809 … … 775 821 776 822 /****************************************************************************************** 777 * This function creates a new inode and associated dentry for the directory defined 778 * by the <cwd_xp> & <path> arguments. 823 * This function creates a new directory as defined by the <root_xp> & <path> arguments. 779 824 * TODO not implemented yet... 780 825 ****************************************************************************************** 781 * @ cwd_xp : extended pointer on the current working directory file descriptor.782 * @ path : pathname (absolute or relative to current directory).826 * @ root_xp : extended pointer on the path root directory. 827 * @ path : pathname (absolute or relative to CWD). 783 828 * @ mode : access rights (as defined by chmod) 784 829 * @ returns 0 if success / -1 if error. 785 830 *****************************************************************************************/ 786 error_t vfs_mkdir( xptr_t cwd_xp,831 error_t vfs_mkdir( xptr_t root_xp, 787 832 char * path, 788 833 uint32_t mode ); 789 834 790 835 /****************************************************************************************** 791 * This function makes the directory identified by <cwd_xp / path> arguments to become792 * t he working directory for the calling process.836 * This function makes the directory identified by the <root_xp and <path> arguments 837 * to become the working directory for the calling process. 793 838 ****************************************************************************************** 794 * @ cwd_xp : extended pointer on current directory file descriptor (relative path).795 * @ path : file pathname (absolute or relative to current directory).839 * @ root_xp : extended pointer on the path root directory. 840 * @ path : pathname (absolute or relative to CWD). 796 841 * return 0 if success / -1 if error. 797 842 *****************************************************************************************/ 798 error_t vfs_chdir( xptr_t cwd_xp,843 error_t vfs_chdir( xptr_t root_xp, 799 844 char * path ); 800 845 801 846 /****************************************************************************************** 802 * This function change the access rigths for the file identified by the <cwd_xp / path>803 * arguments. The new access rights aredefined by the <mode> argument value.847 * This function change the access rigths for the file/directory identified by the 848 * <root_xp> and <path> arguments as defined by the <mode> argument value. 804 849 ****************************************************************************************** 805 * @ cwd_xp : extended pointer on current directory file descriptor (relative path).806 * @ path : file pathname (absolute or relative to current directory).807 * @ mode : access rights new value.850 * @ root_xp : extended pointer on the path root directory. 851 * @ path : pathname (absolute or relative to CWD). 852 * @ mode : access rights 808 853 * return 0 if success / -1 if error. 809 854 *****************************************************************************************/ 810 error_t vfs_chmod( xptr_t cwd_xp,855 error_t vfs_chmod( xptr_t root_xp, 811 856 char * path, 812 857 uint32_t mode ); … … 816 861 * TODO not implemented yet 817 862 ****************************************************************************************** 818 * @ path : FIFO pathname (absolute or relative to current directory).819 * @ cwd_xp : extended pointer on the current working directory file descriptor.820 * @ mode 821 *****************************************************************************************/ 822 error_t vfs_mkfifo( xptr_t cwd_xp,863 * @ root_xp : extended pointer on the path root directory. 864 * @ path : pathname (absolute or relative to CWD). 865 * @ mode : access rights new value. 866 *****************************************************************************************/ 867 error_t vfs_mkfifo( xptr_t root_xp, 823 868 char * path, 824 869 uint32_t mode ); … … 905 950 906 951 /***************************************************************************************** 907 * This function updates the FS on the IOC device for the FAT itself.908 * It scan all clusters registered in the FAT mapper, and copies to device909 * each page marked as dirty.952 * This function updates the FS defined by the <fs_type> argument on the IOC device 953 * for the FAT itself. It scan all clusters registered in the FAT mapper, and copies 954 * to device each page marked as dirty. 910 955 * 911 956 * Depending on the file system type, it calls the relevant, FS specific function. 912 957 * It can be called by a thread running in any cluster. 913 958 ***************************************************************************************** 959 * @ fs_type : specific file system type. 914 960 * @ return 0 if success / return EIO if failure during device access. 915 961 ****************************************************************************************/ 916 error_t vfs_fs_sync_fat( v oid);962 error_t vfs_fs_sync_fat( vfs_fs_type_t fs_type ); 917 963 918 964 /***************************************************************************************** 919 * This function updates the free clusters info on the IOC device. 965 * This function updates the free clusters info on the IOC device for the FS defined 966 * by the <fs_type> argument. 920 967 * 921 968 * Depending on the file system type, it calls the relevant, FS specific function. 922 969 * It can be called by a thread running in any cluster. 923 970 ***************************************************************************************** 971 * @ fs_type : specific file system type. 924 972 * @ return 0 if success / return EIO if failure during device access. 925 973 ****************************************************************************************/ 926 error_t vfs_fs_sync_free_info( v oid);974 error_t vfs_fs_sync_free_info( vfs_fs_type_t fs_type ); 927 975 928 976 /******************************************************************************************
Note: See TracChangeset
for help on using the changeset viewer.