Changeset 610 for trunk/kernel/fs/vfs.c
- Timestamp:
- Dec 27, 2018, 7:38:58 PM (4 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
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,
Note: See TracChangeset
for help on using the changeset viewer.