Changeset 602 for trunk/kernel/fs/vfs.c
- Timestamp:
- Dec 3, 2018, 12:15:53 PM (4 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/kernel/fs/vfs.c
r598 r602 57 57 extern char * lock_type_str[]; // allocated in kernel_init.c 58 58 59 ////////////////////////////////////////////////////////////////////////////////////////// 60 // Context related functions59 /////////////////////////////////////////////////////////////////////////////////////////// 60 // VFS Context related functions 61 61 ////////////////////////////////////////////////////////////////////////////////////////// 62 62 … … 123 123 124 124 ////////////////////////////////////////////////////////////////////////////////////////// 125 // Inoderelated functions125 // VFS inode descriptor related functions 126 126 ////////////////////////////////////////////////////////////////////////////////////////// 127 127 … … 145 145 vfs_fs_type_t fs_type, 146 146 vfs_inode_type_t inode_type, 147 void * extend,148 147 uint32_t attr, 149 148 uint32_t rights, … … 228 227 inode->ctx = ctx; 229 228 inode->mapper = mapper; 230 inode->extend = extend;229 inode->extend = NULL; 231 230 232 231 // initialise inode field in mapper … … 258 257 } // end vfs_inode_create() 259 258 260 //////////////////////////////////////////////// 261 error_t vfs_inode_destroy( vfs_inode_t * inode ) 262 { 263 assert( (inode->refcount == 0) , "inode refcount non zero\n" ); 259 ///////////////////////////////////////////// 260 void vfs_inode_destroy( vfs_inode_t * inode ) 261 { 262 263 // check inode refcount 264 assert( (inode->refcount == 0) , "inode refcount non zero\n" ); 264 265 265 266 // release memory allocated for mapper … … 272 273 kmem_free( &req ); 273 274 274 return 0;275 276 275 } // end vfs_inode_destroy() 277 278 /////////////////////////////////////////////279 error_t vfs_inode_load( vfs_inode_t * parent,280 char * name,281 xptr_t child_xp )282 {283 284 #if DEBUG_VFS_INODE_LOAD285 uint32_t cycle = (uint32_t)hal_get_cycles();286 if( DEBUG_VFS_INODE_LOAD < cycle )287 printk("\n[%s] thread %x enter for <%s> / cycle %d\n",288 __FUNCTION__, CURRENT_THREAD , name , cycle );289 #endif290 291 error_t error = 0;292 293 assert( (parent != NULL) , "parent pointer is NULL\n");294 295 assert( (child_xp != XPTR_NULL) , "child pointer is NULL\n");296 297 // get parent inode FS type298 vfs_fs_type_t fs_type = parent->ctx->type;299 300 // call relevant FS function301 if( fs_type == FS_TYPE_FATFS )302 {303 error = fatfs_inode_load( parent , name , child_xp );304 }305 else if( fs_type == FS_TYPE_RAMFS )306 {307 assert( false , "should not be called for RAMFS\n" );308 }309 else if( fs_type == FS_TYPE_DEVFS )310 {311 assert( false , "should not be called for DEVFS\n" );312 }313 else314 {315 assert( false , "undefined file system type\n" );316 }317 318 #if DEBUG_VFS_INODE_LOAD319 cycle = (uint32_t)hal_get_cycles();320 if( DEBUG_VFS_INODE_LOAD < cycle )321 printk("\n[%s] thread %x exit for <%s> / cycle %d\n",322 __FUNCTION__, CURRENT_THREAD , name , cycle );323 #endif324 325 return error;326 327 } // end vfs_inode_load()328 276 329 277 //////////////////////////////////////////// … … 429 377 } // end vfs_inode_get_name() 430 378 379 /////////////////////////////////////////////////////// 380 error_t vfs_inode_load_all_pages( vfs_inode_t * inode ) 381 { 382 383 assert( (inode != NULL) , "inode pointer is NULL\n" ); 384 385 uint32_t page_id; 386 xptr_t page_xp; 387 388 mapper_t * mapper = inode->mapper; 389 uint32_t size = inode->size; 390 391 assert( (mapper != NULL) , "mapper pointer is NULL\n" ); 392 393 #if DEBUG_VFS_INODE_LOAD_ALL 394 uint32_t cycle = (uint32_t)hal_get_cycles(); 395 thread_t * this = CURRENT_THREAD; 396 char name[CONFIG_VFS_MAX_NAME_LENGTH]; 397 vfs_inode_get_name( XPTR( local_cxy , inode ) , name ); 398 if( DEBUG_VFS_INODE_LOAD_ALL < cycle ) 399 printk("\n[%s] thread[%x,%x] enter for <%s> in cluster %x / cycle %d\n", 400 __FUNCTION__, this->process->pid, this->trdid, name, local_cxy, cycle ); 401 #endif 402 403 // compute number of pages 404 uint32_t npages = size >> CONFIG_PPM_PAGE_SHIFT; 405 if( (size & CONFIG_PPM_PAGE_MASK) || (size == 0) ) npages++; 406 407 // loop on pages 408 for( page_id = 0 ; page_id < npages ; page_id ++ ) 409 { 410 // If the mage is missing, this function allocates the missing page, 411 // and load the page from IOC device into mapper 412 page_xp = mapper_remote_get_page( XPTR( local_cxy , mapper ), page_id ); 413 414 if( page_xp == XPTR_NULL ) return -1; 415 } 416 417 #if DEBUG_VFS_INODE_LOAD_ALL 418 cycle = (uint32_t)hal_get_cycles(); 419 if( DEBUG_VFS_INODE_LOAD_ALL < cycle ) 420 printk("\n[%s] thread[%x,%x] exit for <%x> in cluster %x / cycle %d\n", 421 __FUNCTION__, this->process->pid, this->trdid, name, local_cxy, cycle ); 422 #endif 423 424 return 0; 425 426 } // end vfs_inode_load_all_pages() 427 431 428 //////////////////////////////////////////////////////////////////////////////////////////// 432 // Dentryrelated functions429 // VFS dentry descriptor related functions 433 430 ////////////////////////////////////////////////////////////////////////////////////////// 434 431 … … 480 477 dentry->length = length; 481 478 dentry->parent = parent; 479 dentry->extend = NULL; 482 480 strcpy( dentry->name , name ); 483 481 … … 509 507 cycle = (uint32_t)hal_get_cycles(); 510 508 if( DEBUG_VFS_DENTRY_CREATE < cycle ) 511 printk("\n[%s] thread[%x,%x] exit for <%s> / dentry %x/ cycle %d\n",512 __FUNCTION__, this->process->pid, this->trdid, name, dentry, cycle );509 printk("\n[%s] thread[%x,%x] exit for <%s> / dentry [%x,%x] / cycle %d\n", 510 __FUNCTION__, this->process->pid, this->trdid, name, local_cxy, dentry, cycle ); 513 511 #endif 514 512 … … 517 515 } // end vfs_dentry_create() 518 516 519 //////////////////////////////////////////////// ///520 error_tvfs_dentry_destroy( vfs_dentry_t * dentry )521 { 522 error_t error; 523 524 assert( (dentry->refcount == 0) , __FUNCTION__, "dentry refcount non zero\n" );517 //////////////////////////////////////////////// 518 void vfs_dentry_destroy( vfs_dentry_t * dentry ) 519 { 520 521 // check dentry refcount 522 assert( (dentry->refcount == 0) , "dentry refcount non zero\n" ); 525 523 526 524 // get pointer on parent inode … … 528 526 529 527 // remove this dentry from parent inode htab 530 error = xhtab_remove( XPTR( local_cxy , &parent->children ), 531 dentry->name, 532 XPTR( local_cxy , &dentry->list ) ); 533 534 if( error ) return EINVAL; 528 xhtab_remove( XPTR( local_cxy , &parent->children ), 529 dentry->name, 530 XPTR( local_cxy , &dentry->list ) ); 535 531 536 532 // release memory allocated to dentry … … 540 536 kmem_free( &req ); 541 537 542 return 0; 538 } // end vfs_dentry_destroy() 539 540 ////////////////////////////////////////////// 541 void vfs_dentry_remote_up( xptr_t dentry_xp ) 542 { 543 // get dentry cluster and local pointer 544 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 ); 543 548 } 544 549 550 //////////////////////////////////////////////// 551 void vfs_dentry_remote_down( xptr_t dentry_xp ) 552 { 553 // get dentry cluster and local pointer 554 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 545 560 546 561 547 562 ////////////////////////////////////////////////////////////////////////////////////////// 548 // File descriptor related functions563 // VFS file descriptor related functions 549 564 ////////////////////////////////////////////////////////////////////////////////////////// 550 565 … … 645 660 646 661 ////////////////////////////////////////////////////////////////////////////////////////// 647 // File accessrelated functions662 // "syscalls" API related functions 648 663 ////////////////////////////////////////////////////////////////////////////////////////// 649 664 … … 665 680 uint32_t file_id; // created file descriptor index in reference fd_array 666 681 667 assert( (mode == 0), __FUNCTION__, 668 "the mode parameter is not supported yet\n" ); 682 683 if( mode != 0 ) 684 { 685 printk("\n[ERROR] in %s : the mode parameter is not supported yet\n" ); 686 return -1; 687 } 669 688 670 689 #if DEBUG_VFS_OPEN … … 736 755 uint32_t size ) 737 756 { 738 assert( ( file_xp != XPTR_NULL ) , "file_xp == XPTR_NULL" );739 740 757 cxy_t file_cxy; // remote file descriptor cluster 741 758 vfs_file_t * file_ptr; // remote file descriptor local pointer … … 745 762 error_t error; 746 763 764 // check argument 765 assert( (file_xp != XPTR_NULL), "file_xp == XPTR_NULL\n" ); 766 747 767 // get cluster and local pointer on remote file descriptor 748 768 file_cxy = GET_CXY( file_xp ); … … 752 772 inode_type = hal_remote_l32( XPTR( file_cxy , &file_ptr->type ) ); 753 773 754 assert( (inode_type == INODE_TYPE_FILE) , 755 774 // check inode type 775 assert( (inode_type == INODE_TYPE_FILE), "inode type is not INODE_TYPE_FILE" ); 756 776 757 777 // get mapper pointer and file offset from file descriptor … … 770 790 else 771 791 { 772 rpc_mapper_move_buffer_client( file_cxy, 773 mapper, 774 to_buffer, 775 true, // user buffer 776 file_offset, 777 (uint64_t)(intptr_t)buffer, 778 size, 779 &error ); 792 rpc_mapper_move_user_client( file_cxy, 793 mapper, 794 to_buffer, 795 file_offset, 796 buffer, 797 size, 798 &error ); 780 799 } 781 800 782 if( error ) return -1; 783 else return size; 801 // update file offset in file descriptor 802 hal_remote_atomic_add( XPTR( file_cxy , &file_ptr->offset ) , size ); 803 804 if( error ) 805 { 806 return -1; 807 } 808 809 return size; 784 810 785 811 } // end vfs_user_move() … … 791 817 uint32_t size ) 792 818 { 793 assert( ( file_xp != XPTR_NULL ) , "file_xp == XPTR_NULL" );794 795 819 cxy_t file_cxy; // remote file descriptor cluster 796 820 vfs_file_t * file_ptr; // remote file descriptor local pointer 797 vfs_inode_type_t inode_type; 821 vfs_inode_type_t inode_type; // remote file type 798 822 uint32_t file_offset; // current offset in file 799 mapper_t * mapper; 823 mapper_t * mapper_ptr; // remote mapper local pointer 824 xptr_t mapper_xp; // remote mapper extended pointer 800 825 error_t error; 826 827 // check argument 828 assert( (file_xp != XPTR_NULL) , "file_xp == XPTR_NULL\n" ); 801 829 802 830 // get cluster and local pointer on remote file descriptor … … 810 838 if( inode_type == INODE_TYPE_FILE ) 811 839 { 812 // get mapper pointer and file offset from file descriptor840 // get mapper pointers and file offset from file descriptor 813 841 file_offset = hal_remote_l32( XPTR( file_cxy , &file_ptr->offset ) ); 814 mapper = (mapper_t *)hal_remote_lpt( XPTR( file_cxy , &file_ptr->mapper ) ); 842 mapper_ptr = hal_remote_lpt( XPTR( file_cxy , &file_ptr->mapper ) ); 843 mapper_xp = XPTR( file_cxy , mapper_ptr ); 815 844 816 845 // move data between mapper and buffer 817 if( file_cxy == local_cxy ) 818 { 819 error = mapper_move_kernel( mapper, 820 to_buffer, 821 file_offset, 822 buffer_xp, 823 size ); 824 } 825 else 826 { 827 rpc_mapper_move_buffer_client( file_cxy, 828 mapper, 829 to_buffer, 830 false, // kernel buffer 831 file_offset, 832 buffer_xp, 833 size, 834 &error ); 835 } 836 846 error = mapper_move_kernel( mapper_xp, 847 to_buffer, 848 file_offset, 849 buffer_xp, 850 size ); 837 851 if( error ) return -1; 838 else return 0;839 852 } 840 853 else … … 843 856 return -1; 844 857 } 858 859 return 0; 860 845 861 } // end vfs_kernel_move() 846 862 … … 853 869 xptr_t offset_xp; 854 870 xptr_t lock_xp; 871 xptr_t size_xp; 855 872 cxy_t file_cxy; 856 873 vfs_file_t * file_ptr; … … 858 875 uint32_t new; 859 876 860 assert( (file_xp != XPTR_NULL) , "file_xp == XPTR_NULL" ); 877 // check argument 878 assert( (file_xp != XPTR_NULL) , "file_xp == XPTR_NULL\n" ); 861 879 862 880 // get cluster and local pointer on remote file descriptor … … 864 882 file_ptr = GET_PTR( file_xp ); 865 883 866 // build extended pointers on lock and offset 884 // get local pointer on remote inode 885 inode_ptr = (vfs_inode_t *)hal_remote_lpt( XPTR( file_cxy , &file_ptr->inode ) ); 886 887 // build extended pointers on lock, offset and size 867 888 offset_xp = XPTR( file_cxy , &file_ptr->offset ); 868 889 lock_xp = XPTR( file_cxy , &file_ptr->lock ); 890 size_xp = XPTR( file_cxy , &inode_ptr->size ); 869 891 870 892 // take file descriptor lock … … 881 903 else if ( whence == SEEK_END ) // new = size + offset 882 904 { 883 // get local pointer on remote inode 884 inode_ptr = (vfs_inode_t *)hal_remote_lpt( XPTR( file_cxy , &file_ptr->inode ) ); 885 886 new = hal_remote_l32( XPTR( file_cxy , &inode_ptr->size ) ) + offset; 905 new = hal_remote_l32( size_xp ) + offset; 887 906 } 888 907 else … … 893 912 } 894 913 914 #if DEBUG_VFS_LSEEK 915 uint32_t cycle = (uint32_t)hal_get_cycles(); 916 thread_t * this = CURRENT_THREAD; 917 char name[CONFIG_VFS_MAX_NAME_LENGTH]; 918 vfs_inode_get_name( XPTR( file_cxy , inode_ptr ) , name ); 919 if( cycle > DEBUG_VFS_LSEEK ) 920 printk("\n[%s] thread[%x,%x] for <%s> / new offset %d / cycle %d\n", 921 __FUNCTION__ , this->process->pid, this->trdid, name, new, cycle ); 922 #endif 923 895 924 // set new offset 896 925 hal_remote_s32( offset_xp , new ); … … 900 929 901 930 // success 902 if ( new_offset != NULL ) 903 *new_offset = new; 931 if ( new_offset != NULL ) *new_offset = new; 904 932 return 0; 905 933 … … 922 950 process_t * process_ptr; // process copy local pointer 923 951 924 assert( (file_xp != XPTR_NULL) , "file_xp == XPTR_NULL" ); 925 926 assert( (file_id < CONFIG_PROCESS_FILE_MAX_NR) , "illegal file_id" );952 // check arguments 953 assert( (file_xp != XPTR_NULL) , "file_xp == XPTR_NULL\n" ); 954 assert( (file_id < CONFIG_PROCESS_FILE_MAX_NR) , "illegal file_id\n" ); 927 955 928 956 thread_t * this = CURRENT_THREAD; … … 1019 1047 char * path ) 1020 1048 { 1021 assert( false , "not implemented cwd_xp %x, path <%s> \n", 1022 cwd_xp, path ); 1023 return 0; 1024 } 1049 error_t error; 1050 xptr_t inode_xp; // extended pointer on target inode 1051 cxy_t inode_cxy; // target inode cluster identifier 1052 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 1061 1062 #if DEBUG_VFS_UNLINK 1063 thread_t * this = CURRENT_THREAD; 1064 uint32_t cycle = (uint32_t)hal_get_cycles(); 1065 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 1076 inode_cxy = GET_CXY( inode_xp ); 1077 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 ) 1102 { 1103 printk("\n[ERROR] in %s : cannot update FAT mapper <%s>\n", path ); 1104 return -1; 1105 } 1106 1107 #if(DEBUG_VFS_UNLINK & 1) 1108 if( DEBUG_VFS_UNLINK < cycle ) 1109 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 1116 { 1117 error = vfs_fs_remove_dentry( dentry_parent_ptr, 1118 dentry_ptr ); 1119 } 1120 else // dentry is remote 1121 { 1122 rpc_vfs_fs_remove_dentry_client( dentry_cxy, 1123 dentry_parent_ptr, 1124 dentry_ptr, 1125 &error ); 1126 } 1127 if( error ) 1128 { 1129 printk("\n[ERROR] in %s : cannot update dentry on device for <%s>\n", path ); 1130 return -1; 1131 } 1132 1133 #if(DEBUG_VFS_UNLINK & 1) 1134 if( DEBUG_VFS_UNLINK < cycle ) 1135 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 ); 1140 1141 #if DEBUG_VFS_UNLINK 1142 if( DEBUG_VFS_UNLINK < cycle ) 1143 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 ); 1145 #endif 1146 return 0; 1147 } 1148 ///////////////////////////////// 1149 else if( type == INODE_TYPE_DIR ) 1150 { 1151 printk("\n[ERROR] in %s : unsupported type %s\n", vfs_inode_type_str( type ) ); 1152 return -1; 1153 } 1154 //// 1155 else 1156 { 1157 printk("\n[ERROR] in %s : unsupported type %s\n", vfs_inode_type_str( type ) ); 1158 return -1; 1159 } 1160 1161 } // end vfs_unlink() 1025 1162 1026 1163 ////////////////////////////////////// … … 1058 1195 1059 1196 return 0; 1060 } 1197 1198 } // end vfs_stat() 1061 1199 1062 1200 ///////////////////////////////////////////// … … 1172 1310 1173 1311 ////////////////////////////////////////////////////////////////////////////////////////// 1174 // Inode Treefunctions1312 // Distributed Inode Tree access related functions 1175 1313 ////////////////////////////////////////////////////////////////////////////////////////// 1176 1314 … … 1336 1474 } // end vfs_display() 1337 1475 1476 /* 1338 1477 ////////////////////////////////////////////////////////////////////////////////////////// 1339 // This function is used by the vfs_lookup() function.1478 // This static function is used by the vfs_lookup() function. 1340 1479 // It takes an extended pointer on a remote inode (parent directory inode), 1341 1480 // and check access_rights violation for the calling thread. … … 1347 1486 // @ return true if access rights are violated. 1348 1487 ////////////////////////////////////////////////////////////////////////////////////////// 1349 bool_t vfs_access_denied( xptr_t inode_xp,1488 static bool_t vfs_access_denied( xptr_t inode_xp, 1350 1489 uint32_t client_uid, 1351 1490 uint32_t client_gid ) … … 1364 1503 else return true; 1365 1504 } 1505 */ 1366 1506 1367 1507 ////////////////////////////////////////////////////////////////////////////////////////// … … 1465 1605 cxy_t parent_cxy; // cluster for parent inode 1466 1606 vfs_inode_t * parent_ptr; // local pointer on parent inode 1607 xptr_t dentry_xp; // extended pointer on dentry 1467 1608 xptr_t child_xp; // extended pointer on child inode 1468 1609 cxy_t child_cxy; // cluster for child inode 1469 vfs_inode_t * child_ptr; // local pointer on child inode 1610 vfs_inode_t * child_ptr; // local pointer on child inode 1611 vfs_inode_type_t child_type; // child inode type 1470 1612 vfs_fs_type_t fs_type; // File system type 1471 1613 vfs_ctx_t * ctx_ptr; // local pointer on FS context … … 1519 1661 #if (DEBUG_VFS_LOOKUP & 1) 1520 1662 if( DEBUG_VFS_LOOKUP < cycle ) 1521 printk("\n[%s] look for<%s> / last = %d\n",1522 __FUNCTION__ , name, last );1663 printk("\n[%s] thread[%x,%x] look for <%s> in <%s> / last = %d\n", 1664 __FUNCTION__, process->pid, this->trdid, name, pathname, last ); 1523 1665 #endif 1524 1666 … … 1533 1675 #if (DEBUG_VFS_LOOKUP & 1) 1534 1676 if( DEBUG_VFS_LOOKUP < cycle ) 1535 printk("\n[%s] miss <%s> node => try to create it\n",1536 __FUNCTION__ 1677 printk("\n[%s] thread[%x,%x] miss <%s> node => try to create it\n", 1678 __FUNCTION__, process->pid, this->trdid, name ); 1537 1679 #endif 1538 1680 // if a child node is not found in the inode tree, … … 1544 1686 // . if it is not found in the parent mapper: 1545 1687 // - if ( not last or not create ) an error is reported 1546 // - if (last and create and dir) a new directory is created 1547 // - if (last and create and not dir) a new file is created 1688 // - if (last and create) a new file or directory is created 1548 1689 1549 1690 // release lock on parent inode 1550 1691 vfs_inode_unlock( parent_xp ); 1551 1692 1552 // get parent inode FS type1693 // get parent inode cluster and local pointer 1553 1694 parent_cxy = GET_CXY( parent_xp ); 1554 1695 parent_ptr = GET_PTR( parent_xp ); 1555 ctx_ptr = (vfs_ctx_t *)hal_remote_lpt( XPTR( parent_cxy,&parent_ptr->ctx ) ); 1696 1697 // get parent inode FS type 1698 ctx_ptr = hal_remote_lpt( XPTR( parent_cxy,&parent_ptr->ctx ) ); 1556 1699 fs_type = hal_remote_l32( XPTR( parent_cxy , &ctx_ptr->type ) ); 1557 1700 1558 1701 // select a cluster for missing inode 1559 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; 1560 1707 1561 1708 // insert a new child dentry/inode in inode tree 1562 1709 error = vfs_add_child_in_parent( child_cxy, 1563 0, // type will be updated later1710 child_type, 1564 1711 fs_type, 1565 1712 parent_xp, 1566 1713 name, 1567 NULL, // fs_type_specific inode extend1714 &dentry_xp, 1568 1715 &child_xp ); 1569 1716 if( error ) 1570 1717 { 1571 printk("\n[ERROR] in %s : cannot create node %s forpath <%s>\n",1718 printk("\n[ERROR] in %s : cannot create node <%s> in path <%s>\n", 1572 1719 __FUNCTION__ , name, pathname ); 1573 return ENOMEM;1720 return -1; 1574 1721 } 1575 1722 1576 // get child inode cluster and local pointer 1577 child_cxy = GET_CXY( child_xp ); 1723 // get child inode local pointer 1578 1724 child_ptr = GET_PTR( child_xp ); 1579 1725 1580 1726 #if (DEBUG_VFS_LOOKUP & 1) 1581 1727 if( DEBUG_VFS_LOOKUP < cycle ) 1582 printk("\n[%s] missing <%s> inode speculatively created / cxy %x / ptr %x\n", 1583 __FUNCTION__ , name , child_cxy, child_ptr ); 1584 #endif 1585 // scan parent mapper to complete the missing inode 1728 printk("\n[%s] thread[%x,%x] created missing inode <%s> in cluster %x\n", 1729 __FUNCTION__, process->pid, this->trdid, name, child_cxy ); 1730 #endif 1731 // scan parent mapper to find the missing dentry, and complete 1732 // the initialisation of dentry and child inode desciptors 1586 1733 if( parent_cxy == local_cxy ) 1734 1587 1735 { 1588 error = vfs_ inode_load( parent_ptr,1589 name,1590 child_xp );1736 error = vfs_fs_child_init( parent_ptr, 1737 name, 1738 child_xp ); 1591 1739 } 1592 1740 else 1593 1741 { 1594 rpc_vfs_ inode_load_client( parent_cxy,1595 parent_ptr,1596 name,1597 child_xp,1598 &error );1742 rpc_vfs_fs_child_init_client( parent_cxy, 1743 parent_ptr, 1744 name, 1745 child_xp, 1746 &error ); 1599 1747 } 1600 1748 1601 1749 if ( error ) // child not found in parent mapper 1602 1750 { 1603 if ( last && create && dir ) // new directory => update inode type1751 if ( last && create ) // add a new dentry in parent 1604 1752 { 1605 hal_remote_s32( XPTR( child_cxy, &child_ptr->type ), INODE_TYPE_DIR ); 1753 error = vfs_new_child_init( parent_xp, 1754 dentry_xp, 1755 child_xp ); 1756 if ( error ) 1757 { 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 ); 1761 return -1; 1762 } 1606 1763 1607 1764 #if (DEBUG_VFS_LOOKUP & 1) 1608 1765 if( DEBUG_VFS_LOOKUP < cycle ) 1609 printk("\n[%s] created node <%s> in path %s / type DIR\n",1610 __FUNCTION__ , name, pathname );1766 printk("\n[%s] thread[%x,%x] created inode <%s> in path\n", 1767 __FUNCTION__, process->pid, this->trdid, name ); 1611 1768 #endif 1612 1769 } 1613 else if ( last && create ) // new file => update inode type 1614 { 1615 hal_remote_s32( XPTR( child_cxy, &child_ptr->type ), INODE_TYPE_FILE ); 1616 1617 #if (DEBUG_VFS_LOOKUP & 1) 1618 if( DEBUG_VFS_LOOKUP < cycle ) 1619 printk("\n[%s] created node <%s> in path %s / type FILE\n", 1620 __FUNCTION__ , name, pathname ); 1621 #endif 1622 } 1623 else // not last or not create => remove created node 1770 else // not last or not create => error 1624 1771 { 1625 1772 printk("\n[ERROR] in %s : <%s> node not found in parent for <%s>\n", … … 1629 1776 } 1630 1777 } 1631 else // child found in parent 1778 else // child found in parent mapper 1632 1779 { 1633 1780 // load child mapper from device if child is a directory (prefetch) … … 1636 1783 if( child_cxy == local_cxy ) 1637 1784 { 1638 error = vfs_ mapper_load_all( child_ptr );1785 error = vfs_inode_load_all_pages( child_ptr ); 1639 1786 } 1640 1787 else 1641 1788 { 1642 rpc_vfs_ mapper_load_all_client( child_cxy,1643 child_ptr,1644 &error );1789 rpc_vfs_inode_load_all_pages_client( child_cxy, 1790 child_ptr, 1791 &error ); 1645 1792 } 1646 1793 if ( error ) … … 1654 1801 #if (DEBUG_VFS_LOOKUP & 1) 1655 1802 if( DEBUG_VFS_LOOKUP < cycle ) 1656 printk("\n[%s] load mapper from device for node <%s> in path %s\n",1657 __FUNCTION__ , name, pathname );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 ); 1658 1805 #endif 1659 1806 } … … 1668 1815 #if (DEBUG_VFS_LOOKUP & 1) 1669 1816 if( DEBUG_VFS_LOOKUP < cycle ) 1670 printk("\n[%s] found <%s> / inode %x in cluster %x\n",1671 __FUNCTION__ , name , GET_PTR(child_xp), GET_CXY(child_xp) );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) ); 1672 1819 #endif 1673 1820 child_ptr = GET_PTR( child_xp ); … … 1710 1857 cycle = (uint32_t)hal_get_cycles(); 1711 1858 if( DEBUG_VFS_LOOKUP < cycle ) 1712 printk("\n[%s] thread[%x,%x] exit for <%s>\n" 1713 " parent %x in cluster %x / child %x in cluster %x / cycle %d\n", 1714 __FUNCTION__ , process->pid, this->trdid, pathname, 1715 parent_ptr, parent_cxy, child_ptr, child_cxy, cycle ); 1859 printk("\n[%s] thread[%x,%x] exit for <%s> cycle %d\n", 1860 __FUNCTION__ , process->pid, this->trdid, pathname, cycle ); 1716 1861 #endif 1717 1862 … … 1723 1868 1724 1869 } // end vfs_lookup() 1870 1871 1872 1873 /////////////////////////////////////////////// 1874 error_t vfs_new_child_init( xptr_t parent_xp, 1875 xptr_t dentry_xp, 1876 xptr_t child_xp ) 1877 { 1878 error_t error; 1879 uint32_t cluster; 1880 uint32_t child_type; 1881 uint32_t child_size; 1882 1883 #if DEBUG_VFS_NEW_CHILD_INIT 1884 char parent_name[CONFIG_VFS_MAX_NAME_LENGTH]; 1885 char child_name[CONFIG_VFS_MAX_NAME_LENGTH]; 1886 vfs_inode_get_name( parent_xp , parent_name ); 1887 vfs_inode_get_name( child_xp , child_name ); 1888 uint32_t cycle = (uint32_t)hal_get_cycles(); 1889 thread_t * this = CURRENT_THREAD; 1890 if( DEBUG_VFS_NEW_CHILD_INIT < cycle ) 1891 printk("\n[%s] thread[%x,%x] enter / parent <%s> / child <%s> / cycle %d\n", 1892 __FUNCTION__ , this->process->pid, this->trdid, parent_name, child_name, cycle ); 1893 #endif 1894 1895 // get parent inode cluster and local pointer 1896 cxy_t parent_cxy = GET_CXY( parent_xp ); 1897 vfs_inode_t * parent_ptr = GET_PTR( parent_xp ); 1898 1899 // get dentry local pointer 1900 vfs_dentry_t * dentry_ptr = GET_PTR( dentry_xp ); 1901 1902 // get child inode cluster and local pointer 1903 cxy_t child_cxy = GET_CXY( child_xp ); 1904 vfs_inode_t * child_ptr = GET_PTR( child_xp ); 1905 1906 // 1. allocate one free cluster to child inode 1907 // depending on the child inode FS type 1908 vfs_ctx_t * ctx = hal_remote_lpt( XPTR( child_cxy , &child_ptr->ctx ) ); 1909 1910 error = vfs_fs_cluster_alloc( ctx->type, 1911 &cluster ); 1912 if ( error ) 1913 { 1914 printk("\n[ERROR] in %s : cannot find a free VFS cluster\n", 1915 __FUNCTION__ ); 1916 return -1; 1917 } 1918 1919 #if( DEBUG_VFS_NEW_CHILD_INIT & 1) 1920 if( DEBUG_VFS_NEW_CHILD_INIT < cycle ) 1921 printk("\n[%s] thread[%x,%x] allocated one FAT cluster to <%s>\n", 1922 __FUNCTION__ , this->process->pid, this->trdid, child_name ); 1923 #endif 1924 1925 // 2. update the child inode descriptor 1926 child_type = hal_remote_l32( XPTR( child_cxy , &child_ptr->type ) ); 1927 child_size = (child_type == INODE_TYPE_DIR) ? 4096 : 0; 1928 1929 hal_remote_s32( XPTR( child_cxy , &child_ptr->size ) , child_size ); 1930 hal_remote_spt( XPTR( child_cxy , &child_ptr->extend ) , (void*)(intptr_t)cluster ); 1931 1932 // 3. update the parent inode mapper, and 1933 // update the dentry extension if required 1934 if( local_cxy == parent_cxy ) 1935 { 1936 error = vfs_fs_add_dentry( parent_ptr, 1937 dentry_ptr ); 1938 } 1939 else 1940 { 1941 rpc_vfs_fs_add_dentry_client( parent_cxy, 1942 parent_ptr, 1943 dentry_ptr, 1944 &error ); 1945 } 1946 if ( error ) 1947 { 1948 printk("\n[ERROR] in %s : cannot register child in parent directory\n", 1949 __FUNCTION__ ); 1950 return -1; 1951 } 1952 1953 #if DEBUG_VFS_NEW_CHILD_INIT 1954 cycle = (uint32_t)hal_get_cycles(); 1955 if( DEBUG_VFS_NEW_CHILD_INIT < cycle ) 1956 printk("\n[%s] thread[%x,%x] exit / parent <%s> / child <%> / cycle %d\n", 1957 __FUNCTION__ , this->process->pid, this->trdid, parent_name, child_name, cycle ); 1958 #endif 1959 1960 return 0; 1961 1962 } // end vfs_new_child_init() 1725 1963 1726 1964 //////////////////////////////////////////// … … 1794 2032 1795 2033 1796 ////////////////////////////////////////////////////////////// 1797 error_t vfs_add_child_in_parent( cxy_t child_ cxy,1798 vfs_inode_type_t inode_type,2034 //////////////////////////////////////////////////////////////////// 2035 error_t vfs_add_child_in_parent( cxy_t child_inode_cxy, 2036 vfs_inode_type_t child_inode_type, 1799 2037 vfs_fs_type_t fs_type, 1800 xptr_t parent_ xp,2038 xptr_t parent_inode_xp, 1801 2039 char * name, 1802 void * extend,1803 xptr_t * child_ xp )2040 xptr_t * dentry_xp, 2041 xptr_t * child_inode_xp ) 1804 2042 { 1805 2043 error_t error; 1806 xptr_t dentry_xp; // extended pointer on created dentry 1807 xptr_t inode_xp; // extended pointer on created inode 1808 cxy_t parent_cxy; // parent inode cluster identifier 1809 vfs_inode_t * parent_ptr; // parent inode local pointer 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 1810 2049 1811 2050 // get parent inode cluster and local pointer 1812 parent_ cxy = GET_CXY( parent_xp );1813 parent_ ptr = GET_PTR( parent_xp );2051 parent_inode_cxy = GET_CXY( parent_inode_xp ); 2052 parent_inode_ptr = GET_PTR( parent_inode_xp ); 1814 2053 1815 2054 #if DEBUG_VFS_ADD_CHILD 2055 char parent_name[CONFIG_VFS_MAX_NAME_LENGTH]; 2056 vfs_inode_get_name( parent_inode_xp , parent_name ); 1816 2057 uint32_t cycle = (uint32_t)hal_get_cycles(); 1817 2058 thread_t * this = CURRENT_THREAD; 1818 2059 if( DEBUG_VFS_ADD_CHILD < cycle ) 1819 printk("\n[%s] thread[%x,%x] enter for <%s> / child_cxy %x / parent_cxy %x / cycle %d\n",1820 __FUNCTION__, this->process->pid, this->trdid, name, 1821 child_cxy, parent_cxy, (uint32_t)hal_get_cycles() );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() ); 1822 2063 #endif 1823 2064 1824 2065 // 1. create dentry 1825 if( parent_ cxy == local_cxy ) // parent cluster is the local cluster2066 if( parent_inode_cxy == local_cxy ) // parent cluster is the local cluster 1826 2067 { 1827 2068 error = vfs_dentry_create( fs_type, 1828 2069 name, 1829 parent_ ptr,1830 & dentry_xp );2070 parent_inode_ptr, 2071 &new_dentry_xp ); 1831 2072 } 1832 2073 else // parent cluster is remote 1833 2074 { 1834 rpc_vfs_dentry_create_client( parent_ cxy,2075 rpc_vfs_dentry_create_client( parent_inode_cxy, 1835 2076 fs_type, 1836 2077 name, 1837 parent_ ptr,1838 & dentry_xp,2078 parent_inode_ptr, 2079 &new_dentry_xp, 1839 2080 &error ); 1840 2081 } … … 1843 2084 { 1844 2085 printk("\n[ERROR] in %s : cannot create dentry <%s> in cluster %x\n", 1845 __FUNCTION__ , name , parent_cxy ); 1846 return ENOMEM; 1847 } 2086 __FUNCTION__ , name , parent_inode_cxy ); 2087 return -1; 2088 } 2089 2090 // get dentry local pointer 2091 new_dentry_ptr = GET_PTR( new_dentry_xp ); 1848 2092 1849 2093 #if(DEBUG_VFS_ADD_CHILD & 1) 1850 2094 if( DEBUG_VFS_ADD_CHILD < cycle ) 1851 2095 printk("\n[%s] thread[%x,%x] / dentry <%s> created in cluster %x\n", 1852 __FUNCTION__, this->process->pid, this->trdid, name, parent_ cxy );2096 __FUNCTION__, this->process->pid, this->trdid, name, parent_inode_cxy ); 1853 2097 #endif 1854 2098 … … 1859 2103 uint32_t gid = 0; 1860 2104 1861 if( child_ cxy == local_cxy ) // child cluster is the local cluster1862 { 1863 error = vfs_inode_create( dentry_xp,2105 if( child_inode_cxy == local_cxy ) // child cluster is the local cluster 2106 { 2107 error = vfs_inode_create( new_dentry_xp, 1864 2108 fs_type, 1865 inode_type, 1866 extend, 2109 child_inode_type, 1867 2110 attr, 1868 2111 mode, 1869 2112 uid, 1870 2113 gid, 1871 & inode_xp );2114 &new_inode_xp ); 1872 2115 } 1873 2116 else // child cluster is remote 1874 2117 { 1875 rpc_vfs_inode_create_client( child_ cxy,1876 dentry_xp,2118 rpc_vfs_inode_create_client( child_inode_cxy, 2119 new_dentry_xp, 1877 2120 fs_type, 1878 inode_type, 1879 extend, 2121 child_inode_type, 1880 2122 attr, 1881 2123 mode, 1882 2124 uid, 1883 2125 gid, 1884 & inode_xp,2126 &new_inode_xp, 1885 2127 &error ); 1886 2128 } … … 1889 2131 { 1890 2132 printk("\n[ERROR] in %s : cannot create inode in cluster %x\n", 1891 __FUNCTION__ , child_ cxy );2133 __FUNCTION__ , child_inode_cxy ); 1892 2134 1893 vfs_dentry_t * dentry = GET_PTR( dentry_xp ); 1894 if( parent_cxy == local_cxy ) vfs_dentry_destroy( dentry ); 1895 else rpc_vfs_dentry_destroy_client( parent_cxy , dentry , &error ); 1896 return ENOMEM; 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 ); 2137 return -1; 1897 2138 } 1898 2139 … … 1900 2141 if( DEBUG_VFS_ADD_CHILD < cycle ) 1901 2142 printk("\n[%s] thread[%x,%x] / inode <%s> created in cluster %x\n", 1902 __FUNCTION__ , this->process->pid, this->trdid, name , child_ cxy );1903 #endif 1904 1905 // 3. update extended pointer on inode in dentry1906 cxy_t dentry_cxy = GET_CXY( dentry_xp );1907 vfs_ dentry_t * dentry_ptr = GET_PTR( dentry_xp );1908 hal_remote_s64( XPTR( dentry_cxy , &dentry_ptr->child_xp ) , inode_xp );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 ); 1909 2150 1910 2151 #if DEBUG_VFS_ADD_CHILD … … 1915 2156 #endif 1916 2157 1917 // success : return extended pointer on child inode 1918 *child_xp = inode_xp; 2158 // return extended pointer on dentry & child inode 2159 *dentry_xp = new_dentry_xp; 2160 *child_inode_xp = new_inode_xp; 1919 2161 return 0; 1920 2162 1921 // FIXME update the refcount fields in both inode and dentry1922 1923 2163 } // end vfs_add_child_in_parent() 1924 2164 1925 //////////////////////////////////////////////////// ///1926 error_tvfs_remove_child_from_parent( xptr_t inode_xp )2165 //////////////////////////////////////////////////// 2166 void vfs_remove_child_from_parent( xptr_t inode_xp ) 1927 2167 { 1928 2168 cxy_t inode_cxy; … … 1931 2171 cxy_t dentry_cxy; 1932 2172 vfs_dentry_t * dentry_ptr; 1933 error_t error;1934 2173 1935 2174 // get inode cluster and local pointer … … 1937 2176 inode_ptr = GET_PTR( inode_xp ); 1938 2177 1939 // get cluster and pointers of associated dentry2178 // get associated dentry cluster and pointers 1940 2179 dentry_xp = hal_remote_l64( XPTR( inode_cxy , &inode_ptr->parent_xp ) ); 1941 2180 dentry_cxy = GET_CXY( dentry_xp ); 1942 2181 dentry_ptr = GET_PTR( dentry_xp ); 1943 2182 1944 // FIXME update the refcount fields in both inode and dentry 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 ); 1945 2194 1946 2195 // delete dentry 1947 2196 if( dentry_cxy == local_cxy ) 1948 2197 { 1949 error =vfs_dentry_destroy( dentry_ptr );2198 vfs_dentry_destroy( dentry_ptr ); 1950 2199 } 1951 2200 else 1952 2201 { 1953 2202 rpc_vfs_dentry_destroy_client( dentry_cxy, 1954 dentry_ptr, 1955 &error ); 1956 } 1957 if( error ) return EINVAL; 2203 dentry_ptr ); 2204 } 1958 2205 1959 2206 // delete inode … … 1965 2212 { 1966 2213 rpc_vfs_inode_destroy_client( inode_cxy, 1967 inode_ptr, 1968 &error ); 1969 } 1970 if( error ) return EINVAL; 1971 1972 return 0; 2214 inode_ptr ); 2215 } 1973 2216 1974 2217 } // end vfs_remove_child_from_parent() 1975 2218 1976 2219 ////////////////////////////////////////////////////////////////////////////////////////// 1977 // Mapper related functions2220 // API used by VFS to access a specific FS 1978 2221 ////////////////////////////////////////////////////////////////////////////////////////// 1979 2222 1980 /////////////////////////////////////////// /1981 error_t vfs_ mapper_move_page( page_t * page,1982 2223 /////////////////////////////////////////// 2224 error_t vfs_fs_move_page( xptr_t page_xp, 2225 bool_t to_mapper ) 1983 2226 { 1984 2227 error_t error = 0; 1985 2228 1986 assert( (page != NULL) , "page pointer is NULL\n" ); 1987 1988 mapper_t * mapper = page->mapper; 1989 1990 assert( (mapper != NULL) , "no mapper for page\n" ); 1991 1992 #if DEBUG_VFS_MAPPER_MOVE 1993 uint32_t cycle = (uint32_t)hal_get_cycles(); 1994 thread_t * this = CURRENT_THREAD; 1995 if( DEBUG_VFS_MAPPER_MOVE < cycle ) 1996 printk("\n[%s] thread[%x,%x] enter for page %d / mapper %x / inode %x / cycle %d\n", 1997 __FUNCTION__, this->process->pid, this->trdid, page->index, mapper, mapper->inode, cycle ); 1998 #endif 2229 assert( (page_xp != XPTR_NULL) , "page pointer is NULL\n" ); 2230 2231 page_t * page_ptr = GET_PTR( page_xp ); 2232 cxy_t page_cxy = GET_CXY( page_xp ); 2233 2234 // get local pointer on page mapper 2235 mapper_t * mapper = hal_remote_lpt( XPTR( page_cxy , &page_ptr->mapper ) ); 2236 2237 assert( (mapper != NULL) , "no mapper for page\n" ); 2238 2239 // get FS type 2240 vfs_fs_type_t fs_type = hal_remote_l32( XPTR( page_cxy , &mapper->type ) ); 2241 2242 // call relevant FS function 2243 if( fs_type == FS_TYPE_FATFS ) 2244 { 2245 error = fatfs_move_page( page_xp , to_mapper ); 2246 } 2247 else if( fs_type == FS_TYPE_RAMFS ) 2248 { 2249 assert( false , "should not be called for RAMFS\n" ); 2250 } 2251 else if( fs_type == FS_TYPE_DEVFS ) 2252 { 2253 assert( false , "should not be called for DEVFS\n" ); 2254 } 2255 else 2256 { 2257 assert( false , "undefined file system type\n" ); 2258 } 2259 2260 return error; 2261 2262 } // end vfs_fs_move_page() 2263 2264 //////////////////////////////////////////////// 2265 error_t vfs_fs_add_dentry( vfs_inode_t * inode, 2266 vfs_dentry_t * dentry ) 2267 { 2268 error_t error = 0; 2269 2270 assert( (inode != NULL) , "inode pointer is NULL\n" ); 2271 assert( (dentry != NULL) , "dentry pointer is NULL\n" ); 2272 2273 mapper_t * mapper = inode->mapper; 2274 2275 assert( (mapper != NULL) , "mapper pointer is NULL\n" ); 1999 2276 2000 2277 // get FS type … … 2004 2281 if( fs_type == FS_TYPE_FATFS ) 2005 2282 { 2006 // enter mapper in write mode 2007 rwlock_wr_acquire( &mapper->lock ); 2008 2009 // move page to mapper 2010 error = fatfs_mapper_move_page( page , to_mapper ); 2011 2012 // exit mapper in write mode 2013 rwlock_wr_release( &mapper->lock ); 2283 error = fatfs_add_dentry( inode , dentry ); 2014 2284 } 2015 2285 else if( fs_type == FS_TYPE_RAMFS ) … … 2026 2296 } 2027 2297 2028 #if DEBUG_VFS_MAPPER_MOVE2029 cycle = (uint32_t)hal_get_cycles();2030 if( DEBUG_VFS_MAPPER_MOVE < cycle )2031 printk("\n[%s] thread[%x,%x] exit for page %d / mapper %x / inode %x / cycle %d\n",2032 __FUNCTION__, this->process->pid, this->trdid, page->index, mapper, mapper->inode, cycle );2033 #endif2034 2035 2298 return error; 2036 2299 2037 } // end vfs_move_page() 2038 2039 ////////////////////////////////////////////////// 2040 error_t vfs_mapper_load_all( vfs_inode_t * inode ) 2041 { 2042 assert( (inode != NULL) , "inode pointer is NULL\n" ); 2043 2044 uint32_t index; 2045 page_t * page; 2300 } // end vfs_fs_add_dentry() 2301 2302 /////////////////////////////////////////////////// 2303 error_t vfs_fs_remove_dentry( vfs_inode_t * inode, 2304 vfs_dentry_t * dentry ) 2305 { 2306 error_t error = 0; 2307 2308 assert( (inode != NULL) , "inode pointer is NULL\n" ); 2309 assert( (dentry != NULL) , "dentry pointer is NULL\n" ); 2046 2310 2047 2311 mapper_t * mapper = inode->mapper; 2048 uint32_t size = inode->size;2049 2312 2050 2313 assert( (mapper != NULL) , "mapper pointer is NULL\n" ); 2051 2314 2052 #if DEBUG_VFS_MAPPER_LOAD 2053 uint32_t cycle = (uint32_t)hal_get_cycles(); 2054 thread_t * this = CURRENT_THREAD; 2055 if( DEBUG_VFS_MAPPER_MOVE < cycle ) 2056 printk("\n[%s] thread[%x,%x] enter for inode %x in cluster %x / cycle %d\n", 2057 __FUNCTION__, this->process->pid, this->trdid, inode, local_cxy, cycle ); 2058 #endif 2059 2060 // compute number of pages 2061 uint32_t npages = size >> CONFIG_PPM_PAGE_SHIFT; 2062 if( (size & CONFIG_PPM_PAGE_MASK) || (size == 0) ) npages++; 2063 2064 // loop on pages 2065 for( index = 0 ; index < npages ; index ++ ) 2066 { 2067 // this function allocates the missing page in mapper, 2068 // and call the vfs_mapper_move_page() to load the page from device 2069 page = mapper_get_page( mapper , index ); 2070 2071 if( page == NULL ) return EIO; 2072 } 2073 2074 #if DEBUG_VFS_MAPPER_LOAD 2075 cycle = (uint32_t)hal_get_cycles(); 2076 if( DEBUG_VFS_MAPPER_MOVE < cycle ) 2077 printk("\n[%s] thread[%x,%x] exit for inode %x in cluster %x / cycle %d\n", 2078 __FUNCTION__, this->process->pid, this->trdid, inode, local_cxy, cycle ); 2079 #endif 2080 2081 return 0; 2082 2083 } // end vfs_mapper_load_all() 2084 2315 // get FS type 2316 vfs_fs_type_t fs_type = mapper->type; 2317 2318 // call relevant FS function 2319 if( fs_type == FS_TYPE_FATFS ) 2320 { 2321 error = fatfs_remove_dentry( inode , dentry ); 2322 } 2323 else if( fs_type == FS_TYPE_RAMFS ) 2324 { 2325 assert( false , "should not be called for RAMFS\n" ); 2326 } 2327 else if( fs_type == FS_TYPE_DEVFS ) 2328 { 2329 assert( false , "should not be called for DEVFS\n" ); 2330 } 2331 else 2332 { 2333 assert( false , "undefined file system type\n" ); 2334 } 2335 2336 return error; 2337 2338 } // end vfs_fs_remove_dentry() 2339 2340 //////////////////////////////////////////////// 2341 error_t vfs_fs_child_init( vfs_inode_t * parent, 2342 char * name, 2343 xptr_t child_xp ) 2344 { 2345 error_t error = 0; 2346 2347 // check arguments 2348 assert( (parent != NULL) , "parent pointer is NULL\n"); 2349 assert( (child_xp != XPTR_NULL) , "child pointer is NULL\n"); 2350 2351 // get parent inode FS type 2352 vfs_fs_type_t fs_type = parent->ctx->type; 2353 2354 // call relevant FS function 2355 if( fs_type == FS_TYPE_FATFS ) 2356 { 2357 error = fatfs_child_init( parent , name , child_xp ); 2358 } 2359 else if( fs_type == FS_TYPE_RAMFS ) 2360 { 2361 assert( false , "should not be called for RAMFS\n" ); 2362 } 2363 else if( fs_type == FS_TYPE_DEVFS ) 2364 { 2365 assert( false , "should not be called for DEVFS\n" ); 2366 } 2367 else 2368 { 2369 assert( false , "undefined file system type\n" ); 2370 } 2371 2372 return error; 2373 2374 } // end vfs_fs_child_init() 2375 2376 ///////////////////////////////////////////////// 2377 error_t vfs_fs_cluster_alloc( uint32_t fs_type, 2378 uint32_t * cluster ) 2379 { 2380 error_t error = 0; 2381 2382 // call relevant FS function 2383 if( fs_type == FS_TYPE_FATFS ) 2384 { 2385 error = fatfs_cluster_alloc( cluster ); 2386 } 2387 else if( fs_type == FS_TYPE_RAMFS ) 2388 { 2389 assert( false , "should not be called for RAMFS\n" ); 2390 } 2391 else if( fs_type == FS_TYPE_DEVFS ) 2392 { 2393 assert( false , "should not be called for DEVFS\n" ); 2394 } 2395 else 2396 { 2397 assert( false , "undefined file system type\n" ); 2398 } 2399 2400 return error; 2401 2402 } // end vfs_fs_alloc_cluster() 2403 2404 //////////////////////////////////////////////// 2405 error_t vfs_fs_release_inode( xptr_t inode_xp ) 2406 { 2407 error_t error = 0; 2408 2409 assert( (inode_xp != XPTR_NULL) , "inode pointer is NULL\n") 2410 2411 vfs_inode_t * inode_ptr = GET_PTR( inode_xp ); 2412 cxy_t inode_cxy = GET_CXY( inode_xp ); 2413 2414 // get local pointer on page mapper 2415 mapper_t * mapper = hal_remote_lpt( XPTR( inode_cxy , &inode_ptr->mapper ) ); 2416 2417 assert( (mapper != NULL) , "mapper pointer is NULL\n") 2418 2419 // get FS type from mapper 2420 vfs_fs_type_t fs_type = hal_remote_l32( XPTR( inode_cxy , &mapper->type ) ); 2421 2422 // call relevant FS function 2423 if( fs_type == FS_TYPE_FATFS ) 2424 { 2425 error = fatfs_release_inode( inode_xp ); 2426 } 2427 else if( fs_type == FS_TYPE_RAMFS ) 2428 { 2429 assert( false , "should not be called for RAMFS\n" ); 2430 } 2431 else if( fs_type == FS_TYPE_DEVFS ) 2432 { 2433 assert( false , "should not be called for DEVFS\n" ); 2434 } 2435 else 2436 { 2437 assert( false , "undefined file system type\n" ); 2438 } 2439 2440 return error; 2441 2442 } // end vfs_fs_release_inode() 2443 2444
Note: See TracChangeset
for help on using the changeset viewer.