Changeset 626 for trunk/kernel/fs
- Timestamp:
- Apr 29, 2019, 7:25:09 PM (6 years ago)
- Location:
- trunk/kernel/fs
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/kernel/fs/fatfs.c
r625 r626 37 37 #include <fatfs.h> 38 38 39 #define LITTLE_ENDIAN 1 39 40 40 41 ////////////////////////////////////////////////////////////////////////////////////////// … … 72 73 73 74 ////////////////////////////////////////////////////////////////////////////////////////// 74 // This function return an integer record value (one, two, or four bytes) 75 // from a memory buffer, taking into account endianness.76 // ////////////////////////////////////////////////////////////////////////////////////////77 // @ offset : first byte of record in buffer.78 // @ size : record length in bytes (1/2/4).79 // @ buffer : pointer on buffer base.80 // @ little endian : the most significant byte has the highest address when true.75 // This function return an integer record value (one, two, or four bytes) from a local 76 // array of bytes, taking into account the global LITTLE_ENDIAN parameter: 77 // if LITTLE_ENDIAN is true, the most significant byte has the highest address. 78 ////////////////////////////////////////////////////////////////////////////////////////// 79 // @ offset : first byte in array. 80 // @ nbytes : record length in bytes (1/2/4). 81 // @ buffer : local pointer on byte array. 81 82 // @ return the integer value in a 32 bits word. 82 83 ////////////////////////////////////////////////////////////////////////////////////////// 83 84 static uint32_t fatfs_get_record( uint32_t offset, 84 uint32_t size, 85 uint8_t * buffer, 86 uint32_t little_endian ) 87 { 88 uint32_t n; 89 uint32_t res = 0; 90 91 if ( little_endian ) 92 { 93 for( n = size ; n > 0 ; n-- ) res = (res<<8) | buffer[offset+n-1]; 94 } 95 else // big_endian 96 { 97 for( n = 0 ; n < size ; n++ ) res = (res<<8) | buffer[offset+n]; 85 uint32_t nbytes, 86 uint8_t * buffer ) 87 { 88 uint32_t i; 89 uint32_t res = 0; 90 91 if ( LITTLE_ENDIAN ) 92 { 93 for( i = nbytes ; i > 0 ; i-- ) res = (res<<8) | buffer[offset+i-1]; 94 } 95 else 96 { 97 for( i = 0 ; i < nbytes ; i++ ) res = (res<<8) | buffer[offset+i]; 98 98 } 99 99 return res; … … 102 102 103 103 ////////////////////////////////////////////////////////////////////////////////////////// 104 // This function writes one, two, or four bytes from a 32 bits integer to a memory buffer,105 // taking into account endianness.106 // ////////////////////////////////////////////////////////////////////////////////////////107 // @ offset : first byte of record in buffer.108 // @ size : record length in bytes (1/2/4).109 // @ buffer : pointer on buffer base.110 // @ little endian : the most significant byte has the highest address when true.104 // This function return an integer record value (one, two, or four bytes) from a remote 105 // array of bytes, taking into account the global LITTLE_ENDIAN parameter: 106 // if LITTLE_ENDIAN is true, the most significant byte has the highest address. 107 ////////////////////////////////////////////////////////////////////////////////////////// 108 // @ offset : first byte in array. 109 // @ nbytes : record length in bytes (1/2/4). 110 // @ buffer_xp : extended pointer on byte array. 111 111 // @ return the integer value in a 32 bits word. 112 112 ////////////////////////////////////////////////////////////////////////////////////////// 113 static uint32_t fatfs_get_remote_record( uint32_t offset, 114 uint32_t nbytes, 115 xptr_t buffer_xp ) 116 { 117 uint32_t i; 118 uint32_t res = 0; 119 120 if ( LITTLE_ENDIAN ) 121 { 122 for( i = nbytes ; i > 0 ; i-- ) 123 { 124 res = (res<<8) | hal_remote_lb( buffer_xp+offset+i-1 ); 125 } 126 } 127 else 128 { 129 for( i = 0 ; i < nbytes ; i++ ) 130 { 131 res = (res<<8) | hal_remote_lb( buffer_xp+offset+i ); 132 } 133 } 134 return res; 135 136 } // end fatfs_get_remote_record() 137 138 ////////////////////////////////////////////////////////////////////////////////////////// 139 // This function writes one, two, or four bytes from a 32 bits integer to a local 140 // array of bytes, taking into account the global LITTLE_ENDIAN parameter: 141 // if LITTLE_ENDIAN is true, the most significant byte has the highest address. 142 ////////////////////////////////////////////////////////////////////////////////////////// 143 // @ offset : first byte in array. 144 // @ nbytes : record length in bytes (1/2/4). 145 // @ buffer : local pointer on byte array. 146 // @ value : 32 bits integer value. 147 ////////////////////////////////////////////////////////////////////////////////////////// 113 148 static void fatfs_set_record( uint32_t offset, 114 uint32_t size,149 uint32_t nbytes, 115 150 uint8_t * buffer, 116 uint32_t little_endian,117 151 uint32_t value ) 118 152 { 119 uint32_t n; 120 121 if ( little_endian ) 122 { 123 for( n = size ; n > 0 ; n-- ) buffer[offset+n-1] = (uint8_t)(value>>((n-1)<<3)); 124 } 125 else // big_endian 126 { 127 for( n = 0 ; n < size ; n++ ) buffer[offset+n] = (uint8_t)(value>>((size-1-n)<<3)); 153 uint32_t i; 154 155 if ( LITTLE_ENDIAN ) 156 { 157 for( i = nbytes ; i > 0 ; i-- ) buffer[offset+i-1] = (uint8_t)(value>>((i-1)<<3)); 158 } 159 else 160 { 161 for( i = 0 ; i < nbytes ; i++ ) buffer[offset+i] = (uint8_t)(value>>((nbytes-1-i)<<3)); 162 } 163 164 } // end fatfs_set_record() 165 166 ////////////////////////////////////////////////////////////////////////////////////////// 167 // This function writes one, two, or four bytes from a 32 bits integer to a remote 168 // array of bytes, taking into account the global LITTLE_ENDIAN parameter: 169 // if LITTLE_ENDIAN is true, the most significant byte has the highest address. 170 ////////////////////////////////////////////////////////////////////////////////////////// 171 // @ offset : first byte in array. 172 // @ nbytes : record length in bytes (1/2/4). 173 // @ buffer_xp : extended pointer on byte array. 174 // @ value : 32 bits integer value. 175 ////////////////////////////////////////////////////////////////////////////////////////// 176 static void fatfs_set_remote_record( uint32_t offset, 177 uint32_t nbytes, 178 xptr_t buffer_xp, 179 uint32_t value ) 180 { 181 uint32_t i; 182 183 if ( LITTLE_ENDIAN ) 184 { 185 for( i = nbytes ; i > 0 ; i-- ) 186 { 187 hal_remote_sb( (buffer_xp+offset+i-1) , (uint8_t)(value>>((i-1)<<3)) ); 188 } 189 } 190 else 191 { 192 for( i = 0 ; i < nbytes ; i++ ) 193 { 194 hal_remote_sb( (buffer_xp+offset+i) , (uint8_t)(value>>((nbytes-1-i)<<3)) ); 195 } 128 196 } 129 197 … … 374 442 375 443 ////////////////////////////////////////////////////////////////////////////////////////// 444 // This static function is called by both the fatfs_free_clusters_increment(), 445 // and the fatfs_free_cluster_decrement() functions defined below. 446 // It synchronously updates the "free_clusters" and "free_cluster_hint" variables 447 // in FS_INFO sector on the IOC device, each times these variables are modified. 448 ////////////////////////////////////////////////////////////////////////////////////////// 449 // @ fatfs_ctx_xp : extended pointer on fatfs context in FAT cluster. 450 // @ free_clusters : new free_clusters value. 451 // @ free_cluster_hint : new free_cluster_hint value. 452 // @ return 0 if success, return -1 if the FS_INFO sector cannot be updated. 453 ////////////////////////////////////////////////////////////////////////////////////////// 454 static error_t fatfs_free_clusters_update_ioc( xptr_t fatfs_ctx_xp, 455 uint32_t free_clusters, 456 uint32_t free_cluster_hint ) 457 { 458 cxy_t fat_cxy; // FAT cluster identifier 459 fatfs_ctx_t * fatfs_ctx_ptr; // local pointer on fatfs context in FAT cluster 460 uint8_t * fs_info_buffer_ptr; // local pointer on FS_INFO buffer in FAT cluster 461 xptr_t fs_info_buffer_xp; // extended pointer on FS_INFO buffer in FAT cluster 462 uint32_t fs_info_lba; // FS_INFO sector lba on IOC device 463 464 // get cluster and local pointer on FAT cluster context 465 fat_cxy = GET_CXY( fatfs_ctx_xp ); 466 fatfs_ctx_ptr = GET_PTR( fatfs_ctx_xp ); 467 468 // get pointers on FS_INFO buffer in FAT cluster 469 fs_info_buffer_ptr = hal_remote_lpt( XPTR( fat_cxy , &fatfs_ctx_ptr->fs_info_buffer ) ); 470 fs_info_buffer_xp = XPTR( fat_cxy , fs_info_buffer_ptr ); 471 472 // get lba of FS_INFO sector on IOC device from fatfs context 473 fs_info_lba = hal_remote_l32( XPTR( fat_cxy , &fatfs_ctx_ptr->fs_info_lba ) ); 474 475 // update the FS_INFO buffer in FAT cluster 476 fatfs_set_remote_record( FS_FREE_CLUSTERS , fs_info_buffer_xp , free_clusters ); 477 fatfs_set_remote_record( FS_FREE_CLUSTER_HINT , fs_info_buffer_xp , free_cluster_hint ); 478 479 // update the FS_INFO sector on IOC device 480 return dev_ioc_sync_write( fs_info_buffer_xp , fs_info_lba , 1 ); 481 482 } // fatfs_free_clusters_update_ioc() 483 484 ////////////////////////////////////////////////////////////////////////////////////////// 376 485 // This static function decrements the "free_clusters" variable, and updates the 377 // "free_cluster_hint" variable in the FATFS context , identified by the <fat_ctx_cxy>378 // and <fat_ctx_ptr> arguments (cluster containing the FAT mapper).486 // "free_cluster_hint" variable in the FATFS context in FAT cluster, identified 487 // by the <fat_ctx_xp> argument, when a new <cluster> has been allocated from FAT. 379 488 // It scan all slots in the FAT mapper seen as an array of 32 bits words, looking for the 380 489 // first free slot larger than the <cluster> argument, to update "free_cluster_hint". 490 // It calls the fatfs_free_clusters_update_ioc() function to synchronously update the 491 // FS_INFO sector on the IOC device. It can be called by a thead running in any cluster. 381 492 // 382 493 // WARNING : The free_lock protecting exclusive access to these variables 383 494 // must be taken by the calling function. 384 495 ////////////////////////////////////////////////////////////////////////////////////////// 385 // @ fat_ctx_cxy : FAT mapper cluster identifier. 386 // @ fat_ctx_ptr : local pointer on FATFS context. 387 // @ cluster : recently allocated cluster index in FAT. 388 ////////////////////////////////////////////////////////////////////////////////////////// 389 static error_t fatfs_free_clusters_decrement( cxy_t fat_ctx_cxy, 390 fatfs_ctx_t * fat_ctx_ptr, 391 uint32_t cluster ) 392 { 496 // @ fatfs_ctx_xp : extended pointer on FATFS context in FAT cluster. 497 // @ cluster : recently allocated cluster index in FAT. 498 // @ return 0 if success, return -1 if the FS_INFO sector cannot be updated. 499 ////////////////////////////////////////////////////////////////////////////////////////// 500 static error_t fatfs_free_clusters_decrement( xptr_t fatfs_ctx_xp, 501 uint32_t cluster ) 502 { 503 error_t error; 504 cxy_t fat_cxy; // FAT cluster identifier 505 fatfs_ctx_t * fat_ctx_ptr; // local pointer on fatfs context in FAT cluster 393 506 xptr_t mapper_xp; // extended pointer on FAT mapper 394 507 xptr_t hint_xp; // extended pointer on "free_cluster_hint" shared variable 395 508 xptr_t numb_xp; // extended pointer on "free_clusters" shared variable 396 509 uint32_t numb; // "free_clusters" variable current value 510 uint32_t hint; // "free_cluster_hint" variable current value 397 511 uint32_t page_id; // page index in FAT mapper 398 512 uint32_t slot_id; // slot index in one page of FAT (1024 slots per page) … … 405 519 uint32_t cycle = (uint32_t)hal_get_cycles(); 406 520 thread_t * this = CURRENT_THREAD; 407 if( DEBUG_FATFS_FREE_CLUSTERS < (uint32_t)hal_get_cycles())521 if( DEBUG_FATFS_FREE_CLUSTERS < cycle ) 408 522 printk("\n[%s] thread[%x,%x] enter for allocated cluster %x / cycle %d\n", 409 523 __FUNCTION__, this->process->pid, this->trdid, cluster , cycle ); 410 524 #endif 411 525 412 // build extended pointers on free_clusters, and free_cluster_hint 413 hint_xp = XPTR( fat_ctx_cxy , &fat_ctx_ptr->free_cluster_hint ); 414 numb_xp = XPTR( fat_ctx_cxy , &fat_ctx_ptr->free_clusters ); 415 416 // update "free_clusters" 417 numb = hal_remote_l32( numb_xp ); 418 hal_remote_s32( numb_xp , numb - 1 ); 526 // get FAT cluster an local pointer on fatfs context in FAT cluster 527 fat_cxy = GET_CXY( fatfs_ctx_xp ); 528 fat_ctx_ptr = GET_PTR( fatfs_ctx_xp ); 529 530 // build extended pointers on free_clusters, and free_cluster_hint in fatfs context 531 hint_xp = XPTR( fat_cxy , &fat_ctx_ptr->free_cluster_hint ); 532 numb_xp = XPTR( fat_cxy , &fat_ctx_ptr->free_clusters ); 533 534 // update "free_clusters" value 535 numb = hal_remote_l32( numb_xp ) - 1; 536 hal_remote_s32( numb_xp , numb ); 419 537 420 538 // get extended pointer on FAT mapper 421 mapper_xp = hal_remote_l64( XPTR( fat_c tx_cxy , &fat_ctx_ptr->fat_mapper_xp ) );539 mapper_xp = hal_remote_l64( XPTR( fat_cxy , &fat_ctx_ptr->fat_mapper_xp ) ); 422 540 423 541 // initialise variables to scan the FAT mapper … … 425 543 page_id = (cluster + 1) >> 10; 426 544 slot_id = (cluster + 1) & 0x3FF; 427 page_max = hal_remote_l32( XPTR( fat_c tx_cxy, &fat_ctx_ptr->fat_sectors_count ) ) >> 3;545 page_max = hal_remote_l32( XPTR( fat_cxy, &fat_ctx_ptr->fat_sectors_count ) ) >> 3; 428 546 429 547 // scan FAT mapper / loop on pages … … 451 569 if ( hal_remote_l32( slot_xp ) == FREE_CLUSTER ) 452 570 { 453 // update "free_cluster_hint" 454 hal_remote_s32( hint_xp , (page_id << 10) + slot_id - 1 ); 571 // update "free_cluster_hint" value 572 hint = (page_id << 10) + slot_id - 1; 573 hal_remote_s32( hint_xp , hint ); 574 575 // update FS_INFO sector on IOC device 576 error = fatfs_free_clusters_update_ioc( fatfs_ctx_xp , numb , hint ); 577 578 if( error ) 579 { 580 printk("\n[ERROR] in %s : cannot update FS_INFO on IOC\n", __FUNCTION__ ); 581 return -1; 582 } 455 583 456 584 #if DEBUG_FATFS_FREE_CLUSTERS 457 585 cycle = (uint32_t)hal_get_cycles(); 458 586 if( DEBUG_FATFS_FREE_CLUSTERS < (uint32_t)hal_get_cycles() ) 459 printk("\n[%s] thread[%x,%x] exit / hint %x / free_clusters %x / cycle %d\n",460 __FUNCTION__, this->process->pid, this->trdid, 461 hal_remote_l32(hint_xp), hal_remote_l32(numb_xp) , cycle);587 printk("\n[%s] thread[%x,%x] updated free cluster info / hint %x / number %x\n", 588 __FUNCTION__, this->process->pid, this->trdid, 589 hal_remote_l32(hint_xp), hal_remote_l32(numb_xp) ); 462 590 #endif 463 591 return 0; … … 469 597 } // end loop on slots 470 598 471 // update (page_id,slot_id)variables599 // update page_id & slot_id variables 472 600 page_id++; 473 601 slot_id = 0; … … 483 611 ////////////////////////////////////////////////////////////////////////////////////////// 484 612 // This static function increments the "free_clusters" variable, and updates the 485 // "free_cluster_hint" variables in the FATFS context , identified by the <fat_ctx_cxy>486 // and <fat_ctx_ptr> argument (cluster containing the FAT mapper).613 // "free_cluster_hint" variables in the FATFS context in FAT cluster, identified 614 // by the <fat_ctx_xp> argument, when a cluster is released to FAT. 487 615 // If the released cluster index is smaller than the current (hint) value, 488 616 // it set "free_cluster_hint" <= cluster. 617 // It calls the fatfs_free_clusters_update_ioc() function to synchronously update the 618 // FS_INFO sector on the IOC device. It can be called by a thead running in any cluster. 489 619 // 490 620 // WARNING : The free_lock protecting exclusive access to these variables 491 621 // must be taken by the calling function. 492 622 ////////////////////////////////////////////////////////////////////////////////////////// 493 // @ fat_ctx_cxy : FAT mapper cluster identifier. 494 // @ fat_ctx_ptr : local pointer on FATFS context. 495 // @ cluster : recently released cluster index in FAT. 496 ////////////////////////////////////////////////////////////////////////////////////////// 497 static void fatfs_free_clusters_increment( cxy_t fat_ctx_cxy, 498 fatfs_ctx_t * fat_ctx_ptr, 499 uint32_t cluster ) 500 { 623 // @ fatfs_ctx_xp : extended pointer on FATFS context in FAT cluster. 624 // @ cluster : recently released cluster index in FAT. 625 // @ return 0 if success, return -1 if the FS_INFO sector cannot be updated. 626 ////////////////////////////////////////////////////////////////////////////////////////// 627 static error_t fatfs_free_clusters_increment( xptr_t fatfs_ctx_xp, 628 uint32_t cluster ) 629 { 630 error_t error; 631 cxy_t fat_cxy; // FAT cluster identifier 632 fatfs_ctx_t * fat_ctx_ptr; // local pointer on fatfs context in FAT cluster 501 633 xptr_t hint_xp; // extended pointer on "free_cluster_hint" shared variable 502 634 xptr_t numb_xp; // extended pointer on "free_clusters" shared variable … … 504 636 uint32_t numb; // "free_clusters" variable current value 505 637 638 #if DEBUG_FATFS_FREE_CLUSTERS 639 uint32_t cycle = (uint32_t)hal_get_cycles(); 640 thread_t * this = CURRENT_THREAD; 641 if( DEBUG_FATFS_FREE_CLUSTERS < cycle ) 642 printk("\n[%s] thread[%x,%x] enter for released cluster %x / cycle %d\n", 643 __FUNCTION__, this->process->pid, this->trdid, cluster , cycle ); 644 #endif 645 646 // get FAT cluster an local pointer on fatfs context in FAT cluster 647 fat_cxy = GET_CXY( fatfs_ctx_xp ); 648 fat_ctx_ptr = GET_PTR( fatfs_ctx_xp ); 649 506 650 // build extended pointers on free_clusters, and free_cluster_hint 507 hint_xp = XPTR( fat_c tx_cxy , &fat_ctx_ptr->free_cluster_hint );508 numb_xp = XPTR( fat_c tx_cxy , &fat_ctx_ptr->free_clusters );651 hint_xp = XPTR( fat_cxy , &fat_ctx_ptr->free_cluster_hint ); 652 numb_xp = XPTR( fat_cxy , &fat_ctx_ptr->free_clusters ); 509 653 510 654 // get current value of free_cluster_hint and free_clusters … … 512 656 numb = hal_remote_l32( numb_xp ); 513 657 514 // update free_cluster_hint if required 515 if ( (cluster - 1) < hint ) hal_remote_s32( hint_xp , (cluster - 1) ); 658 // update "numb" and "hint" variables as required 659 numb++; 660 if ( (cluster - 1) < hint ) hint = cluster - 1; 516 661 517 662 // update free_clusters 518 hal_remote_s32( numb_xp , numb + 1 ); 663 hal_remote_s32( numb_xp , numb ); 664 hal_remote_s32( hint_xp , hint ); 665 666 // update FS_INFO sector on IOC device 667 error = fatfs_free_clusters_update_ioc( fatfs_ctx_xp , numb , hint ); 668 669 if( error ) 670 { 671 printk("\n[ERROR] in %s : cannot update FS_INFO on IOC\n", __FUNCTION__ ); 672 return -1; 673 } 519 674 520 675 #if DEBUG_FATFS_FREE_CLUSTERS 521 676 thread_t * this = CURRENT_THREAD; 522 677 if( DEBUG_FATFS_FREE_CLUSTERS < (uint32_t)hal_get_cycles() ) 523 printk("\n[%s] thread[%x,%x] update sfree cluster info : hint %x / number %x\n",678 printk("\n[%s] thread[%x,%x] updated free cluster info : hint %x / number %x\n", 524 679 __FUNCTION__, this->process->pid, this->trdid, 525 680 hal_remote_l32( hint_xp ), hal_remote_l32( numb_xp ) ); 526 681 #endif 682 683 return 0; 527 684 528 685 } // end fatfs_free_clusters_increment() … … 576 733 FREE_CLUSTER ) ) return -1; 577 734 578 // Update free_cluster_hint and free_clusters in FAT context 579 fatfs_free_clusters_increment( mapper_cxy, 580 fatfs_ctx, 581 cluster ); 582 583 return 0; 735 // Update free_cluster info in FATFS context and in FS_INFO sector 736 return fatfs_free_clusters_increment( XPTR( mapper_cxy , fatfs_ctx ) , cluster ); 584 737 585 738 } // end fatfs_recursive_release() … … 590 743 ////////////////////////////////////////////////////////////////////////////////////////// 591 744 592 /////////////////////////////////////////// 593 void fatfs_ctx_display( fatfs_ctx_t * ctx ) 594 { 595 printk("\n*** FAT context ***\n" 745 /////////////////////////////////// 746 void fatfs_display_ctx( cxy_t cxy ) 747 { 748 // get pointer on local FATFS context 749 vfs_ctx_t * vfs_ctx = &fs_context[FS_TYPE_FATFS]; 750 fatfs_ctx_t * ctx = hal_remote_lpt( XPTR( cxy , &vfs_ctx->extend ) ); 751 752 uint32_t fat_sectors = hal_remote_l32( XPTR( cxy , &ctx->fat_sectors_count ) ); 753 uint32_t sector_size = hal_remote_l32( XPTR( cxy , &ctx->bytes_per_sector ) ); 754 uint32_t sec_per_clus = hal_remote_l32( XPTR( cxy , &ctx->sectors_per_cluster ) ); 755 uint32_t fat_lba = hal_remote_l32( XPTR( cxy , &ctx->fat_begin_lba ) ); 756 uint32_t data_lba = hal_remote_l32( XPTR( cxy , &ctx->cluster_begin_lba ) ); 757 uint32_t fsinfo_lba = hal_remote_l32( XPTR( cxy , &ctx->fs_info_lba ) ); 758 uint32_t root_dir_clus = hal_remote_l32( XPTR( cxy , &ctx->root_dir_cluster ) ); 759 uint32_t free_clusters = hal_remote_l32( XPTR( cxy , &ctx->free_clusters ) ); 760 uint32_t free_cluster_hint = hal_remote_l32( XPTR( cxy , &ctx->free_cluster_hint ) ); 761 xptr_t mapper_xp = hal_remote_l64( XPTR( cxy , &ctx->fat_mapper_xp ) ); 762 void * fs_info_buffer = hal_remote_lpt( XPTR( cxy , &ctx->fs_info_buffer ) ); 763 764 printk("\n*** FAT context in cluster %x\n" 596 765 "- fat_sectors = %d\n" 597 766 "- sector size = %d\n" 598 767 "- cluster size = %d\n" 599 "- fat_first_lba = %d\n" 600 "- data_first_lba = %d\n" 601 "- root_dir_cluster = %d\n" 602 "- free_clusters = %d\n" 603 "- free_cluster_hint = %d\n" 604 "- fat_mapper_xp = %l\n", 605 ctx->fat_sectors_count, 606 ctx->bytes_per_sector, 607 ctx->sectors_per_cluster * ctx->bytes_per_sector, 608 ctx->fat_begin_lba, 609 ctx->cluster_begin_lba, 610 ctx->root_dir_cluster, 611 ctx->free_clusters, 612 ctx->free_cluster_hint, 613 ctx->fat_mapper_xp ); 614 615 } // end ctx_display() 768 "- fat_lba = %x\n" 769 "- data_lba = %x\n" 770 "- fsinfo_lba = %x\n" 771 "- root_dir_cluster = %x\n" 772 "- free_clusters = %x\n" 773 "- free_cluster_hint = %x\n" 774 "- fat_mapper_ptr = %x\n" 775 "- fs_info_buffer = %x\n", 776 cxy, 777 fat_sectors, 778 sector_size, 779 sector_size * sec_per_clus, 780 fat_lba, 781 data_lba, 782 fsinfo_lba, 783 root_dir_clus, 784 free_clusters, 785 free_cluster_hint, 786 GET_PTR( mapper_xp ), 787 fs_info_buffer ); 788 789 } // end fatfs_ctx_display() 616 790 617 791 ////////////////////////////////////////// … … 622 796 uint32_t maxline; 623 797 624 // co pute numner of lines to display798 // compute number of lines to display 625 799 maxline = nentries >> 3; 626 800 if( nentries & 0x7 ) maxline++; 627 801 628 802 // get pointer on local FATFS context 629 vfs_ctx_t * vfs_ctx = &fs_context[FS_TYPE_FATFS];630 fatfs_ctx_t * fatfs_ctx = (fatfs_ctx_t *)vfs_ctx->extend;803 vfs_ctx_t * vfs_ctx = &fs_context[FS_TYPE_FATFS]; 804 fatfs_ctx_t * loc_fatfs_ctx = (fatfs_ctx_t *)vfs_ctx->extend; 631 805 632 806 // get extended pointer on FAT mapper 633 xptr_t fat_mapper_xp = fatfs_ctx->fat_mapper_xp; 634 635 // get extended pointer and cluster of FAT mapper requested page 807 xptr_t fat_mapper_xp = loc_fatfs_ctx->fat_mapper_xp; 808 809 // get FAT cluster identifier 810 cxy_t fat_cxy = GET_CXY( fat_mapper_xp ); 811 812 // get pointer on FATFS context in FAT cluster 813 fatfs_ctx_t * fat_fatfs_ctx = hal_remote_lpt( XPTR( fat_cxy , &vfs_ctx->extend ) ); 814 815 // get current value of hint and free_clusters 816 uint32_t hint = hal_remote_l32( XPTR( fat_cxy , &fat_fatfs_ctx->free_cluster_hint ) ); 817 uint32_t free = hal_remote_l32( XPTR( fat_cxy , &fat_fatfs_ctx->free_clusters ) ); 818 819 // get extended pointer on requested page in FAT mapper 636 820 xptr_t page_xp = mapper_remote_get_page( fat_mapper_xp , page_id ); 637 821 638 822 // get extended pointer on requested page base 639 823 xptr_t base_xp = ppm_page2base( page_xp ); 640 641 printk("\n***** FAT content / page %d *****\n", page_id ); 824 void * base = GET_PTR( base_xp ); 825 826 printk("\n***** FAT mapper / cxy %x / page_id %d / base %x / free_clusters %x / hint %x\n", 827 fat_cxy, page_id, base, free, hint ); 828 642 829 for( line = 0 ; line < maxline ; line++ ) 643 830 { … … 766 953 kmem_req_t req; 767 954 uint8_t * buffer; 955 xptr_t buffer_xp; 768 956 769 957 #if DEBUG_FATFS_CTX_INIT … … 778 966 assert( (fatfs_ctx != NULL) , "pointer on FATFS context is NULL" ); 779 967 780 // check only cluster 0 does FATFS init 968 // check only cluster 0 does FATFS initialization 781 969 assert( (local_cxy == 0) , "only cluster 0 can initialize FATFS"); 782 970 783 // allocate a 512 bytes buffer to store the boot record 971 // allocate a permanent 512 bytes buffer to store 972 // - temporarily the BOOT sector 973 // - permanently the FS_INFO sector 784 974 req.type = KMEM_512_BYTES; 785 975 req.flags = AF_KERNEL | AF_ZERO; 786 976 buffer = (uint8_t *)kmem_alloc( &req ); 977 buffer_xp = XPTR( local_cxy , buffer ); 787 978 788 979 if( buffer == NULL ) … … 793 984 794 985 // load the BOOT record from device 795 error = dev_ioc_sync_read( buffer , 0 , 1 );986 error = dev_ioc_sync_read( buffer_xp , 0 , 1 ); 796 987 797 988 if ( error ) … … 807 998 808 999 // get sector size from boot record 809 uint32_t sector_size = fatfs_get_record( BPB_BYTSPERSEC , buffer , 1);1000 uint32_t sector_size = fatfs_get_record( BPB_BYTSPERSEC , buffer ); 810 1001 if ( sector_size != 512 ) 811 1002 { … … 815 1006 816 1007 // get cluster size from boot record 817 uint32_t nb_sectors = fatfs_get_record( BPB_SECPERCLUS , buffer , 1);1008 uint32_t nb_sectors = fatfs_get_record( BPB_SECPERCLUS , buffer ); 818 1009 if ( nb_sectors != 8 ) 819 1010 { … … 823 1014 824 1015 // get number of FAT copies from boot record 825 uint32_t nb_fats = fatfs_get_record( BPB_NUMFATS , buffer , 1);1016 uint32_t nb_fats = fatfs_get_record( BPB_NUMFATS , buffer ); 826 1017 if ( nb_fats != 1 ) 827 1018 { … … 831 1022 832 1023 // get number of sectors in FAT from boot record 833 uint32_t fat_sectors = fatfs_get_record( BPB_FAT32_FATSZ32 , buffer , 1);1024 uint32_t fat_sectors = fatfs_get_record( BPB_FAT32_FATSZ32 , buffer ); 834 1025 if ( (fat_sectors & 0xF) != 0 ) 835 1026 { … … 839 1030 840 1031 // get root cluster from boot record 841 uint32_t root_cluster = fatfs_get_record( BPB_FAT32_ROOTCLUS , buffer , 1);1032 uint32_t root_cluster = fatfs_get_record( BPB_FAT32_ROOTCLUS , buffer ); 842 1033 if ( root_cluster != 2 ) 843 1034 { … … 847 1038 848 1039 // get FAT lba from boot record 849 uint32_t fat_lba = fatfs_get_record( BPB_RSVDSECCNT , buffer , 1);1040 uint32_t fat_lba = fatfs_get_record( BPB_RSVDSECCNT , buffer ); 850 1041 851 1042 // get FS_INFO sector lba from boot record 852 uint32_t fs_info_lba = fatfs_get_record( BPB_FAT32_FSINFO , buffer , 1);1043 uint32_t fs_info_lba = fatfs_get_record( BPB_FAT32_FSINFO , buffer ); 853 1044 854 1045 // load the FS_INFO record from device 855 error = dev_ioc_sync_read( buffer , fs_info_lba , 1 );1046 error = dev_ioc_sync_read( buffer_xp , fs_info_lba , 1 ); 856 1047 857 1048 if ( error ) … … 861 1052 } 862 1053 863 // get free 864 uint32_t free_clusters = fatfs_get_record( FS_FREE_CLUSTERS , buffer , 1);1054 // get free_clusters number from FS_INFO record 1055 uint32_t free_clusters = fatfs_get_record( FS_FREE_CLUSTERS , buffer ); 865 1056 if ( free_clusters >= fat_sectors << 7 ) 866 1057 { … … 869 1060 } 870 1061 871 // get cluster hint from FS_INFO record 872 uint32_t free_cluster_hint = fatfs_get_record( FS_FREE_CLUSTER_HINT , buffer , 1 ); 1062 // get free_cluster_hint from FS_INFO record 1063 uint32_t free_cluster_hint = fatfs_get_record( FS_FREE_CLUSTER_HINT , buffer ); 1064 873 1065 if ( free_cluster_hint >= fat_sectors << 7 ) 874 1066 { … … 876 1068 hal_core_sleep(); 877 1069 } 878 879 // release the 512 bytes buffer880 req.type = KMEM_512_BYTES;881 req.ptr = buffer;882 kmem_free( &req );883 1070 884 1071 // allocate a mapper for the FAT itself … … 890 1077 } 891 1078 892 // WARNING : the inode field MUST beNULL for the FAT mapper1079 // the inode field is NULL for the FAT mapper 893 1080 fat_mapper->inode = NULL; 894 895 1081 896 1082 // initialize the FATFS context … … 902 1088 fatfs_ctx->root_dir_cluster = 2; 903 1089 fatfs_ctx->fat_mapper_xp = XPTR( local_cxy , fat_mapper ); 1090 fatfs_ctx->fs_info_lba = fs_info_lba; 904 1091 fatfs_ctx->free_clusters = free_clusters; 905 1092 fatfs_ctx->free_cluster_hint = free_cluster_hint; 1093 fatfs_ctx->fs_info_buffer = buffer; 906 1094 907 1095 remote_queuelock_init( XPTR( local_cxy , &fatfs_ctx->free_lock ) , LOCK_FATFS_FREE ); … … 1019 1207 while ( (offset < 4096) && (found == 0) ) 1020 1208 { 1021 if ( fatfs_get_record( LDIR_ORD, (base + offset) , 0) == NO_MORE_ENTRY )1209 if ( fatfs_get_record( LDIR_ORD, (base + offset) ) == NO_MORE_ENTRY ) 1022 1210 { 1023 1211 found = 1; … … 1335 1523 1336 1524 // check for LFN entry 1337 assert( (fatfs_get_record( DIR_ATTR, base + offset , 0) == ATTR_LONG_NAME_MASK ),1525 assert( (fatfs_get_record( DIR_ATTR, base + offset ) == ATTR_LONG_NAME_MASK ), 1338 1526 "this directory entry must be a LFN\n"); 1339 1527 … … 1439 1627 while( (offset < 4096) && (found == 0) ) 1440 1628 { 1441 attr = fatfs_get_record( DIR_ATTR , base + offset , 0);1442 ord = fatfs_get_record( LDIR_ORD , base + offset , 0);1629 attr = fatfs_get_record( DIR_ATTR , base + offset ); 1630 ord = fatfs_get_record( LDIR_ORD , base + offset ); 1443 1631 1444 1632 if (ord == NO_MORE_ENTRY) // no more entry => break … … 1559 1747 1560 1748 // check arguments 1561 assert( (parent_inode != NULL) , "parent_inode is NULL\n" ); 1562 assert( (name != NULL) , "name is NULL\n" ); 1563 assert( (child_inode_xp != XPTR_NULL ) , "child_inode is XPTR_NULL\n" ); 1749 assert( (parent_inode != NULL) , "parent_inode is NULL\n" ); 1750 assert( (name != NULL) , "name is NULL\n" ); 1751 assert( (child_inode_xp != XPTR_NULL ) , "child_inode is NULL\n" ); 1752 1753 // get child inode cluster and local pointer 1754 child_inode_cxy = GET_CXY( child_inode_xp ); 1755 child_inode_ptr = GET_PTR( child_inode_xp ); 1756 1757 // build extended pointer on root of list of parent dentries 1758 root_xp = XPTR( child_inode_cxy , &child_inode_ptr->parents ); 1759 1760 // check child inode has at least one parent 1761 assert( (xlist_is_empty( root_xp ) == false ), "child inode must have one parent\n"); 1564 1762 1565 1763 #if DEBUG_FATFS_GET_DENTRY … … 1578 1776 error = fatfs_scan_directory( mapper, name , &entry , &index ); 1579 1777 1580 if( error ) 1581 { 1582 vfs_inode_get_name( XPTR( local_cxy , parent_inode ) , dir_name ); 1583 printk("\n[ERROR] in %s : cannot find <%s> in parent mapper <%s>\n", 1584 __FUNCTION__, name , dir_name ); 1585 return -1; 1586 } 1778 // return non fatal error if not found 1779 if( error ) return -1; 1587 1780 1588 1781 // get relevant infos from FAT32 directory entry 1589 cluster = (fatfs_get_record( DIR_FST_CLUS_HI , entry , 1 ) << 16) | 1590 (fatfs_get_record( DIR_FST_CLUS_LO , entry , 1 ) ) ; 1591 is_dir = (fatfs_get_record( DIR_ATTR , entry , 1 ) & ATTR_DIRECTORY); 1592 size = fatfs_get_record( DIR_FILE_SIZE , entry , 1 ); 1593 1594 // get child inode cluster and local pointer 1595 child_inode_cxy = GET_CXY( child_inode_xp ); 1596 child_inode_ptr = GET_PTR( child_inode_xp ); 1597 1598 // build extended pointer on root of list of parent dentries 1599 root_xp = XPTR( child_inode_cxy , &child_inode_ptr->parents ); 1600 1601 // check child inode has at least one parent 1602 assert( (xlist_is_empty( root_xp ) == false ), "child inode must have one parent\n"); 1782 cluster = (fatfs_get_record( DIR_FST_CLUS_HI , entry ) << 16) | 1783 (fatfs_get_record( DIR_FST_CLUS_LO , entry ) ) ; 1784 is_dir = (fatfs_get_record( DIR_ATTR , entry ) & ATTR_DIRECTORY); 1785 size = fatfs_get_record( DIR_FILE_SIZE , entry ); 1603 1786 1604 1787 // scan list of parent dentries to search the parent_inode … … 1692 1875 1693 1876 // set size in FAT32 directory entry 1694 fatfs_set_record( DIR_FILE_SIZE , entry , 1 ,size );1877 fatfs_set_record( DIR_FILE_SIZE , entry , size ); 1695 1878 1696 1879 // get local pointer on modified page base … … 1795 1978 bool_t valid = (dentry_id >= min_dentry) && (dirent_id < max_dirent ); 1796 1979 1797 attr = fatfs_get_record( DIR_ATTR , base + offset , 0);1798 ord = fatfs_get_record( LDIR_ORD , base + offset , 0);1980 attr = fatfs_get_record( DIR_ATTR , base + offset ); 1981 ord = fatfs_get_record( LDIR_ORD , base + offset ); 1799 1982 1800 1983 if (ord == NO_MORE_ENTRY) // no more entry => break … … 2033 2216 error_t fatfs_sync_free_info( void ) 2034 2217 { 2218 error_t error; 2219 fatfs_ctx_t * fatfs_ctx_ptr; // local pointer on fatfs context in cluster 0 2220 uint32_t ctx_free_clusters; // number of free clusters from fatfs context 2221 uint32_t ctx_free_cluster_hint; // free cluster hint from fatfs context 2222 uint32_t ioc_free_clusters; // number of free clusters from fatfs context 2223 uint32_t ioc_free_cluster_hint; // free cluster hint from fatfs context 2224 uint32_t fs_info_lba; // lba of FS_INFO sector on IOC device 2225 uint8_t * fs_info_buffer; // local pointer on FS_INFO buffer in cluster 0 2226 xptr_t fs_info_buffer_xp; // extended pointer on FS_INFO buffer in cluster 0 2227 uint8_t tmp_buf[512]; // 512 bytes temporary buffer 2228 xptr_t tmp_buf_xp; // extended pointer on temporary buffer 2035 2229 2036 2230 #if DEBUG_FATFS_SYNC_FSINFO … … 2042 2236 #endif 2043 2237 2044 uint8_t * buffer; // dynamically allocated aligned 512 bytes buffer 2045 kmem_req_t req; 2046 error_t error; 2047 2048 // get FS_INFO lba, free_ from FATFS context 2049 fatfs_ctx_t * fatfs_ctx = fs_context[FS_TYPE_FATFS].extend; 2050 uint32_t lba = fatfs_ctx->fs_info_lba; 2051 uint32_t hint = fatfs_ctx->free_cluster_hint; 2052 uint32_t number = fatfs_ctx->free_clusters; 2053 2054 // allocate buffer to store the FS_INFO sector 2055 req.type = KMEM_512_BYTES; 2056 req.flags = AF_KERNEL | AF_ZERO; 2057 buffer = (uint8_t *)kmem_alloc( &req ); 2058 if( buffer == NULL ) 2059 { 2060 printk("\n[PANIC] in %s : cannot allocate buffer\n", __FUNCTION__ ); 2061 return ENOMEM; 2062 } 2063 2064 // load the FS_INFO sector from device to buffer 2065 error = dev_ioc_read( buffer , lba , 1 ); 2238 // get pointer on fatfs context in cluster 0 2239 fatfs_ctx_ptr = hal_remote_lpt( XPTR( 0 , &fs_context[FS_TYPE_FATFS].extend ) ); 2240 2241 // get "free_clusters" and "free_cluster_hint" from fatfs context in cluster 0 2242 ctx_free_clusters = hal_remote_l32( XPTR( 0 , &fatfs_ctx_ptr->free_clusters ) ); 2243 ctx_free_cluster_hint = hal_remote_l32( XPTR( 0 , &fatfs_ctx_ptr->free_cluster_hint ) ); 2244 2245 // get fs_info_lba 2246 fs_info_lba = hal_remote_l32( XPTR( 0 , &fatfs_ctx_ptr->fs_info_lba ) ); 2247 2248 // build extended pointer on temporary buffer 2249 tmp_buf_xp = XPTR( local_cxy , tmp_buf ); 2250 2251 // copy FS_INFO sector from IOC to local buffer 2252 error = dev_ioc_sync_read( tmp_buf_xp , fs_info_lba , 1 ); 2253 2066 2254 if ( error ) 2067 2255 { 2068 printk("\n[PANIC] in %s : cannot read FS_INFO record\n", __FUNCTION__ ); 2069 return EIO; 2070 } 2071 2072 // update buffer 2073 fatfs_set_record( FS_FREE_CLUSTERS , buffer , 1 , number ); 2074 fatfs_set_record( FS_FREE_CLUSTER_HINT , buffer , 1 , hint ); 2075 2076 // write modified FS_INFO sector from buffer to device 2077 error = dev_ioc_write( buffer , lba , 1 ); 2078 if ( error ) 2079 { 2080 printk("\n[PANIC] in %s : cannot write FS_INFO record\n", __FUNCTION__ ); 2081 return EIO; 2082 } 2083 2084 // release the 512 bytes buffer 2085 req.type = KMEM_512_BYTES; 2086 req.ptr = buffer; 2087 kmem_free( &req ); 2256 printk("\n[ERROR] in %s : cannot access FS_INFO on IOC device\n", __FUNCTION__ ); 2257 return -1; 2258 } 2259 2260 // get current values of "free_clusters" and "free_cluster_hint" from FS_INFO on IOC 2261 ioc_free_clusters = fatfs_get_remote_record( FS_FREE_CLUSTERS , tmp_buf_xp ); 2262 ioc_free_cluster_hint = fatfs_get_remote_record( FS_FREE_CLUSTER_HINT , tmp_buf_xp ); 2263 2264 // check values 2265 if( (ioc_free_clusters != ctx_free_clusters) || 2266 (ioc_free_cluster_hint != ctx_free_cluster_hint) ) 2267 { 2268 printk("\n[WARNING] in %s : unconsistent free clusters info\n" 2269 " ioc_free %x / ctx_free %x / ioc_hint %x / ctx_hint %x\n", 2270 __FUNCTION__, ioc_free_clusters, ctx_free_clusters, 2271 ioc_free_cluster_hint, ctx_free_cluster_hint ); 2272 2273 // get pointers on FS_INFO buffer in cluster 0 2274 fs_info_buffer = hal_remote_lpt( XPTR( 0 , &fatfs_ctx_ptr->fs_info_buffer ) ); 2275 fs_info_buffer_xp = XPTR( 0 , fs_info_buffer ); 2276 2277 // update FS_INFO buffer in cluster 0 2278 fatfs_set_remote_record(FS_FREE_CLUSTERS ,fs_info_buffer_xp,ctx_free_clusters ); 2279 fatfs_set_remote_record(FS_FREE_CLUSTER_HINT,fs_info_buffer_xp,ctx_free_cluster_hint); 2280 2281 // update the FS_INFO sector on IOC device 2282 error = dev_ioc_sync_write( fs_info_buffer_xp , fs_info_lba , 1 ); 2283 2284 if ( error ) 2285 { 2286 printk("\n[ERROR] in %s : cannot update FS_INFO on IOC device\n", __FUNCTION__ ); 2287 return -1; 2288 } 2289 } 2088 2290 2089 2291 #if DEBUG_FATFS_SYNC_FSINFO … … 2096 2298 return 0; 2097 2299 2098 } // end fatfs_sync_f s_info()2300 } // end fatfs_sync_free_info() 2099 2301 2100 2302 ////////////////////////////////////////////////////////// 2101 2303 error_t fatfs_cluster_alloc( uint32_t * searched_cluster ) 2102 2304 { 2305 error_t error; 2103 2306 uint32_t page_id; // page index in FAT mapper 2104 2307 uint32_t slot_id; // slot index in page (1024 slots per page) … … 2109 2312 fatfs_ctx_t * fat_fatfs_ctx; // local pointer on FATFS context in FAT cluster 2110 2313 xptr_t mapper_xp; // extended pointer on FAT mapper 2111 cxy_t mapper_cxy;// Fat mapper cluster identifier2314 cxy_t fat_cxy; // Fat mapper cluster identifier 2112 2315 xptr_t page_xp; // extended pointer on current page descriptor in mapper 2113 2316 xptr_t slot_xp; // extended pointer on FAT slot defined by hint 2114 2317 xptr_t lock_xp; // extended pointer on lock protecting free clusters info 2115 2318 xptr_t hint_xp; // extended pointer on free_cluster_hint in FAT cluster 2116 xptr_t numb_xp; // extended pointer on free_clusters_number in FAT cluster2319 xptr_t free_xp; // extended pointer on free_clusters_number in FAT cluster 2117 2320 2118 2321 #if DEBUG_FATFS_CLUSTER_ALLOC … … 2130 2333 loc_fatfs_ctx = vfs_ctx->extend; 2131 2334 2132 // get extended pointer and clusteron FAT mapper2335 // get extended pointer on FAT mapper 2133 2336 mapper_xp = loc_fatfs_ctx->fat_mapper_xp; 2134 mapper_cxy = GET_CXY( mapper_xp ); 2337 2338 // get FAT cluster 2339 fat_cxy = GET_CXY( mapper_xp ); 2135 2340 2136 2341 // get local pointer on FATFS context in FAT cluster 2137 fat_fatfs_ctx = hal_remote_lpt( XPTR( mapper_cxy , &vfs_ctx->extend ) );2342 fat_fatfs_ctx = hal_remote_lpt( XPTR( fat_cxy , &vfs_ctx->extend ) ); 2138 2343 2139 2344 // build relevant extended pointers on free clusters info in mapper cluster 2140 lock_xp = XPTR( mapper_cxy , &fat_fatfs_ctx->free_lock );2141 hint_xp = XPTR( mapper_cxy , &fat_fatfs_ctx->free_cluster_hint );2142 numb_xp = XPTR( mapper_cxy , &fat_fatfs_ctx->free_clusters );2345 lock_xp = XPTR( fat_cxy , &fat_fatfs_ctx->free_lock ); 2346 hint_xp = XPTR( fat_cxy , &fat_fatfs_ctx->free_cluster_hint ); 2347 free_xp = XPTR( fat_cxy , &fat_fatfs_ctx->free_clusters ); 2143 2348 2144 2349 // take the lock protecting free clusters 2145 2350 remote_queuelock_acquire( lock_xp ); 2146 2351 2147 // get hint and free_clusters values from FATFS context 2352 // get hint and free_clusters values from FATFS context in FAT cluster 2148 2353 cluster = hal_remote_l32( hint_xp ) + 1; 2149 free_clusters = hal_remote_l32( numb_xp );2354 free_clusters = hal_remote_l32( free_xp ); 2150 2355 2151 2356 #if (DEBUG_FATFS_CLUSTER_ALLOC & 1) … … 2168 2373 } 2169 2374 2170 2171 2172 2375 // get page index & slot index for selected cluster 2173 2376 page_id = cluster >> 10; 2174 2377 slot_id = cluster & 0x3FF; 2175 2378 2176 // get relevant page descriptor from mapper2379 // get relevant page descriptor from FAT mapper 2177 2380 page_xp = mapper_remote_get_page( mapper_xp , page_id ); 2178 2381 … … 2194 2397 } 2195 2398 2196 // update free cluster info in FATFS context 2197 fatfs_free_clusters_decrement( mapper_cxy , fat_fatfs_ctx , cluster ); 2399 // update free cluster info in FATFS context and in FS_INFO sector 2400 error = fatfs_free_clusters_decrement( XPTR( fat_cxy , fat_fatfs_ctx ) , cluster ); 2401 2402 if( error ) 2403 { 2404 printk("\n[ERROR] in %s : cannot update free cluster info\n", __FUNCTION__ ); 2405 remote_queuelock_acquire( lock_xp ); 2406 return -1; 2407 } 2408 2409 // update FAT mapper 2410 hal_remote_s32( slot_xp , END_OF_CHAIN_CLUSTER_MAX ); 2411 2412 // synchronously update FAT on device 2413 error = fatfs_move_page( page_xp , IOC_SYNC_WRITE ); 2414 2415 if( error ) 2416 { 2417 printk("\n[ERROR] in %s : cannot update FAT on IOC device\n", __FUNCTION__ ); 2418 remote_queuelock_acquire( lock_xp ); 2419 return -1; 2420 } 2198 2421 2199 2422 // release free clusters busylock 2200 2423 remote_queuelock_release( lock_xp ); 2201 2202 // update FAT mapper2203 hal_remote_s32( slot_xp , END_OF_CHAIN_CLUSTER_MAX );2204 2205 // synchronously update FAT on device2206 fatfs_move_page( page_xp , IOC_SYNC_WRITE );2207 2424 2208 2425 #if DEBUG_FATFS_CLUSTER_ALLOC 2209 2426 cycle = (uint32_t)hal_get_cycles(); 2210 2427 if( DEBUG_FATFS_CLUSTER_ALLOC < cycle ) 2211 printk("\n[%s] thread[%x,%x] exit / updated cluster %x in FAT / cycle %d\n",2428 printk("\n[%s] thread[%x,%x] exit / allocated cluster %x in FAT / cycle %d\n", 2212 2429 __FUNCTION__, this->process->pid, this->trdid, cluster, cycle ); 2213 2430 #endif … … 2230 2447 xptr_t first_xp; // extended pointer on inode extension 2231 2448 uint32_t first_cluster; // first cluster index for released inode 2232 vfs_inode_t * inode_ptr; 2233 cxy_t inode_cxy; 2449 vfs_inode_t * inode_ptr; // local pointer on target inode 2450 cxy_t inode_cxy; // target inode cluster identifier 2234 2451 2235 2452 // check inode pointer … … 2357 2574 2358 2575 // get page base address 2359 xptr_t b ase_xp= ppm_page2base( page_xp );2360 uint8_t * buffer = (uint8_t *)GET_PTR( base_xp );2576 xptr_t buffer_xp = ppm_page2base( page_xp ); 2577 uint8_t * buffer_ptr = (uint8_t *)GET_PTR( buffer_xp ); 2361 2578 2362 2579 // get inode pointer from mapper 2363 2580 inode_ptr = hal_remote_lpt( XPTR( page_cxy , &mapper_ptr->inode ) ); 2364 2581 2365 ////////////////////////////// it is the FAT mapper 2582 #if DEBUG_FATFS_MOVE_PAGE 2583 if( DEBUG_FATFS_MOVE_PAGE < cycle ) 2584 printk("\n[%s] thread[%x,%x] enters : %s / cxy %x / mapper %x / inode %x / page %x\n", 2585 __FUNCTION__, this->process->pid, this->trdid, 2586 dev_ioc_cmd_str( cmd_type ), page_cxy, mapper_ptr, inode_ptr, buffer_ptr ); 2587 #endif 2588 2589 ////////////////////////////// FAT mapper 2366 2590 if( inode_ptr == NULL ) 2367 2591 { … … 2370 2594 2371 2595 // access device 2372 if ( cmd_type == IOC_SYNC_READ ) error = dev_ioc_sync_read ( buffer , lba , 8 ); 2373 else if( cmd_type == IOC_SYNC_WRITE ) error = dev_ioc_sync_write( buffer , lba , 8 ); 2374 else if( cmd_type == IOC_READ ) error = dev_ioc_read ( buffer , lba , 8 ); 2375 else if( cmd_type == IOC_WRITE ) error = dev_ioc_write ( buffer , lba , 8 ); 2376 else error = -1; 2377 2378 if( error ) return EIO; 2596 if (cmd_type == IOC_SYNC_READ ) error = dev_ioc_sync_read ( buffer_xp , lba , 8 ); 2597 else if(cmd_type == IOC_SYNC_WRITE) error = dev_ioc_sync_write( buffer_xp , lba , 8 ); 2598 else if(cmd_type == IOC_READ ) error = dev_ioc_read ( buffer_ptr , lba , 8 ); 2599 else if(cmd_type == IOC_WRITE ) error = dev_ioc_write ( buffer_ptr , lba , 8 ); 2600 else error = -1; 2601 2602 if( error ) 2603 { 2604 printk("\n[ERROR] in %s : cannot access device\n", __FUNCTION__ ); 2605 return -1; 2606 } 2379 2607 2380 2608 #if DEBUG_FATFS_MOVE_PAGE … … 2382 2610 { 2383 2611 if ( (cmd_type == IOC_READ) || (cmd_type == IOC_SYNC_READ) ) 2384 printk("\n[%s] thread[%x,%x] load page %d of FAT/ cycle %d\n",2385 2612 printk("\n[%s] thread[%x,%x] load FAT mapper page %d from IOC / cycle %d\n", 2613 __FUNCTION__, this->process->pid, this->trdid, page_id, cycle ); 2386 2614 else 2387 printk("\n[%s] thread[%x,%x] sync page %d of FAT/ cycle %d\n",2615 printk("\n[%s] thread[%x,%x] sync FAT mapper page %d to IOC / cycle %d\n", 2388 2616 __FUNCTION__, this->process->pid, this->trdid, page_id, cycle ); 2389 2617 } … … 2391 2619 2392 2620 } 2393 ///////////////////////// it is aninode mapper2621 ///////////////////////// inode mapper 2394 2622 else 2395 2623 { … … 2425 2653 } 2426 2654 2427 // get lba f romsearched_cluster2655 // get lba for searched_cluster 2428 2656 uint32_t lba = fatfs_lba_from_cluster( fatfs_ctx , searched_cluster ); 2657 2658 // access device 2659 if (cmd_type == IOC_SYNC_READ ) error = dev_ioc_sync_read ( buffer_xp , lba , 8 ); 2660 else if(cmd_type == IOC_SYNC_WRITE) error = dev_ioc_sync_write( buffer_xp , lba , 8 ); 2661 else if(cmd_type == IOC_READ ) error = dev_ioc_read ( buffer_ptr , lba , 8 ); 2662 else if(cmd_type == IOC_WRITE ) error = dev_ioc_write ( buffer_ptr , lba , 8 ); 2663 else error = -1; 2664 2665 if( error ) 2666 { 2667 printk("\n[ERROR] in %s : cannot access device\n", __FUNCTION__ ); 2668 return -1; 2669 } 2429 2670 2430 2671 #if DEBUG_FATFS_MOVE_PAGE … … 2440 2681 #endif 2441 2682 2442 // access device2443 if ( cmd_type == IOC_SYNC_READ ) error = dev_ioc_sync_read ( buffer , lba , 8 );2444 else if( cmd_type == IOC_SYNC_WRITE ) error = dev_ioc_sync_write( buffer , lba , 8 );2445 else if( cmd_type == IOC_READ ) error = dev_ioc_read ( buffer , lba , 8 );2446 else if( cmd_type == IOC_WRITE ) error = dev_ioc_write ( buffer , lba , 8 );2447 else error = -1;2448 2449 if( error )2450 {2451 printk("\n[ERROR] in %s : cannot access device\n", __FUNCTION__ );2452 return -1;2453 }2454 2683 } 2455 2684 -
trunk/kernel/fs/fatfs.h
r625 r626 173 173 /***************************************************************************************** 174 174 * This structure defines a FATFS specific context (extension to VFS context). 175 * This extension is replicated in all clusters. 176 * 177 * WARNING : Almost all fields are constant values, but the <free_cluster_hint> and 178 * <free_clusters> are shared variables. All kernel instances use the variables 179 * in cluster 0, using the <free_lock> remote busy_lock for exclusive access. 175 * This fatfs context is replicated in all clusters. 176 * 177 * WARNING : Almost all fields are constant values, but the <free_cluster_hint>, 178 * <free_clusters> and <free_lock> are shared variables. Moreover, the <fs_info_buffer>, 179 * only allocated in cluster 0, contains a copy of the FS_INFO sector. It is used by all 180 * kernel instances to synchronously update the free clusters info on IOC device. 181 * For these four variables, all kernel instances must use the values in cluster 0, 182 * and take the <free_lock> stored in this cluster for exclusive access to FAT. 180 183 ****************************************************************************************/ 181 184 182 185 typedef struct fatfs_ctx_s 183 186 { 187 /* read-only constants replicated in all clusters */ 184 188 uint32_t fat_sectors_count; /*! number of sectors in FAT region */ 185 189 uint32_t bytes_per_sector; /*! number of bytes per sector */ … … 190 194 uint32_t root_dir_cluster; /*! cluster index for root directory */ 191 195 xptr_t fat_mapper_xp; /*! extended pointer on FAT mapper */ 196 197 /* shared variables (only the copy in FAT cluster must be used) */ 192 198 uint32_t free_cluster_hint; /*! cluster[hint+1] is the first free */ 193 199 uint32_t free_clusters; /*! free clusters number */ 194 remote_queuelock_t free_lock; /*! exclusive access to hint & number */ 200 remote_queuelock_t free_lock; /*! exclusive access to FAT */ 201 uint8_t * fs_info_buffer; /*! local pointer on FS_INFO buffer */ 195 202 } 196 203 fatfs_ctx_t; … … 224 231 225 232 /***************************************************************************************** 226 * This function display the content of the local FATFS context. 227 ***************************************************************************************** 228 * @ ctx : local pointer on the context. 229 ****************************************************************************************/ 230 void fatfs_ctx_display( fatfs_ctx_t * ctx ); 231 232 /***************************************************************************************** 233 * This function displays the content of a part of the File Allocation Table. 234 * It loads the requested page fom device to mapper if required. 235 ***************************************************************************************** 236 * @ page_id : page index in FAT mapper (one page is 4 Kbytes). 237 * @ nentries : number of entries (one entry is 4 bytes). 233 * This function display the content of the FATFS context copy in cluster identified 234 * by the <cxy> argument. 235 * This function can be called by a thread running in any cluster. 236 ***************************************************************************************** 237 * @ cxy : target cluster identifier. 238 ****************************************************************************************/ 239 void fatfs_display_ctx( cxy_t cxy ); 240 241 /***************************************************************************************** 242 * This function access the FAT mapper to display one page of the File Allocation Table. 243 * It loads the requested page fom IOC device to FAT mapper if required. 244 * This function can be called by a thread running in any cluster. 245 ***************************************************************************************** 246 * @ page_id : page index in FAT mapper (one page is 4 Kbytes). 247 * @ nb_entries : number of entries (one entry is 4 bytes). 238 248 ****************************************************************************************/ 239 249 void fatfs_display_fat( uint32_t page_id, 240 uint32_t n entries );250 uint32_t nb_entries ); 241 251 242 252 … … 254 264 255 265 /***************************************************************************************** 256 * This function access the boot device, and initialises the local FATFS context 257 * from informations contained in the boot record. 266 * This function access the boot device, and initialises the local FATFS context, 267 * from informations contained in the boot record. This initialisation includes the 268 * creation of the FAT mapper in cluster 0. 258 269 ***************************************************************************************** 259 270 * @ vfs_ctx : local pointer on VFS context for FATFS. … … 271 282 * This function implements the generic vfs_fs_add_dentry() function for the FATFS. 272 283 ***************************************************************************************** 273 * This function updates a directory identified by the <inode> argument284 * This function updates a directory mapper identified by the <inode> argument 274 285 * to add a new directory entry identified by the <dentry> argument. 275 * All modified pages in directory mapper are synchronously updated on IOC device.276 * It must be called by a thread running in the cluster containing the inode.286 * All modified pages in the directory mapper are synchronously updated on IOC device. 287 * It must be called by a thread running in the cluster containing the directory inode. 277 288 * 278 289 * Implementation note : this function works in two steps: … … 313 324 * This function implements the generic vfs_fs_new_dentry() function for the FATFS. 314 325 ***************************************************************************************** 315 * It initializes a new inode/dentry couple in Inode Tree, attached to the directory316 * identified by the <parent_inode> argument. The directory entry is identified317 * by the <name> argument. The child inode descriptor, identified by the <child_inode_xp>318 * argument, and the associated dentry descriptor must have been previously allocated.319 * It scan the parent mapper to find the <name> argument.320 * It set the "type", "size", and "extend" fields in the child inode descriptor.321 * It set the " extend" field in the dentry descriptor.326 * It scan a parent directory mapper, identified by the <parent_inode> argument to find 327 * a directory entry identified by the <name> argument. In case of success, it 328 * initializes the inode/dentry couple, identified by the <child_inode_xp> argument 329 * in the Inode Tree. The child inode descriptor, and the associated dentry descriptor 330 * must have been previously allocated by the caller. 331 * - It set the "type", "size", and "extend" fields in the child inode descriptor. 332 * - It set the " extend" field in the dentry descriptor. 322 333 * It must be called by a thread running in the cluster containing the parent inode. 323 334 ***************************************************************************************** … … 325 336 * @ name : child name. 326 337 * @ child_inode_xp : extended pointer on remote child inode (file or directory). 327 * @ return 0 if success / return ENOENTif child not found.338 * @ return 0 if success / return -1 if child not found. 328 339 ****************************************************************************************/ 329 340 error_t fatfs_new_dentry( struct vfs_inode_s * parent_inode, … … 392 403 ***************************************************************************************** 393 404 * @ inode : local pointer on inode. 394 * @ return 0 if success / return EIO if failure duringdevice access.405 * @ return 0 if success / return -1 if failure during IOC device access. 395 406 ****************************************************************************************/ 396 407 error_t fatfs_sync_inode( struct vfs_inode_s * inode ); … … 399 410 * This function implements the generic vfs_fs_sync_fat() function for the FATFS. 400 411 ***************************************************************************************** 401 * It updates the FAT FSon the IOC device for the FAT itself.412 * It updates the FAT on the IOC device for the FAT itself. 402 413 * It scan all clusters registered in the FAT mapper, and copies from mapper to device 403 414 * each page marked as dirty. … … 408 419 * variables defining the smallest/largest dirty page index in FAT mapper... 409 420 ***************************************************************************************** 410 * @ return 0 if success / return EIO if failure duringdevice access.421 * @ return 0 if success / return -1 if failure during IOC device access. 411 422 ****************************************************************************************/ 412 423 error_t fatfs_sync_fat( void ); … … 415 426 * This function implements the generic vfs_fs_sync_fsinfo() function for the FATFS. 416 427 ***************************************************************************************** 417 * It updates the FS_INFO sector on the IOC device. 418 * It copies the <free_cluster_hint> and <free_clusters> variables from 419 * the FATFS context in cluster 0 to the FS_INFO sector on device. 420 ***************************************************************************************** 421 * @ return 0 if success / return EIO if failure during device access. 428 * It checks the current values of the "free_clusters" and "free_cluster_hint" variables 429 * in the FS_INFO sector on IOC, versus the values stored in the fatfs context. 430 * As these values are synchronously updated on IOC device at each modification, 431 * it does nothing if the values are equal. It updates the FS_INFO sector on IOC device, 432 * and displays a warning message on TXT0 if they are not equal. 433 * This function can be called by any thread running in any cluster. 434 ***************************************************************************************** 435 * @ return 0 if success / return -1 if failure during IOC device access. 422 436 ****************************************************************************************/ 423 437 error_t fatfs_sync_free_info( void ); … … 430 444 * It can be called by a thread running in any cluster, as it uses remote access 431 445 * primitives when the FAT mapper is remote. It takes the queuelock stored in the FATFS 432 * context (located in the same cluster as the FAT mapper itself), to get exclusive433 * access to the FAT. It uses the <free_cluster_hint> and <free_clusters> variables434 * stored in this FATFS context.446 * context located in the same cluster as the FAT mapper itself, to get exclusive 447 * access to the FAT. It uses and updates the <free_cluster_hint> and <free_clusters> 448 * variables stored in this FATFS context. 435 449 * - it updates the <free_cluster_hint> and <free_clusters> variables in FATFS context. 436 450 * - it updates the FAT mapper (handling miss from IOC device if required). … … 445 459 /***************************************************************************************** 446 460 * This function implements the generic vfs_fs_release_inode() function for the FATFS. 447 *****************************************************************************************461 ***************************************************************************************** 448 462 * It releases all clusters allocated to a file/directory identified by the <inode_xp> 449 463 * argument. All released clusters are marked FREE_CLUSTER in the FAT mapper. … … 466 480 * The pointer on the mapper and the page index in file are found in the page descriptor. 467 481 * It is used for both a regular file/directory mapper, and the FAT mapper. 468 * For the FAT mapper, it access the FATFS to get the location on IOC device.469 * For a regular file, it access the FAT mapper to get the cluster index on IOC device.482 * - For the FAT mapper, it updates the FAT region on IOC device. 483 * - For a regular file, it access the FAT mapper to get the cluster index on IOC device. 470 484 * It can be called by any thread running in any cluster. 471 485 * -
trunk/kernel/fs/vfs.c
r625 r626 423 423 } // end vfs_inode_load_all_pages() 424 424 425 ///////////////////////////////////////// 426 void vfs_inode_display( xptr_t inode_xp ) 427 { 428 assert( (inode_xp != XPTR_NULL), "inode pointer is NULL"); 429 430 char name[CONFIG_VFS_MAX_NAME_LENGTH]; 431 432 vfs_inode_get_name( inode_xp , name ); 433 434 cxy_t inode_cxy = GET_CXY( inode_xp ); 435 vfs_inode_t * inode_ptr = GET_PTR( inode_xp ); 436 437 vfs_inode_type_t type = hal_remote_l32( XPTR( inode_cxy , &inode_ptr->type ) ); 438 uint32_t attr = hal_remote_l32( XPTR( inode_cxy , &inode_ptr->attr ) ); 439 uint32_t size = hal_remote_l32( XPTR( inode_cxy , &inode_ptr->size ) ); 440 uint32_t parents = hal_remote_l32( XPTR( inode_cxy , &inode_ptr->links ) ); 441 mapper_t * mapper = hal_remote_lpt( XPTR( inode_cxy , &inode_ptr->mapper ) ); 442 void * extend = hal_remote_lpt( XPTR( inode_cxy , &inode_ptr->extend ) ); 443 444 printk("\n**** inode <%s>\n" 445 " - type = %s\n" 446 " - attr = %x\n" 447 " - size = %d\n" 448 " - parents = %d\n" 449 " - cxy = %x\n" 450 " - inode = %x\n" 451 " - mapper = %x\n" 452 " - extend = %x\n", 453 name, 454 vfs_inode_type_str( type ), 455 attr, 456 size, 457 parents, 458 inode_cxy, 459 inode_ptr, 460 mapper, 461 extend ); 462 463 } // end vfs_inode_display() 464 465 425 466 //////////////////////////////////////////////////////////////////////////////////////////// 426 467 // VFS dentry descriptor related functions … … 737 778 cycle = (uint32_t)hal_get_cycles(); 738 779 if( DEBUG_VFS_OPEN < cycle ) 739 printk("\n[%s] thread[%x,%x] exit for <%s> / fdid %d / c luster%x / cycle %d\n",780 printk("\n[%s] thread[%x,%x] exit for <%s> / fdid %d / cxy %x / cycle %d\n", 740 781 __FUNCTION__, process->pid, this->trdid, path, file_id, GET_CXY( file_xp ), cycle ); 741 782 #endif … … 773 814 // check inode type 774 815 assert( (inode_type == INODE_TYPE_FILE), "bad inode type" ); 816 817 #if DEBUG_VFS_USER_MOVE 818 char name[CONFIG_VFS_MAX_NAME_LENGTH]; 819 uint32_t cycle = (uint32_t)hal_get_cycles(); 820 thread_t * this = CURRENT_THREAD; 821 vfs_inode_t * inode = hal_remote_lpt( XPTR( file_cxy , &file_ptr->inode ) ); 822 vfs_inode_get_name( XPTR( file_cxy , inode ) , name ); 823 if( cycle > DEBUG_VFS_USER_MOVE ) 824 { 825 if( to_buffer ) 826 printk("\n[%s] thread[%x,%x] enter / %d bytes / mapper(%s) -> buffer(%x) / cycle %d\n", 827 __FUNCTION__ , this->process->pid, this->trdid, size, name, buffer, cycle ); 828 else 829 printk("\n[%s] thread[%x,%x] enter / %d bytes / buffer(%x) -> mapper(%s) / cycle %d\n", 830 __FUNCTION__ , this->process->pid, this->trdid, size, buffer, name, cycle ); 831 } 832 #endif 775 833 776 834 // get mapper pointer and file offset from file descriptor … … 794 852 795 853 #if DEBUG_VFS_USER_MOVE 796 char name[CONFIG_VFS_MAX_NAME_LENGTH]; 797 uint32_t cycle = (uint32_t)hal_get_cycles(); 798 thread_t * this = CURRENT_THREAD; 799 vfs_inode_t * inode = hal_remote_lpt( XPTR( file_cxy , &file_ptr->inode ) ); 800 vfs_inode_get_name( XPTR( file_cxy , inode ) , name ); 854 cycle = (uint32_t)hal_get_cycles(); 801 855 if( cycle > DEBUG_VFS_USER_MOVE ) 802 856 { 803 857 if( to_buffer ) 804 printk("\n[%s] thread[%x,%x] moves %d bytes from <%s> mapper to buffer(%x) / cycle %d\n",805 __FUNCTION__ , this->process->pid, this->trdid, size, name, buffer );858 printk("\n[%s] thread[%x,%x] exit / %d bytes / mapper(%s) -> buffer(%x) / cycle %d\n", 859 __FUNCTION__ , this->process->pid, this->trdid, size, name, buffer, cycle ); 806 860 else 807 printk("\n[%s] thread[%x,%x] moves %d bytes from buffer (%x) to <%s> mapper/ cycle %d\n",808 __FUNCTION__ , this->process->pid, this->trdid, size, buffer, name );861 printk("\n[%s] thread[%x,%x] exit / %d bytes / buffer(%x) -> mapper(%s) / cycle %d\n", 862 __FUNCTION__ , this->process->pid, this->trdid, size, buffer, name, cycle ); 809 863 } 810 864 #endif … … 1794 1848 xptr_t inode_children_xp = XPTR( inode_cxy , &inode_ptr->children.items ); 1795 1849 1796 printk("\n@@@ in %s : children_xp = (%x,%x)\n",1797 __FUNCTION__, inode_cxy, &inode_ptr->children.items );1798 1799 1850 // get target inode number of children 1800 1851 inode_children = hal_remote_l32( inode_children_xp ); … … 2166 2217 2167 2218 // display inode 2168 nolock_printk("%s<%s> : %s / extd % d/ %d bytes / dirty %d / cxy %x / inode %x / mapper %x\n",2219 nolock_printk("%s<%s> : %s / extd %x / %d bytes / dirty %d / cxy %x / inode %x / mapper %x\n", 2169 2220 indent_str[indent], name, vfs_inode_type_str( inode_type ), (uint32_t)inode_extd, 2170 2221 inode_size, inode_dirty, inode_cxy, inode_ptr, mapper_ptr ); … … 2301 2352 // This static function is used by the vfs_lookup() function. 2302 2353 // It takes an extended pointer on a remote parent directory inode, a directory 2303 // entry name, and returns an extended pointer on the child inode. 2354 // entry name, and and scan the XHTAB associated to the parent inode to find the 2355 // searched dentry. It does NOT modify the inode tree in case of miss. 2304 2356 // It can be used by any thread running in any cluster. 2305 2357 ////////////////////////////////////////////////////////////////////////////////////////// … … 2424 2476 bool_t create; // searched inode must be created if not found 2425 2477 bool_t excl; // searched inode must not exist 2426 bool_t par ;// searched inode is the parent2478 bool_t parent; // searched inode is the parent 2427 2479 thread_t * this; // pointer on calling thread descriptor 2428 2480 process_t * process; // pointer on calling process descriptor … … 2449 2501 create = (lookup_mode & VFS_LOOKUP_CREATE) == VFS_LOOKUP_CREATE; 2450 2502 excl = (lookup_mode & VFS_LOOKUP_EXCL) == VFS_LOOKUP_EXCL; 2451 par 2503 parent = (lookup_mode & VFS_LOOKUP_PARENT) == VFS_LOOKUP_PARENT; 2452 2504 2453 2505 // initialise loop variables … … 2499 2551 child_cxy = GET_CXY( child_xp ); 2500 2552 2501 // analyse found & last, depending on lookup_mode2502 2553 if( found == false ) // not found in Inode Tree 2503 2554 { 2504 2555 // when a inode is not found in the Inode Tree: 2505 // - if (last and par ) the Inode Tree is not modified2556 // - if (last and parent) the Inode Tree is not modified 2506 2557 // - else we speculatively introduce a new (dentry/inode) in inode tree, 2507 2558 // and scan the parent directory mapper to initialise it. … … 2514 2565 // - if the child is a directory, the child mapper is loaded from device 2515 2566 2516 if( last && par ) // does nothing2567 if( last && parent ) // does nothing 2517 2568 { 2518 2569 … … 2577 2628 } 2578 2629 2579 if ( error ) // child not found in parent mapper 2630 // when the missing dentry is not in the parent mapper, 2631 // it is a new dentry that must be registered in parent directory mapper 2632 if ( error ) 2580 2633 { 2581 2634 if ( last && create ) // add a brand new dentry in parent directory … … 2594 2647 #if (DEBUG_VFS_LOOKUP & 1) 2595 2648 if( DEBUG_VFS_LOOKUP < cycle ) 2596 printk("\n[%s] thread[%x,%x] child <%s> not found in parent mapper => create it\n",2649 printk("\n[%s] thread[%x,%x] child <%s> not found in parent mapper => created it\n", 2597 2650 __FUNCTION__, process->pid, this->trdid, name ); 2598 #endif 2651 vfs_inode_display( child_xp ); 2652 #endif 2653 2654 2599 2655 } 2600 2656 else // not last or not create => error … … 2687 2743 if ( last ) // last inode in path => return relevant info 2688 2744 { 2689 if ( par ) // return parent inode and child name2745 if ( parent ) // return parent inode and child name 2690 2746 { 2691 2747 … … 2757 2813 vfs_inode_t * child_ptr = GET_PTR( child_xp ); 2758 2814 2759 // 1. allocate one free cluster to child inode 2760 // depending on the child inode FS type 2815 // 1. allocate one free cluster in file system to child inode, 2816 // and update the File Allocation Table in both the TAF mapper and IOC device. 2817 // It depends on the child inode FS type. 2761 2818 vfs_ctx_t * ctx = hal_remote_lpt( XPTR( child_cxy , &child_ptr->ctx ) ); 2762 2819 … … 2772 2829 #if( DEBUG_VFS_NEW_DENTRY_INIT & 1) 2773 2830 if( DEBUG_VFS_NEW_DENTRY_INIT < cycle ) 2774 printk("\n[%s] thread[%x,%x] allocated F ATcluster %x to <%s>\n",2831 printk("\n[%s] thread[%x,%x] allocated FS cluster %x to <%s>\n", 2775 2832 __FUNCTION__ , this->process->pid, this->trdid, cluster, child_name ); 2776 2833 #endif 2777 2834 2778 // 2. update the child inode descriptor 2835 // 2. update the child inode descriptor size and extend 2779 2836 child_type = hal_remote_l32( XPTR( child_cxy , &child_ptr->type ) ); 2780 2837 child_size = (child_type == INODE_TYPE_DIR) ? 4096 : 0; … … 3301 3358 #endif 3302 3359 3303 // register new_dentry in parent_inode xhtab of children3360 // 4. register new_dentry in parent_inode xhtab of children 3304 3361 children_xhtab_xp = XPTR( parent_cxy , &parent_inode_ptr->children ); 3305 3362 children_entry_xp = XPTR( parent_cxy , &new_dentry_ptr->children ); … … 3313 3370 #endif 3314 3371 3315 // update "parent" and "child_xp" fields in new_dentry3372 // 5. update "parent" and "child_xp" fields in new_dentry 3316 3373 hal_remote_s64( XPTR( parent_cxy , &new_dentry_ptr->child_xp ) , new_inode_xp ); 3317 3374 hal_remote_spt( XPTR( parent_cxy , &new_dentry_ptr->parent ) , parent_inode_ptr ); -
trunk/kernel/fs/vfs.h
r625 r626 376 376 * argument to a local buffer identified by the <name> argument. 377 377 * The local buffer size must be at least CONFIG_VFS_MAX_NAME_LENGTH. 378 ***************************************************************************************** 378 ****************************************************************************************** 379 379 * @ inode_xp : extended pointer on the remote inode. 380 380 * @ name : local buffer pointer. … … 396 396 error_t vfs_inode_load_all_pages( vfs_inode_t * inode ); 397 397 398 398 /****************************************************************************************** 399 * This debug function display the curren state of an inode descriptor identified by 400 * the <inode_xp> argument. 401 *****************************************************************************************/ 402 void vfs_inode_display( xptr_t inode_xp ); 399 403 400 404 /****************************************************************************************** … … 547 551 * It can be executed by any thread running in any cluster (can be different from both 548 552 * the child cluster and the parent cluster). 549 * 550 * [Implementation ]553 * The new child inode and the parent inode can have different FS types. 554 * [Implementation note] 551 555 * As there are cross-references between inode and dentry, this function implements 552 * a three steps scenario :556 * a five steps scenario : 553 557 * 1) The dentry descriptor is created in the cluster containing the existing <parent_xp> 554 558 * inode, and partially initialized, using the RPC_VFS_CREATE DENTRY if required. 555 559 * 2) The inode and its associated mapper are created in cluster identified by <child_cxy>, 556 560 * and partially initialised, using the RPC_VFS_CREATE_INODE if required. 557 * The new inode and the parent inode can have different FS types.558 * 3) The pointers between the parent inode, the new dentry, and the child inode559 * are updated, using remote accesses.560 ***************************************************************************************** *561 * 3) The pointers on dentry in parent inode are updated, using remote access. 562 * 4) The pointers on dentry in child inode are updated, using remotes access. 563 * 5) The pointers on parent and child inode in dentry are updated, using remotes access. 564 ***************************************************************************************** 561 565 * @ child_inode_cxy : [in] target cluster for child inode. 562 566 * @ fs_type : [in] child inode FS type. … … 591 595 592 596 /****************************************************************************************** 593 * This function is called by the vfs_lookup() function when a new dentry/inodemust594 * be created from scratch and introduced in both the Inode Treeand the IOC device.595 * The dentry and inode descriptors have beencreated by the caller.596 * - It allocates one cluster from the relevant FS, and updates the File Allocation597 * Table (both the FAT mapper, andthe IOC device).598 * -It set the "size", and "extend" fields in child inode descriptor.599 * - It updates the parent directory to introduce the new child in the parent directory600 * inode descriptor (radix tree), in theparent inode mapper, and onIOC device.601 * -It set the "extend" field in dentry descriptor.597 * This function is called by the vfs_lookup() function when a new (dentry/inode) must 598 * be created from scratch and introduced in both the parent mapper and the IOC device. 599 * The dentry and inode descriptors must have been previously created by the caller. 600 * 1. It allocates one cluster from the relevant FS, updates the FAT mapper, 601 * and synchronously update the IOC device). 602 * 2. It set the "size", and "extend" fields in child inode descriptor. 603 * 3. It updates the parent directory mapper to introduce the new child, 604 * and synchronously update the IOC device. 605 * 4. It set the "extend" field in dentry descriptor. 602 606 * It can be called by a thread running in any cluster. 603 607 ******************************************************************************************
Note: See TracChangeset
for help on using the changeset viewer.