Changeset 657 for trunk/kernel/fs
- Timestamp:
- Mar 18, 2020, 11:16:59 PM (5 years ago)
- Location:
- trunk/kernel/fs
- Files:
-
- 7 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/kernel/fs/devfs.c
r637 r657 3 3 * 4 4 * Author Mohamed Lamine Karaoui (2014,2015) 5 * Alain Greiner (2016,2017,2018,2019 )5 * Alain Greiner (2016,2017,2018,2019,2020) 6 6 * 7 7 * Copyright (c) Sorbonne Universites … … 53 53 #endif 54 54 55 /////////////////////////////////// //56 devfs_ctx_t * devfs_ctx_alloc( void)55 /////////////////////////////////// 56 xptr_t devfs_ctx_alloc( cxy_t cxy ) 57 57 { 58 58 kmem_req_t req; … … 62 62 req.flags = AF_KERNEL | AF_ZERO; 63 63 64 return kmem_alloc( &req ); 64 // allocates devfs context from target cluster 65 return XPTR( cxy , kmem_remote_alloc( cxy , &req ) ); 65 66 } 66 67 67 68 ///////////////////////////////////////////// 68 void devfs_ctx_init( devfs_ctx_t * devfs_ctx,69 xptr_t 70 xptr_t 69 void devfs_ctx_init( xptr_t devfs_ctx_xp, 70 xptr_t devfs_dev_inode_xp, 71 xptr_t devfs_external_inode_xp ) 71 72 { 72 devfs_ctx->dev_inode_xp = devfs_dev_inode_xp; 73 devfs_ctx->external_inode_xp = devfs_external_inode_xp; 74 75 fs_context[FS_TYPE_DEVFS].extend = devfs_ctx; 73 // get cluster and local pointer on remote devfs context 74 devfs_ctx_t * devfs_ctx_ptr = GET_PTR( devfs_ctx_xp ); 75 cxy_t devfs_ctx_cxy = GET_CXY( devfs_ctx_xp ); 76 77 // set values in remote devfs context 78 hal_remote_s64( XPTR( devfs_ctx_cxy , &devfs_ctx_ptr->dev_inode_xp ), 79 devfs_dev_inode_xp ); 80 81 hal_remote_s64( XPTR( devfs_ctx_cxy , &devfs_ctx_ptr->external_inode_xp ), 82 devfs_external_inode_xp ); 83 84 // register devfs context in the remote fs_context array[] 85 hal_remote_spt( XPTR( devfs_ctx_cxy , &fs_context[FS_TYPE_DEVFS].extend ), 86 devfs_ctx_ptr ); 76 87 } 77 88 78 ////////////////////////////////////////////// ///79 void devfs_ctx_destroy( devfs_ctx_t * devfs_ctx)89 ////////////////////////////////////////////// 90 void devfs_ctx_destroy( xptr_t devfs_ctx_xp ) 80 91 { 81 92 kmem_req_t req; 82 93 94 // get cluster and local pointer on devfs context 95 devfs_ctx_t * devfs_ctx_ptr = GET_PTR( devfs_ctx_xp ); 96 cxy_t devfs_ctx_cxy = GET_CXY( devfs_ctx_xp ); 97 83 98 req.type = KMEM_KCM; 84 req.ptr = devfs_ctx; 85 kmem_free( &req ); 99 req.ptr = devfs_ctx_ptr; 100 101 // release devfs context descriptor to remote cluster 102 kmem_remote_free( devfs_ctx_cxy , &req ); 86 103 } 87 104 … … 95 112 vfs_inode_t * inode; 96 113 114 // get 115 97 116 // create DEVFS "dev" inode in cluster 0 98 117 error = vfs_add_child_in_parent( 0, // cxy … … 158 177 /////////////////////////////////////////////////// 159 178 void devfs_local_init( xptr_t devfs_dev_inode_xp, 160 xptr_t devfs_external_inode_xp, 161 xptr_t * devfs_internal_inode_xp ) 179 xptr_t devfs_external_inode_xp ) 162 180 { 181 xptr_t internal_inode_xp; // extended pointer on <internal> inode 182 vfs_inode_t * internal_inode_ptr; // local pointer on <internal> inode 163 183 char node_name[16]; 164 184 xptr_t chdev_xp; … … 168 188 vfs_inode_t * inode_ptr; 169 189 uint32_t channel; 170 xptr_t unused_xp; // required by add_child_in_parent()190 xptr_t unused_xp; // required by add_child_in_parent() 171 191 error_t error; 192 172 193 173 194 #if DEBUG_DEVFS_LOCAL_INIT … … 179 200 #endif 180 201 181 // create "internal"directory202 // create <internal> directory 182 203 snprintf( node_name , 16 , "internal_%x" , local_cxy ); 183 204 184 error = vfs_add_child_in_parent( local_cxy, 185 FS_TYPE_DEVFS, 186 devfs_dev_inode_xp, 187 node_name, 205 error = vfs_add_child_in_parent( local_cxy, // target cluster 206 FS_TYPE_DEVFS, // FS type 207 devfs_dev_inode_xp, // parent inode 208 node_name, // child name 188 209 &unused_xp, 189 devfs_internal_inode_xp );190 191 // set inode "type" field192 in ode_ptr = GET_PTR( *devfs_internal_inode_xp );193 in ode_ptr->type = INODE_TYPE_DEV;210 &internal_inode_xp ); // child inode 211 212 // set <internal> inode "type" field 213 internal_inode_ptr = GET_PTR( internal_inode_xp ); 214 internal_inode_ptr->type = INODE_TYPE_DEV; 194 215 195 216 // create dentries <.> and <..> in <internal> 196 error |= vfs_add_special_dentries( *devfs_internal_inode_xp,217 error |= vfs_add_special_dentries( internal_inode_xp, 197 218 devfs_dev_inode_xp ); 198 219 … … 226 247 error = vfs_add_child_in_parent( local_cxy, 227 248 FS_TYPE_DEVFS, 228 *devfs_internal_inode_xp,249 internal_inode_xp, 229 250 chdev_ptr->name, 230 251 &unused_xp, … … 270 291 error = vfs_add_child_in_parent( local_cxy, 271 292 FS_TYPE_DEVFS, 272 *devfs_internal_inode_xp,293 internal_inode_xp, 273 294 chdev_ptr->name, 274 295 &unused_xp, -
trunk/kernel/fs/devfs.h
r612 r657 3 3 * 4 4 * Authors Mohamed Lamine Karaoui (2014,2015) 5 * Alain Greiner (2016,2017 )5 * Alain Greiner (2016,2017,2018,2019,2020) 6 6 * 7 7 * Copyright (c) 2011,2012 UPMC Sorbonne Universites … … 26 26 #define _DEVFS_H_ 27 27 28 28 29 ////////////////////////////////////////////////////////////////////////////////////////// 29 // The DEVFS File System contains inodes and dentries associated to all chdev descriptors30 // availablesin the architecture.30 // The DEVFS File System contains the inodes and dentries associated to the chdev 31 // descriptors available in the architecture. 31 32 // 32 33 // It is structured as a three levels tree structure : … … 41 42 // 42 43 // The DEVFS extensions to the generic VFS are the following: 43 // 1) The vfs_ctx_t "extend" void* field is pointing on the devfs_ctx_t structure. 44 // This structure contains two extended pointers on the DEVFS "dev" directory inode, 45 // and on the "external" directory inode. 46 // 2) The vfs_inode_t "extend" void* field is pointing on the chdev descriptor. 44 // 1) The vfs_ctx_t "extend" field is pointing on the devfs_ctx_t structure. 45 // 2) The vfs_inode_t "extend" field is pointing on the chdev descriptor. 47 46 ////////////////////////////////////////////////////////////////////////////////////////// 48 47 … … 57 56 } 58 57 devfs_ctx_t; 59 60 61 58 /***************************************************************************************** 62 * This fuction allocates memory from local cluster for a DEVFS context descriptor. 59 * This fuction allocates memory for a DEVFS context descriptor in cluster identified 60 * by the <cxy> argument. 63 61 ***************************************************************************************** 64 * @ return a pointer on the created context / return NULL if failure. 62 * @ cxy : [in] target cluster identifier. 63 * @ return an extended pointer on the created context / return NULL if failure. 65 64 ****************************************************************************************/ 66 devfs_ctx_t * devfs_ctx_alloc( void);65 xptr_t devfs_ctx_alloc( cxy_t cxy ); 67 66 68 67 /***************************************************************************************** … … 70 69 * to the relevant VFS context in the local cluster. 71 70 ***************************************************************************************** 72 * @ devfs_ctx : localpointer on DEVFS context.71 * @ devfs_ctx : [in] extended pointer on DEVFS context. 73 72 * @ devfs_dev_inode_xp : [out] extended pointer on <dev> inode. 74 73 * @ devfs_external_inode_xp : [out] extended pointer on <external> inode. 75 74 ****************************************************************************************/ 76 void devfs_ctx_init( devfs_ctx_t * devfs_ctx,77 xptr_t 78 xptr_t 75 void devfs_ctx_init( xptr_t devfs_ctx_xp, 76 xptr_t devfs_dev_inode_xp, 77 xptr_t devfs_external_inode_xp ); 79 78 80 79 /***************************************************************************************** … … 83 82 * @ devfs_ctx : local pointer on DEVFS context. 84 83 ****************************************************************************************/ 85 void devfs_ctx_destroy( devfs_ctx_t * devfs_ctx);84 void devfs_ctx_destroy( xptr_t devfs_ctx_xp ); 86 85 87 86 /***************************************************************************************** 88 * This function start to create the DEVFS subtree. 89 * This function should be called once in the cluster containing the VFS parent inode. 90 * More precisely, it creates in cluster 0 the "dev" and "external" DEVFS directories. 91 * For each one, it creates the inode and link the associated dentry to parent inode. 92 * The DEVFS root inode is linked to the VFS parent inode identified by <parent_inode_xp>. 87 * This function starts to create the DEVFS subtree. 88 * This function creates in cluster 0 the "dev" and "external" DEVFS directories. 89 * For each one, it creates the inode and the associated dentry. The DEVFS root inode 90 * <dev is linked to the VFS parent inode identified by <parent_inode_xp>. 93 91 ***************************************************************************************** 94 * @ parent_inode_xp : extended pointer on the parent VFS inode.92 * @ parent_inode_xp : [in] extended pointer on the parent VFS inode. 95 93 * @ devfs_dev_inode_xp : [out] extended pointer on created <dev> inode. 96 94 * @ devfs_external_inode_xp : [out] extended pointer on created <external> inode. … … 105 103 * 1. In each cluster (i), it creates the "internal" directory, 106 104 * linked to the DEVFS "dev" parent directory. 107 * 2. In each cluster (i), it creates - for each external chdev in cluster (i) -105 * 2. In each cluster (i), it creates, for each external chdev in cluster (i), 108 106 * a pseudo-file, linked to the DEVFS "external" parent directory. 109 * 3. In each cluster (i), it creates - for each internal chdev in cluster (i) -107 * 3. In each cluster (i), it creates, for each internal chdev in cluster (i), 110 108 * a pseudo-file, linked to the DEVFS "internal" parent directory. 111 109 ***************************************************************************************** 112 * @ devfs_dev_inode_xp : extended pointer on DEVFS root inode. 113 * @ devfs_external_inode_xp : extended pointer on DEVFS external inode. 114 * @ devfs_internal_inode_xp : [out] extended pointer on created <internal> inode. 110 * @ devfs_dev_inode_xp : [in] extended pointer on DEVFS root inode. 111 * @ devfs_external_inode_xp : [in] extended pointer on DEVFS external inode. 115 112 ****************************************************************************************/ 116 113 void devfs_local_init( xptr_t devfs_dev_inode_xp, 117 xptr_t devfs_external_inode_xp, 118 xptr_t * devfs_internal_inode_xp ); 114 xptr_t devfs_external_inode_xp ); 119 115 120 116 /****************************************************************************************** -
trunk/kernel/fs/fatfs.c
r656 r657 2 2 * fatfs.c - FATFS file system API implementation. 3 3 * 4 * Author Alain Greiner (2016,2017,2018,2019 )4 * Author Alain Greiner (2016,2017,2018,2019,2020) 5 5 * 6 6 * Copyright (c) UPMC Sorbonne Universites … … 122 122 for( i = nbytes ; i > 0 ; i-- ) 123 123 { 124 res = (res<<8) | hal_remote_lb( buffer_xp +offset+i-1 );124 res = (res<<8) | hal_remote_lb( buffer_xp + offset + i-1 ); 125 125 } 126 126 } … … 129 129 for( i = 0 ; i < nbytes ; i++ ) 130 130 { 131 res = (res<<8) | hal_remote_lb( buffer_xp +offset+i );131 res = (res<<8) | hal_remote_lb( buffer_xp + offset + i ); 132 132 } 133 133 } … … 135 135 136 136 } // end fatfs_get_remote_record() 137 138 /* 137 139 138 140 ////////////////////////////////////////////////////////////////////////////////////////// … … 164 166 } // end fatfs_set_record() 165 167 168 */ 169 166 170 ////////////////////////////////////////////////////////////////////////////////////////// 167 171 // This function writes one, two, or four bytes from a 32 bits integer to a remote … … 185 189 for( i = nbytes ; i > 0 ; i-- ) 186 190 { 187 hal_remote_sb( (buffer_xp +offset+i-1) , (uint8_t)(value>>((i-1)<<3)) );191 hal_remote_sb( (buffer_xp + offset + i-1 ) , (uint8_t)(value>>((i-1)<<3)) ); 188 192 } 189 193 } … … 192 196 for( i = 0 ; i < nbytes ; i++ ) 193 197 { 194 hal_remote_sb( (buffer_xp +offset+i) , (uint8_t)(value>>((nbytes-1-i)<<3)) );198 hal_remote_sb( (buffer_xp + offset + i) , (uint8_t)(value>>((nbytes-1-i)<<3)) ); 195 199 } 196 200 } … … 470 474 cxy_t fat_cxy; // FAT cluster identifier 471 475 fatfs_ctx_t * fatfs_ctx; // local pointer on FATFS context in FAT cluster 472 xptr_t fat_mapper_xp; // extended pointer on FAT mapper473 476 mapper_t * fat_mapper_ptr; // local pointer on FAT mapper 474 477 uint32_t page_id; // current page index in FAT mapper … … 482 485 fatfs_ctx = GET_PTR( fatfs_ctx_xp ); 483 486 484 // get FAT mapper pointers from FATFS context 485 fat_mapper_xp = hal_remote_l64( XPTR( fat_cxy , &fatfs_ctx->fat_mapper_xp ) ); 486 fat_mapper_ptr = GET_PTR( fat_mapper_xp ); 487 488 // check FAT cluster 489 assert( (fat_cxy == GET_CXY( fat_mapper_xp )) , "unconsistent FAT cluster" ); 487 // get FAT mapper pointer from FATFS context 488 fat_mapper_ptr = hal_remote_lpt( XPTR( fat_cxy , &fatfs_ctx->fat_mapper ) ); 490 489 491 490 // build extended pointer on FAT mapper radix tree … … 575 574 576 575 // update the FS_INFO sector on IOC device 577 return dev_ioc_ move_data( IOC_SYNC_WRITE ,fs_info_buffer_xp , fs_info_lba , 1 );576 return dev_ioc_sync_write( fs_info_buffer_xp , fs_info_lba , 1 ); 578 577 579 578 } // end fatfs_update_ioc_fsinfo() … … 581 580 ////////////////////////////////////////////////////////////////////////////////////////// 582 581 // This static function decrements the "free_clusters" variable, and updates the 583 // "free_cluster_hint" variable in the FATFS context in FAT cluster, identified 584 // by the <fat_ctx_xp> argument, when a new <cluster> has been allocated from FAT. 582 // "free_cluster_hint" variable in the FATFS context in FAT cluster, when a new 583 // <cluster_id> has been allocated from the FAT. 584 // It synchronously updates the FS_INFO sector on the IOC device. 585 // The FATFS context in FAT cluster is identified by the <fat_ctx_xp> argument. 586 // It can be called by a thead running in any cluster. 585 587 // It scan all slots in the FAT mapper seen as an array of 32 bits words, looking for the 586 // first free slot larger than the <cluster> argument, to update "free_cluster_hint". 587 // It synchronously updates the FS_INFO sector on the IOC device. 588 // It can be called by a thead running in any cluster. 588 // first free slot larger than the <cluster_id>. 589 589 // The lock protecting exclusive access to the FAT must be taken by the calling function. 590 590 ////////////////////////////////////////////////////////////////////////////////////////// 591 591 // @ fatfs_ctx_xp : extended pointer on FATFS context in FAT cluster. 592 // @ cluster 592 // @ cluster_id : recently allocated cluster index in FAT. 593 593 // @ return 0 if success, return -1 if the FS_INFO sector cannot be updated. 594 594 ////////////////////////////////////////////////////////////////////////////////////////// 595 595 static error_t fatfs_free_clusters_decrement( xptr_t fatfs_ctx_xp, 596 uint32_t cluster )596 uint32_t cluster_id ) 597 597 { 598 598 error_t error; 599 cxy_t fat_cxy; // FAT cluster identifier600 fatfs_ctx_t * fat_ctx_ptr; // local pointer on fatfs context in FAT cluster601 xptr_t fat_mapper_xp; // extendedpointer on FAT mapper602 xptr_t hint_xp; // extended pointer on "free_cluster_hint" shared variable603 xptr_t numb_xp; // extended pointer on "free_clusters" shared variable604 uint32_t numb; // "free_clusters" variable current value605 uint32_t hint; // "free_cluster_hint" variable current value606 uint32_t page_id; // page index in FAT mapper607 uint32_t slot_id; // slot index in one page of FAT (1024 slots per page)608 uint32_t page_max; // max number of pagesin FAT mapper609 xptr_t page_xp; // extended pointer on current page in FAT mapper610 xptr_t base_xp; // extended pointer on current page base611 xptr_t slot_xp; // extended pointer on current slot in FAT mapper599 cxy_t fat_cxy; // FAT cluster identifier 600 fatfs_ctx_t * fat_ctx_ptr; // local pointer on fatfs context in FAT cluster 601 mapper_t * fat_mapper_ptr; // local pointer on FAT mapper 602 xptr_t fat_mapper_xp; // extended pointer on FAT mapper 603 xptr_t hint_xp; // extended pointer on "free_cluster_hint" shared variable 604 xptr_t numb_xp; // extended pointer on "free_clusters" shared variable 605 uint32_t page_id; // page index in FAT mapper 606 uint32_t slot_id; // slot index in one page of FAT (1024 slots per page) 607 uint32_t page_max; // max number of pages in FAT mapper 608 xptr_t page_xp; // extended pointer on current page in FAT mapper 609 xptr_t base_xp; // extended pointer on current page base 610 xptr_t slot_xp; // extended pointer on current slot in FAT mapper 611 uint32_t found; // free slot found when non zero 612 612 613 613 #if DEBUG_FATFS_FREE_CLUSTERS … … 615 615 thread_t * this = CURRENT_THREAD; 616 616 if( DEBUG_FATFS_FREE_CLUSTERS < cycle ) 617 printk("\n[%s] thread[%x,%x] enter for allocated cluster %x / cycle %d\n",618 __FUNCTION__, this->process->pid, this->trdid, cluster , cycle );617 printk("\n[%s] thread[%x,%x] enter for allocated cluster_id %x / cycle %d\n", 618 __FUNCTION__, this->process->pid, this->trdid, cluster_id , cycle ); 619 619 #endif 620 620 … … 627 627 numb_xp = XPTR( fat_cxy , &fat_ctx_ptr->free_clusters ); 628 628 629 // update "free_clusters" value 630 numb = hal_remote_l32( numb_xp ) - 1; 631 hal_remote_s32( numb_xp , numb ); 632 633 // get extended pointer on FAT mapper 634 fat_mapper_xp = hal_remote_l64( XPTR( fat_cxy , &fat_ctx_ptr->fat_mapper_xp ) ); 635 636 // initialise variables to scan the FAT mapper 637 // and find the first free slot > cluster 638 page_id = (cluster + 1) >> 10; 639 slot_id = (cluster + 1) & 0x3FF; 629 // get pointers on FAT mapper from FATFS context 630 fat_mapper_ptr = hal_remote_lpt( XPTR( fat_cxy , &fat_ctx_ptr->fat_mapper ) ); 631 fat_mapper_xp = XPTR( fat_cxy , fat_mapper_ptr ); 632 633 // initialise the loop variables to scan the FAT mapper 634 page_id = (cluster_id + 1) >> 10; 635 slot_id = (cluster_id + 1) & 0x3FF; 640 636 page_max = hal_remote_l32( XPTR( fat_cxy, &fat_ctx_ptr->fat_sectors_count ) ) >> 3; 641 642 // scan FAT mapper / loop on pages 643 while ( page_id < page_max ) 637 found = 0; 638 639 // scan FAT mapper : first loop on pages 640 while ( (page_id < page_max) && (found == 0) ) 644 641 { 645 642 // get current page from mapper 646 page_xp = mapper_ remote_get_page( fat_mapper_xp , page_id );643 page_xp = mapper_get_fat_page( fat_mapper_xp , page_id ); 647 644 648 645 if( page_xp == XPTR_NULL ) … … 655 652 base_xp = ppm_page2base( page_xp ); 656 653 657 // scan FAT mapper /loop on slots658 while ( slot_id < 1024)654 // scan the FAT mapper : second loop on slots 655 while ( (slot_id < 1024) && (found == 0) ) 659 656 { 660 657 // get extended pointer on current slot … … 664 661 if ( hal_remote_l32( slot_xp ) == FREE_CLUSTER ) 665 662 { 666 // update "free_cluster_hint" value 667 hint = (page_id << 10) + slot_id - 1; 668 hal_remote_s32( hint_xp , hint ); 669 670 // update FS_INFO sector on IOC device 671 error = fatfs_update_ioc_fat( fatfs_ctx_xp, 672 page_id, 673 page_id ); 674 675 if( error ) 676 { 677 printk("\n[ERROR] in %s : cannot update FS_INFO on IOC\n", __FUNCTION__ ); 678 return -1; 679 } 663 // exit both loops 664 found = 1; 665 } 666 else 667 { 668 // update slot_id if not found 669 slot_id++; 670 } 671 } // end loop on slots 672 673 // update page_id & slot_id variables if not found 674 if( found == 0 ) 675 { 676 page_id++; 677 slot_id = 0; 678 } 679 } // end loop on pages 680 681 if( found ) // free cluster found 682 { 683 // update "free_clusters" and "free_cluster_hint" value in FATFS context 684 hal_remote_atomic_add( numb_xp , -1 ); 685 hal_remote_s32( hint_xp , (page_id << 10) + slot_id - 1 ); 686 687 // update FS_INFO sector on IOC device 688 error = fatfs_update_ioc_fsinfo( fatfs_ctx_xp ); 689 690 if( error ) 691 { 692 printk("\n[ERROR] in %s : cannot update FS_INFO on IOC\n", __FUNCTION__ ); 693 return -1; 694 } 680 695 681 696 #if DEBUG_FATFS_FREE_CLUSTERS 682 cycle = (uint32_t)hal_get_cycles(); 683 if( DEBUG_FATFS_FREE_CLUSTERS < (uint32_t)hal_get_cycles() ) 684 printk("\n[%s] thread[%x,%x] exit / hint %x / free %x / cycle %d\n", 697 if( DEBUG_FATFS_FREE_CLUSTERS < cycle ) 698 printk("\n[%s] thread[%x,%x] exit / hint %x / free %x\n", 685 699 __FUNCTION__, this->process->pid, this->trdid, 686 hal_remote_l32(hint_xp), hal_remote_l32(numb_xp), cycle ); 687 #endif 688 return 0; 689 } 690 691 // update slot_id 692 slot_id = 0; 693 694 } // end loop on slots 695 696 // update page_id & slot_id variables 697 page_id++; 698 slot_id = 0; 699 700 } // end loop on pages 701 702 // return error if no free cluster found 703 printk("\n[ERROR] in %s : No free cluster found\n", __FUNCTION__ ); 704 return -1; 700 hal_remote_l32(hint_xp), hal_remote_l32(numb_xp) ); 701 #endif 702 return 0; 703 } 704 else // free cluster not found 705 { 706 printk("\n[ERROR] in %s : No free cluster_id found\n", __FUNCTION__ ); 707 return -1; 708 } 705 709 706 710 } // end fatfs_free_clusters_decrement() … … 709 713 // This static function increments the "free_clusters" variable, and updates the 710 714 // "free_cluster_hint" variables in the FATFS context in FAT cluster, identified 711 // by the <fat_ctx_xp> argument, when a FATFS cluster isreleased.715 // by the <fat_ctx_xp> argument, when a FATFS <cluster_id> has been released. 712 716 // If the released cluster index is smaller than the current (hint) value, 713 717 // it set "free_cluster_hint" <= cluster. 714 // It does NOT update the FS_INFO sector on the IOC device. 718 // It does NOT update the FS_INFO sector on the IOC device, as this is done by the 719 // calling fatfs_release_inode() function. 715 720 // It can be called by a thead running in any cluster. 716 721 // The lock protecting exclusive access to the FAT must be taken by the calling function. 717 722 ////////////////////////////////////////////////////////////////////////////////////////// 718 723 // @ fatfs_ctx_xp : extended pointer on FATFS context in FAT cluster. 719 // @ cluster 724 // @ cluster_id : recently released cluster index in FAT. 720 725 // @ return 0 if success, return -1 if the FS_INFO sector cannot be updated. 721 726 ////////////////////////////////////////////////////////////////////////////////////////// 722 727 static error_t fatfs_free_clusters_increment( xptr_t fatfs_ctx_xp, 723 uint32_t cluster ) 724 { 725 error_t error; 728 uint32_t cluster_id ) 729 { 726 730 cxy_t fat_cxy; // FAT cluster identifier 727 731 fatfs_ctx_t * fat_ctx_ptr; // local pointer on fatfs context in FAT cluster … … 735 739 thread_t * this = CURRENT_THREAD; 736 740 if( DEBUG_FATFS_FREE_CLUSTERS < cycle ) 737 printk("\n[%s] thread[%x,%x] enter for released cluster %x / cycle %d\n",738 __FUNCTION__, this->process->pid, this->trdid, cluster , cycle );741 printk("\n[%s] thread[%x,%x] enter for released cluster_id %x / cycle %d\n", 742 __FUNCTION__, this->process->pid, this->trdid, cluster_id , cycle ); 739 743 #endif 740 744 … … 753 757 // update "numb" and "hint" variables as required 754 758 numb++; 755 if ( (cluster - 1) < hint ) hint = cluster- 1;759 if ( (cluster_id - 1) < hint ) hint = cluster_id - 1; 756 760 757 761 // update free_clusters … … 759 763 hal_remote_s32( hint_xp , hint ); 760 764 761 // update FS_INFO sector on IOC device762 error = fatfs_update_ioc_fsinfo( fatfs_ctx_xp );763 764 if( error )765 {766 printk("\n[ERROR] in %s : cannot update FS_INFO on IOC\n", __FUNCTION__ );767 return -1;768 }769 770 765 #if DEBUG_FATFS_FREE_CLUSTERS 771 cycle = (uint32_t)hal_get_cycles(); 772 if( DEBUG_FATFS_FREE_CLUSTERS < (uint32_t)hal_get_cycles() ) 773 printk("\n[%s] thread[%x,%x] exit / hint %x / free %x / cycle %d\n", 766 if( DEBUG_FATFS_FREE_CLUSTERS < cycle ) 767 printk("\n[%s] thread[%x,%x] exit / hint %x / free %x\n", 774 768 __FUNCTION__, this->process->pid, this->trdid, 775 hal_remote_l32( hint_xp ), hal_remote_l32( numb_xp ) , cycle);769 hal_remote_l32( hint_xp ), hal_remote_l32( numb_xp ) ); 776 770 #endif 777 771 … … 853 847 854 848 ////////////////////////////////////////////////////////////////////////////////////////// 849 // This static function access the FAT mapper to allocate a new cluster in the FATFS, 850 // and returns in <searched_cluster_id> the FATFS cluster index of a free cluster. 851 // It updates the FAT mapper (handling miss from IOC device if required) : 852 // - if the <last_cluster_id> is zero, the new cluster is the first allocated cluster, 853 // and the <searched_cluster_id> FAT slot is set to END_OF_CHAIN_CLUSTER. 854 // - if the <last_cluster_id> argument is not zero, the new cluster is not the first, 855 // the <last_cluster_id> FAT slot is set to <searched_cluster_id>, 856 // the <searched_cluster_id> FAT slot is set to END_OF_CHAIN_CLUSTER. 857 // This function also updates the two "free_cluster_hint" and "free_clusters" variables 858 // stored in the FATFS context. It takes the rwlock stored in the FATFS context in the 859 // FAT cluster to get exclusive access to the FAT. 860 // This function synchronously updates the FAT region on IOC device. 861 // It can be called by a thread running in any cluster as it uses remote accesses. 862 ////////////////////////////////////////////////////////////////////////////////////////// 863 // @ last_cluster_id : [in] previous last cluster index. 864 // @ searched_cluster_id : [out] allocated cluster index. 865 // @ return 0 if success / return -1 if no more free clusters on IOC device. 866 ////////////////////////////////////////////////////////////////////////////////////////// 867 static error_t fatfs_cluster_alloc( uint32_t last_cluster_id, 868 uint32_t * searched_cluster_id ) 869 { 870 error_t error; 871 uint32_t free_clusters; // total number of free clusters 872 uint32_t hint; // hint + 1 is the first free cluster 873 uint32_t new_cluster_id; // allocated cluster index in FAT 874 uint32_t new_page_id; // allocated cluster page index in FAT mapper 875 uint32_t new_slot_id; // allocated cluster slot index in page (1024 slots per page) 876 xptr_t new_page_xp; // extended pointer on FAT page for allocated cluster 877 xptr_t new_slot_xp; // extended pointer on allocated cluster slot in FAT 878 uint32_t last_page_id; // last cluster page index in FAT mapper 879 uint32_t last_slot_id; // last cluster slot index in page (1024 slots per page) 880 xptr_t last_slot_xp; // extended pointer on last cluster slot in FAT 881 xptr_t last_page_xp; // extended pointer on FAT page for last cluster 882 vfs_ctx_t * vfs_ctx; // local pointer on VFS context (same in all clusters) 883 fatfs_ctx_t * loc_fatfs_ctx; // local pointer on local FATFS context 884 fatfs_ctx_t * fat_fatfs_ctx; // local pointer on FATFS context in FAT cluster 885 mapper_t * fat_mapper_ptr; // local pointer on FAT mapper 886 xptr_t fat_mapper_xp; // extended pointer on FAT mapper 887 cxy_t fat_cxy; // FAT mapper cluster identifier 888 xptr_t lock_xp; // extended pointer on lock protecting free clusters info 889 xptr_t hint_xp; // extended pointer on free_cluster_hint in FAT cluster 890 xptr_t free_xp; // extended pointer on free_clusters_number in FAT cluster 891 892 #if DEBUG_FATFS_CLUSTER_ALLOC 893 uint32_t cycle = (uint32_t)hal_get_cycles(); 894 thread_t * this = CURRENT_THREAD; 895 if( DEBUG_FATFS_CLUSTER_ALLOC < cycle ) 896 printk("\n[%s] thread[%x,%x] enter / lats_cluster_id %x / cycle = %d\n", 897 __FUNCTION__, this->process->pid, this->trdid, last_cluster_id, cycle ); 898 #endif 899 900 // get local pointer on VFS context (same in all clusters) 901 vfs_ctx = &fs_context[FS_TYPE_FATFS]; 902 903 // get local pointer on local FATFS context 904 loc_fatfs_ctx = vfs_ctx->extend; 905 906 // get FAT cluster 907 fat_cxy = CONFIG_VFS_ROOT_CXY; 908 909 // get pointers on FAT mapper 910 fat_mapper_ptr = loc_fatfs_ctx->fat_mapper; 911 fat_mapper_xp = XPTR( fat_cxy , fat_mapper_ptr ); 912 913 // get local pointer on FATFS context in FAT cluster 914 fat_fatfs_ctx = hal_remote_lpt( XPTR( fat_cxy , &vfs_ctx->extend ) ); 915 916 // build relevant extended pointers on free clusters info in FAT cluster 917 lock_xp = XPTR( fat_cxy , &fat_fatfs_ctx->lock ); 918 hint_xp = XPTR( fat_cxy , &fat_fatfs_ctx->free_cluster_hint ); 919 free_xp = XPTR( fat_cxy , &fat_fatfs_ctx->free_clusters ); 920 921 // take the FAT lock in write mode 922 remote_rwlock_wr_acquire( lock_xp ); 923 924 // get hint and free_clusters values from FATFS context in FAT cluster 925 hint = hal_remote_l32( hint_xp ); 926 free_clusters = hal_remote_l32( free_xp ); 927 928 #if (DEBUG_FATFS_CLUSTER_ALLOC & 1) 929 if( DEBUG_FATFS_CLUSTER_ALLOC < cycle ) 930 printk("\n[%s] thread[%x,%x] get free info : hint %x / free_clusters %x\n", 931 __FUNCTION__, this->process->pid, this->trdid, hint, free_clusters ); 932 #endif 933 934 // check "free_clusters" 935 if ( free_clusters == 0 ) 936 { 937 printk("\n[ERROR] in %s : no more free FATFS clusters\n", __FUNCTION__ ); 938 remote_rwlock_wr_release( lock_xp ); 939 return -1; 940 } 941 else if ( free_clusters < CONFIG_VFS_FREE_CLUSTERS_MIN ) 942 { 943 printk("\n[WARNING] in %s : only %d free FATFS clusters\n", 944 __FUNCTION__, CONFIG_VFS_FREE_CLUSTERS_MIN ); 945 } 946 947 // get new cluster, page & slot indexes in FAT 948 new_cluster_id = hint + 1; 949 new_page_id = new_cluster_id >> 10; 950 new_slot_id = new_cluster_id & 0x3FF; 951 952 // get relevant FAT page descriptor from FAT mapper 953 new_page_xp = mapper_get_fat_page( fat_mapper_xp , new_page_id ); 954 955 if( new_page_xp == XPTR_NULL ) 956 { 957 printk("\n[ERROR] in %s : cannot acces FAT mapper\n", __FUNCTION__ ); 958 remote_rwlock_wr_release( lock_xp ); 959 return -1; 960 } 961 962 // build extended pointer on new cluster slot in FAT mapper 963 new_slot_xp = ppm_page2base( new_page_xp ) + (new_slot_id << 2); 964 965 // check selected cluster actually free 966 if( hal_remote_l32( new_slot_xp ) != FREE_CLUSTER ) 967 { 968 printk("\n[ERROR] in %s : selected cluster_id %x not free\n", 969 __FUNCTION__, new_cluster_id ); 970 remote_rwlock_wr_release( lock_xp ); 971 return -1; 972 } 973 974 // update new_cluster slot in FAT mapper 975 hal_remote_s32( new_slot_xp , END_OF_CHAIN_CLUSTER_MIN ); 976 977 // handle last_cluster_id argument if non zero 978 if( last_cluster_id ) 979 { 980 // get last cluster page & slot indexes in FAT 981 last_page_id = last_cluster_id >> 10; 982 last_slot_id = last_cluster_id & 0x3FF; 983 984 // get relevant FAT page descriptor from FAT mapper 985 last_page_xp = mapper_get_fat_page( fat_mapper_xp , last_page_id ); 986 987 if( last_page_xp == XPTR_NULL ) 988 { 989 printk("\n[ERROR] in %s : cannot acces FAT mapper\n", __FUNCTION__ ); 990 remote_rwlock_wr_release( lock_xp ); 991 return -1; 992 } 993 994 // build extended pointer on new cluster slot in FAT mapper 995 last_slot_xp = ppm_page2base( last_page_xp ) + (last_slot_id << 2); 996 997 // check last cluster actually end of chain 998 if( hal_remote_l32( last_slot_xp ) != END_OF_CHAIN_CLUSTER_MIN ) 999 { 1000 printk("\n[ERROR] in %s : last_cluster_id %x not END_OF_CHAIN\n", 1001 __FUNCTION__, last_cluster_id ); 1002 remote_rwlock_wr_release( lock_xp ); 1003 return -1; 1004 } 1005 1006 // update last_cluster slot in FAT mapper 1007 hal_remote_s32( last_slot_xp , new_cluster_id ); 1008 } 1009 else 1010 { 1011 last_page_xp = XPTR_NULL; 1012 } 1013 1014 // update the FAT new_page on device 1015 error = fatfs_move_page( new_page_xp , IOC_SYNC_WRITE ); 1016 1017 if( error ) 1018 { 1019 printk("\n[ERROR] in %s : cannot update FAT on IOC device\n", __FUNCTION__ ); 1020 remote_rwlock_wr_release( lock_xp ); 1021 return -1; 1022 } 1023 1024 // update the FAT last_page on device when required 1025 if( (last_page_xp != XPTR_NULL) && (last_page_xp != new_page_xp) ) 1026 { 1027 error = fatfs_move_page( last_page_xp , IOC_SYNC_WRITE ); 1028 1029 if( error ) 1030 { 1031 printk("\n[ERROR] in %s : cannot update FAT on IOC device\n", __FUNCTION__ ); 1032 remote_rwlock_wr_release( lock_xp ); 1033 return -1; 1034 } 1035 } 1036 1037 // update free cluster info in FATFS context and in FS_INFO sector 1038 error = fatfs_free_clusters_decrement( XPTR( fat_cxy , fat_fatfs_ctx ) , new_cluster_id ); 1039 1040 if( error ) 1041 { 1042 printk("\n[ERROR] in %s : cannot update free cluster info\n", __FUNCTION__ ); 1043 remote_rwlock_wr_release( lock_xp ); 1044 return -1; 1045 } 1046 1047 // release FAT lock 1048 remote_rwlock_wr_release( lock_xp ); 1049 1050 #if DEBUG_FATFS_CLUSTER_ALLOC 1051 cycle = (uint32_t)hal_get_cycles(); 1052 if( DEBUG_FATFS_CLUSTER_ALLOC < cycle ) 1053 printk("\n[%s] thread[%x,%x] exit / allocated cluster_id %x in FAT / cycle %d\n", 1054 __FUNCTION__, this->process->pid, this->trdid, new_cluster_id, cycle ); 1055 #endif 1056 1057 *searched_cluster_id = new_cluster_id; 1058 return 0; 1059 1060 } // end fatfs_cluster_alloc() 1061 1062 1063 ////////////////////////////////////////////////////////////////////////////////////////// 855 1064 // This static function access the FAT (File Allocation Table), stored in the FAT mapper, 856 1065 // and returns in <searched_cluster_id> the FATFS cluster_id for a given page of a given 857 // inode, identified by the <searched_page_id> argument ,that is the page index in file1066 // inode, identified by the <searched_page_id> argument that is the page index in file 858 1067 // (i.e. the page index in file mapper). The entry point in the FAT is defined by the 859 1068 // <first_cluster_id> argument, that is the cluster_id of an already allocated cluster. … … 861 1070 // fatfs_inode extension), or any page of the file whose <first_page_id> argument 862 1071 // is smaller than the searched <first_page_id> argument. 863 // This function can be called by a thread running in any cluster, as it uses remote 864 // access primitives when the FAT mapper is remote. 1072 // This function can be called by a thread running in any cluster. 865 1073 // The FAT mapper being a WRITE-THROUGH cache, this function updates the FAT mapper 866 1074 // from informations stored on IOC device in case of miss when scanning the FAT mapper. … … 885 1093 uint32_t current_cluster_id; // index of cluster in FATFS 886 1094 xptr_t lock_xp; // extended pointer on FAT lock 1095 xptr_t fat_mapper_xp; // extended pointer on FAT mapper 1096 mapper_t * fat_mapper_ptr; // local pointer on FAT mapper 1097 cxy_t fat_cxy; // FAT cluster 1098 error_t error; 887 1099 888 1100 assert( (searched_page_id > first_page_id) , … … 893 1105 thread_t * this = CURRENT_THREAD; 894 1106 if( DEBUG_FATFS_GET_CLUSTER < cycle ) 895 printk("\n[%s] thread[%x,%x] enter / first_cluster_id %x / searched_page_id %d / cycle %d\n", 896 __FUNCTION__, this->process->pid, this->trdid, first_cluster_id, searched_page_id, cycle ); 1107 printk("\n[%s] thread[%x,%x] enter / frst_pid %x / frst_cid %x / srch_pid %d / cycle %d\n", 1108 __FUNCTION__, this->process->pid, this->trdid, 1109 first_page_id, first_cluster_id, searched_page_id, cycle ); 897 1110 #endif 898 1111 … … 903 1116 fatfs_ctx_t * loc_fatfs_ctx = vfs_ctx->extend; 904 1117 905 // get extended pointer and cluster on FAT mapper 906 xptr_t fat_mapper_xp = loc_fatfs_ctx->fat_mapper_xp; 907 cxy_t fat_cxy = GET_CXY( fat_mapper_xp ); 1118 // get FAT cluster 1119 fat_cxy = CONFIG_VFS_ROOT_CXY; 1120 1121 // get pointers on FAT mapper 1122 fat_mapper_ptr = loc_fatfs_ctx->fat_mapper; 1123 fat_mapper_xp = XPTR( fat_cxy , fat_mapper_ptr ); 908 1124 909 1125 // get local pointer on FATFS context in FAT cluster … … 931 1147 932 1148 // get pointer on current page descriptor in FAT mapper 933 xptr_t current_page_xp = mapper_ remote_get_page( fat_mapper_xp , fat_page_index );1149 xptr_t current_page_xp = mapper_get_fat_page( fat_mapper_xp , fat_page_index ); 934 1150 935 1151 if( current_page_xp == XPTR_NULL ) … … 942 1158 943 1159 // get pointer on buffer containing the FAT mapper page 944 xptr_t base_xp = ppm_page2base( current_page_xp );945 uint32_t * buffer = (uint32_t *)GET_PTR( base_xp );1160 xptr_t base_xp = ppm_page2base( current_page_xp ); 1161 uint32_t * buffer = (uint32_t *)GET_PTR( base_xp ); 946 1162 947 1163 // get next_cluster_id from FAT slot 948 1164 uint32_t next_cluster_id = hal_remote_l32( XPTR( fat_cxy, &buffer[fat_slot_index] ) ); 949 1165 950 // allocate a new FAT cluster when there is no cluster 951 // allocated on device for the current page 1166 // allocate a new FAT cluster when END_OF_CHAIN found 952 1167 if( next_cluster_id >= END_OF_CHAIN_CLUSTER_MIN ) 953 1168 { … … 956 1171 957 1172 // allocate a new cluster_id (and update both FAT mapper and FAT on device). 958 error _t error = fatfs_cluster_alloc( &next_cluster_id );959 1173 error = fatfs_cluster_alloc( current_cluster_id, 1174 &next_cluster_id ); 960 1175 if( error ) 961 1176 { … … 968 1183 #if (DEBUG_FATFS_GET_CLUSTER & 1) 969 1184 if( DEBUG_FATFS_GET_CLUSTER < cycle ) 970 printk("\n[%s] allocated a new cluster_id % din FATFS\n",1185 printk("\n[%s] allocated a new cluster_id %x in FATFS\n", 971 1186 __FUNCTION__, next_cluster_id ); 972 1187 #endif … … 977 1192 #if (DEBUG_FATFS_GET_CLUSTER & 1) 978 1193 if( DEBUG_FATFS_GET_CLUSTER < cycle ) 979 printk("\n[%s] traverse FAT / fat_page_index %d / fat_slot_index %d/ next_cluster_id %x\n",980 __FUNCTION__, fat_page_index, fat_slot_index, next_cluster_id );1194 printk("\n[%s] traverse FAT / current_cluster_id %x / next_cluster_id %x\n", 1195 __FUNCTION__, current_cluster_id , next_cluster_id ); 981 1196 #endif 982 1197 … … 991 1206 #if DEBUG_FATFS_GET_CLUSTER 992 1207 if( DEBUG_FATFS_GET_CLUSTER < cycle ) 993 printk("\n[%s] thread[%x,%x] exit / searched_cluster_id = %d\n", 994 __FUNCTION__, this->process->pid, this->trdid, current_cluster_id ); 1208 printk("\n[%s] thread[%x,%x] exit / frst_pid %d / frst_cid %x / srch_pid %d / srch_cid %x\n", 1209 __FUNCTION__, this->process->pid, this->trdid, 1210 first_page_id, first_cluster_id, searched_page_id, current_cluster_id ); 995 1211 #endif 996 1212 … … 1000 1216 } // end fatfs_get_cluster() 1001 1217 1002 1003 1004 1005 1006 //////////////////////////////////////////////////////////////////////////////////////////1007 // FATFS specific extern functions1008 //////////////////////////////////////////////////////////////////////////////////////////1009 1010 ///////////////////////////////////1011 void fatfs_display_ctx( cxy_t cxy )1012 {1013 // get pointer on local FATFS context1014 vfs_ctx_t * vfs_ctx = &fs_context[FS_TYPE_FATFS];1015 fatfs_ctx_t * ctx = hal_remote_lpt( XPTR( cxy , &vfs_ctx->extend ) );1016 1017 uint32_t fat_sectors = hal_remote_l32( XPTR( cxy , &ctx->fat_sectors_count ) );1018 uint32_t sector_size = hal_remote_l32( XPTR( cxy , &ctx->bytes_per_sector ) );1019 uint32_t sec_per_clus = hal_remote_l32( XPTR( cxy , &ctx->sectors_per_cluster ) );1020 uint32_t fat_lba = hal_remote_l32( XPTR( cxy , &ctx->fat_begin_lba ) );1021 uint32_t data_lba = hal_remote_l32( XPTR( cxy , &ctx->cluster_begin_lba ) );1022 uint32_t fsinfo_lba = hal_remote_l32( XPTR( cxy , &ctx->fs_info_lba ) );1023 uint32_t root_dir_clus = hal_remote_l32( XPTR( cxy , &ctx->root_dir_cluster ) );1024 uint32_t free_clusters = hal_remote_l32( XPTR( cxy , &ctx->free_clusters ) );1025 uint32_t free_cluster_hint = hal_remote_l32( XPTR( cxy , &ctx->free_cluster_hint ) );1026 xptr_t mapper_xp = hal_remote_l64( XPTR( cxy , &ctx->fat_mapper_xp ) );1027 void * fs_info_buffer = hal_remote_lpt( XPTR( cxy , &ctx->fs_info_buffer ) );1028 1029 printk("\n*** FAT context in cluster %x\n"1030 "- fat_sectors = %d\n"1031 "- sector size = %d\n"1032 "- cluster size = %d\n"1033 "- fat_lba = %x\n"1034 "- data_lba = %x\n"1035 "- fsinfo_lba = %x\n"1036 "- root_dir_cluster = %x\n"1037 "- free_clusters = %x\n"1038 "- free_cluster_hint = %x\n"1039 "- fat_mapper_ptr = %x\n"1040 "- fs_info_buffer = %x\n",1041 cxy,1042 fat_sectors,1043 sector_size,1044 sector_size * sec_per_clus,1045 fat_lba,1046 data_lba,1047 fsinfo_lba,1048 root_dir_clus,1049 free_clusters,1050 free_cluster_hint,1051 GET_PTR( mapper_xp ),1052 fs_info_buffer );1053 1054 } // end fatfs_ctx_display()1055 1056 //////////////////////////////////////////1057 void fatfs_display_fat( uint32_t page_id,1058 uint32_t min_slot,1059 uint32_t nb_slots )1060 {1061 uint32_t line;1062 1063 // compute number of lines to display1064 uint32_t min_line = min_slot >> 3;1065 uint32_t max_line = (min_slot + nb_slots - 1) >> 3;1066 1067 // get pointer on local FATFS context1068 vfs_ctx_t * vfs_ctx = &fs_context[FS_TYPE_FATFS];1069 fatfs_ctx_t * loc_fatfs_ctx = (fatfs_ctx_t *)vfs_ctx->extend;1070 1071 // get pointers on FAT mapper (in FAT cluster)1072 xptr_t mapper_xp = loc_fatfs_ctx->fat_mapper_xp;1073 cxy_t mapper_cxy = GET_CXY( mapper_xp );1074 1075 // get pointer on FATFS context in FAT cluster1076 fatfs_ctx_t * fat_fatfs_ctx = hal_remote_lpt( XPTR( mapper_cxy , &vfs_ctx->extend ) );1077 1078 // get current value of hint and free_clusters1079 uint32_t hint = hal_remote_l32( XPTR( mapper_cxy , &fat_fatfs_ctx->free_cluster_hint ) );1080 uint32_t free = hal_remote_l32( XPTR( mapper_cxy , &fat_fatfs_ctx->free_clusters ) );1081 1082 // get extended pointer on requested page descriptor in FAT mapper1083 xptr_t page_xp = mapper_remote_get_page( mapper_xp , page_id );1084 1085 // get pointers on requested page base1086 xptr_t base_xp = ppm_page2base( page_xp );1087 void * base = GET_PTR( base_xp );1088 1089 printk("\n***** FAT mapper / cxy %x / page_id %d / base %x / free_clusters %x / hint %x\n",1090 mapper_cxy, page_id, base, free, hint );1091 1092 for( line = min_line ; line <= max_line ; line++ )1093 {1094 printk("%d : %X | %X | %X | %X | %X | %X | %X | %X\n", (line<<3),1095 hal_remote_l32( base_xp + ((line<<5) ) ),1096 hal_remote_l32( base_xp + ((line<<5) + 4 ) ),1097 hal_remote_l32( base_xp + ((line<<5) + 8 ) ),1098 hal_remote_l32( base_xp + ((line<<5) + 12 ) ),1099 hal_remote_l32( base_xp + ((line<<5) + 16 ) ),1100 hal_remote_l32( base_xp + ((line<<5) + 20 ) ),1101 hal_remote_l32( base_xp + ((line<<5) + 24 ) ),1102 hal_remote_l32( base_xp + ((line<<5) + 28 ) ) );1103 }1104 1105 } // end fatfs_display_fat()1106 1107 1108 1109 ///////////////////////////////////////////////////////////////////////////////////////1110 // Generic API : the following functions are called by the kernel VFS1111 // and must be defined by all supported file systems.1112 ///////////////////////////////////////////////////////////////////////////////////////1113 1114 /////////////////////////////////////1115 fatfs_ctx_t * fatfs_ctx_alloc( void )1116 {1117 kmem_req_t req;1118 req.type = KMEM_KCM;1119 req.order = bits_log2( sizeof(fatfs_ctx_t) );1120 req.flags = AF_KERNEL | AF_ZERO;1121 1122 return kmem_alloc( &req );1123 }1124 1125 //////////////////////////////////////////////1126 void fatfs_ctx_init( fatfs_ctx_t * fatfs_ctx )1127 {1128 error_t error;1129 kmem_req_t req;1130 uint8_t * buffer;1131 xptr_t buffer_xp;1132 1133 #if DEBUG_FATFS_CTX_INIT1134 uint32_t cycle = (uint32_t)hal_get_cycles();1135 thread_t * this = CURRENT_THREAD;1136 if( DEBUG_FATFS_CTX_INIT < cycle )1137 printk("\n[%s] thread[%x,%x] enter for fatfs_ctx = %x / cycle %d\n",1138 __FUNCTION__ , this->process->pid, this->trdid, fatfs_ctx , cycle );1139 #endif1140 1141 // check argument1142 assert( (fatfs_ctx != NULL) , "pointer on FATFS context is NULL" );1143 1144 // check only cluster 0 does FATFS initialization1145 assert( (local_cxy == 0) , "only cluster 0 can initialize FATFS");1146 1147 // allocate a permanent 512 bytes buffer to store1148 // - temporarily the BOOT sector1149 // - permanently the FS_INFO sector1150 req.type = KMEM_KCM;1151 req.order = 9; // 512 bytes1152 req.flags = AF_KERNEL | AF_ZERO;1153 buffer = kmem_alloc( &req );1154 1155 if( buffer == NULL )1156 {1157 printk("\n[PANIC] in %s : cannot allocate buffer\n", __FUNCTION__ );1158 hal_core_sleep();1159 }1160 1161 buffer_xp = XPTR( local_cxy , buffer );1162 1163 // load the BOOT record from device1164 error = dev_ioc_move_data( IOC_SYNC_READ , buffer_xp , 0 , 1 );1165 1166 if ( error )1167 {1168 printk("\n[PANIC] in %s : cannot access boot record\n", __FUNCTION__ );1169 hal_core_sleep();1170 }1171 1172 #if (DEBUG_FATFS_CTX_INIT & 0x1)1173 if( DEBUG_FATFS_CTX_INIT < cycle )1174 putb( "boot record", buffer , 256 );1175 #endif1176 1177 // get sector size from boot record1178 uint32_t sector_size = fatfs_get_record( BPB_BYTSPERSEC , buffer );1179 if ( sector_size != 512 )1180 {1181 printk("\n[PANIC] in %s : sector size must be 512 bytes\n", __FUNCTION__ );1182 hal_core_sleep();1183 }1184 1185 // get cluster size from boot record1186 uint32_t nb_sectors = fatfs_get_record( BPB_SECPERCLUS , buffer );1187 if ( nb_sectors != 8 )1188 {1189 printk("\n[PANIC] in %s : cluster size must be 8 sectors\n", __FUNCTION__ );1190 hal_core_sleep();1191 }1192 1193 // get number of FAT copies from boot record1194 uint32_t nb_fats = fatfs_get_record( BPB_NUMFATS , buffer );1195 if ( nb_fats != 1 )1196 {1197 printk("\n[PANIC] in %s : number of FAT copies must be 1\n", __FUNCTION__ );1198 hal_core_sleep();1199 }1200 1201 // get number of sectors in FAT from boot record1202 uint32_t fat_sectors = fatfs_get_record( BPB_FAT32_FATSZ32 , buffer );1203 if ( (fat_sectors & 0xF) != 0 )1204 {1205 printk("\n[PANIC] in %s : FAT size not multiple of 16 sectors\n", __FUNCTION__ );1206 hal_core_sleep();1207 }1208 1209 // get root cluster from boot record1210 uint32_t root_cluster = fatfs_get_record( BPB_FAT32_ROOTCLUS , buffer );1211 if ( root_cluster != 2 )1212 {1213 printk("\n[PANIC] in %s : root cluster index must be 2\n", __FUNCTION__ );1214 hal_core_sleep();1215 }1216 1217 // get FAT lba from boot record1218 uint32_t fat_lba = fatfs_get_record( BPB_RSVDSECCNT , buffer );1219 1220 // get FS_INFO sector lba from boot record1221 uint32_t fs_info_lba = fatfs_get_record( BPB_FAT32_FSINFO , buffer );1222 1223 // load the FS_INFO record from device1224 error = dev_ioc_move_data( IOC_SYNC_READ , buffer_xp , fs_info_lba , 1 );1225 1226 if ( error )1227 {1228 printk("\n[PANIC] in %s : cannot access FS_INFO record\n", __FUNCTION__ );1229 hal_core_sleep();1230 }1231 1232 // get free_clusters number from FS_INFO record1233 uint32_t free_clusters = fatfs_get_record( FS_FREE_CLUSTERS , buffer );1234 if ( free_clusters >= fat_sectors << 7 )1235 {1236 printk("\n[PANIC] in %s : unconsistent free_clusters\n", __FUNCTION__ );1237 hal_core_sleep();1238 }1239 1240 // get free_cluster_hint from FS_INFO record1241 uint32_t free_cluster_hint = fatfs_get_record( FS_FREE_CLUSTER_HINT , buffer );1242 1243 if ( free_cluster_hint >= fat_sectors << 7 )1244 {1245 printk("\n[PANIC] in %s : unconsistent free_cluster_hint\n", __FUNCTION__ );1246 hal_core_sleep();1247 }1248 1249 // allocate a mapper for the FAT itself1250 mapper_t * fat_mapper = mapper_create( FS_TYPE_FATFS );1251 if ( fat_mapper == NULL )1252 {1253 printk("\n[PANIC] in %s : no memory for FAT mapper\n", __FUNCTION__ );1254 hal_core_sleep();1255 }1256 1257 // the inode field is NULL for the FAT mapper1258 fat_mapper->inode = NULL;1259 1260 // initialize the FATFS context1261 fatfs_ctx->fat_begin_lba = fat_lba;1262 fatfs_ctx->fat_sectors_count = fat_sectors;1263 fatfs_ctx->bytes_per_sector = sector_size;1264 fatfs_ctx->sectors_per_cluster = nb_sectors;1265 fatfs_ctx->cluster_begin_lba = fat_lba + fat_sectors;1266 fatfs_ctx->root_dir_cluster = 2;1267 fatfs_ctx->fat_mapper_xp = XPTR( local_cxy , fat_mapper );1268 fatfs_ctx->fs_info_lba = fs_info_lba;1269 fatfs_ctx->free_clusters = free_clusters;1270 fatfs_ctx->free_cluster_hint = free_cluster_hint;1271 fatfs_ctx->fs_info_buffer = buffer;1272 1273 remote_rwlock_init( XPTR( local_cxy , &fatfs_ctx->lock ) , LOCK_FATFS_FAT );1274 1275 #if (DEBUG_FATFS_CTX_INIT & 0x1)1276 if( DEBUG_FATFS_CTX_INIT < cycle )1277 fatfs_ctx_display( fatfs_ctx );1278 #endif1279 1280 #if DEBUG_FATFS_CTX_INIT1281 cycle = (uint32_t)hal_get_cycles();1282 if( DEBUG_FATFS_CTX_INIT < cycle )1283 printk("\n[%s] thread[%x,%x] exit for fatfs_ctx = %x / cycle %d\n",1284 __FUNCTION__, this->process->pid, this->trdid, fatfs_ctx, cycle );1285 #endif1286 1287 } // end fatfs_ctx_init()1288 1289 /////////////////////////////////////////////////1290 void fatfs_ctx_destroy( fatfs_ctx_t * fatfs_ctx )1291 {1292 kmem_req_t req;1293 req.type = KMEM_KCM;1294 req.ptr = fatfs_ctx;1295 kmem_free( &req );1296 }1297 1298 ///////////////////////////////////////////////1299 error_t fatfs_add_dentry( vfs_inode_t * inode,1300 vfs_dentry_t * dentry )1301 {1302 error_t error;1303 uint32_t length; // dentry name length1304 uint32_t nb_lfn; // number or required LFN1305 char sfn[11]; // buffer for SFN name1306 uint8_t checksum; // name checksum1307 mapper_t * mapper; // loal pointer on parent inode mapper1308 xptr_t mapper_xp; // extended pointer on parent inode mapper1309 xptr_t child_xp; // extended pointer on child inode1310 cxy_t child_cxy; // child inode cluster1311 vfs_inode_t * child_ptr; // child inode local pointer1312 uint32_t size; // child inode size1313 uint32_t type; // child inode type1314 uint32_t cluster; // child inode cluster index1315 1316 #if DEBUG_FATFS_ADD_DENTRY1317 char dir_name[CONFIG_VFS_MAX_NAME_LENGTH];1318 uint32_t cycle = (uint32_t)hal_get_cycles();1319 thread_t * this = CURRENT_THREAD;1320 vfs_inode_get_name( XPTR( local_cxy , inode ) , dir_name );1321 if( DEBUG_FATFS_ADD_DENTRY < cycle )1322 printk("\n[%s] thread[%x,%x] enter / parent <%s> / child <%s> / cycle %d\n",1323 __FUNCTION__, this->process->pid, this->trdid, dir_name, dentry->name, cycle );1324 #endif1325 1326 // check arguments1327 assert( (inode != NULL) , "inode pointer is NULL\n" );1328 assert( (dentry != NULL) , "dentry pointer is NULL\n" );1329 assert( (inode->mapper != NULL ) , "mapper pointer is NULL\n" );1330 1331 // get pointers on directory mapper1332 mapper = inode->mapper;1333 mapper_xp = XPTR( local_cxy , mapper );1334 1335 // get extended pointers on remote child inode1336 child_xp = dentry->child_xp;1337 child_cxy = GET_CXY( child_xp );1338 child_ptr = GET_PTR( child_xp );1339 1340 // get relevant infos from child inode1341 type = hal_remote_l32( XPTR( child_cxy , &child_ptr->type ) );1342 size = hal_remote_l32( XPTR( child_cxy , &child_ptr->size ) );1343 cluster = (uint32_t)(intptr_t)hal_remote_lpt( XPTR( child_cxy , &child_ptr->extend ) );1344 1345 // analyse dentry name1346 error = fatfs_name_format( dentry->name,1347 &length,1348 &nb_lfn,1349 sfn,1350 &checksum );1351 if ( error )1352 {1353 printk("\n[ERROR] in %s : dentry name > 31 bytes\n", __FUNCTION__ );1354 return -1;1355 }1356 1357 // Search end of directory with two embedded loops:1358 // - scan the pages in the mapper1359 // - scan the entries in each page to find NO_MORE_ENTRY1360 1361 xptr_t page_xp; // extended pointer on page descriptor1362 xptr_t base_xp; // extended pointer on page base1363 uint8_t * base; // local pointer on page base (array of bytes)1364 uint32_t page_id = 0; // page index in mapper1365 uint32_t offset = 0; // position in page1366 uint32_t found = 0; // NO_MORE_ENTRY found1367 1368 // loop on pages in mapper1369 while ( found == 0 )1370 {1371 // get extended pointer on page descriptor in mapper1372 page_xp = mapper_remote_get_page( mapper_xp , page_id );1373 1374 if ( page_xp == XPTR_NULL )1375 {1376 printk("\n[ERROR] in %s : cannot extend directory mapper\n", __FUNCTION__ );1377 return -1;1378 }1379 1380 // get pointer on page base1381 base_xp = ppm_page2base( page_xp );1382 base = GET_PTR( base_xp );1383 1384 // loop on directory entries in this page1385 while ( (offset < 4096) && (found == 0) )1386 {1387 if ( fatfs_get_record( LDIR_ORD, (base + offset) ) == NO_MORE_ENTRY )1388 {1389 found = 1;1390 }1391 else1392 {1393 offset = offset + 32;1394 }1395 } // end loop on entries1396 1397 if ( found == 0 )1398 {1399 page_id++;1400 offset = 0;1401 }1402 } // end loop on pages1403 1404 // Modify the directory mapper: depending on the name length,1405 // the new child requires to write (3, 4, or 5) directory entries.1406 // To actually register the new child, we use a 5 steps FSM1407 // (one state per entry to be written), that is traversed as:1408 // LFN3 -> LFN2 -> LFN1 -> NORMAL -> NOMORE1409 // At most two pages are modified:1410 // - the page containing the NO_MORE_ENTRY is always modified1411 // - the following page can be modified if the name spread on to pages.1412 1413 char * name = dentry->name;1414 1415 uint32_t step; // FSM state1416 1417 if ( nb_lfn == 1 ) step = 3;1418 else if ( nb_lfn == 2 ) step = 4;1419 else if ( nb_lfn == 3 ) step = 5;1420 1421 uint8_t * entry; // pointer on directory entry to be written1422 uint32_t i; // byte index in one 32 bytes directory1423 uint32_t c; // character index in name1424 1425 while ( step )1426 {1427 // when the new child is split on two pages,1428 // we need to access a new page in mapper1429 if ( offset >= 4096 )1430 {1431 // copy the modified page to IOC device1432 fatfs_move_page( page_xp , IOC_SYNC_WRITE );1433 1434 // get the next page in FAT mapper1435 page_xp = mapper_remote_get_page( mapper_xp , page_id + 1 );1436 1437 if ( page_xp == XPTR_NULL )1438 {1439 printk("\n[ERROR] in %s : cannot extend directory mapper\n", __FUNCTION__ );1440 return -1;1441 }1442 1443 // get pointer on page base1444 base_xp = ppm_page2base( page_xp );1445 base = GET_PTR( base_xp );1446 1447 // update offset1448 offset = 0;1449 }1450 1451 // compute directory entry address1452 entry = base + offset;1453 1454 #if (DEBUG_FATFS_ADD_DENTRY & 1)1455 cycle = (uint32_t)hal_get_cycles();1456 if( DEBUG_FATFS_ADD_DENTRY < cycle )1457 printk("\n[%s] FSM step = %d / offset = %x / nb_lfn = %d / cycle %d\n",1458 __FUNCTION__, step, offset, nb_lfn, cycle );1459 #endif1460 1461 // write 32 bytes (one directory entry) per iteration1462 switch ( step )1463 {1464 case 5: // write LFN3 entry1465 {1466 c = 26;1467 // scan the 32 bytes in dir_entry1468 for ( i = 0 ; i < 32 ; i++ )1469 {1470 if (i == 0)1471 {1472 if ( nb_lfn == 3) entry[i] = 0x43;1473 else entry[i] = 0x03;1474 }1475 else if ( ( ((i >= 1 ) && (i<=10) && ((i&1)==1)) ||1476 ((i >= 14) && (i<=25) && ((i&1)==0)) ||1477 ((i >= 28) && (i<=31) && ((i&1)==0)) ) &&1478 ( c < length ) )1479 {1480 entry[i] = name[c];1481 c++;1482 }1483 else if (i == 11) entry[i] = 0x0F;1484 else if (i == 13) entry[i] = checksum;1485 else entry[i] = 0x00;1486 }1487 step--;1488 break;1489 }1490 case 4: // write LFN2 entry1491 {1492 c = 13;1493 // scan the 32 bytes in dir_entry1494 for ( i = 0 ; i < 32 ; i++ )1495 {1496 if (i == 0)1497 {1498 if ( nb_lfn == 2) entry[i] = 0x42;1499 else entry[i] = 0x02;1500 }1501 else if ( ( ((i >= 1 ) && (i<=10) && ((i&1)==1)) ||1502 ((i >= 14) && (i<=25) && ((i&1)==0)) ||1503 ((i >= 28) && (i<=31) && ((i&1)==0)) ) &&1504 ( c < length ) )1505 {1506 entry[i] = name[c];1507 c++;1508 }1509 else if (i == 11) entry[i] = 0x0F;1510 else if (i == 13) entry[i] = checksum;1511 else entry[i] = 0x00;1512 }1513 step--;1514 break;1515 }1516 case 3: // Write LFN1 entry1517 {1518 c = 0;1519 // scan the 32 bytes in dir_entry1520 for ( i = 0 ; i < 32 ; i++ )1521 {1522 if (i == 0)1523 {1524 if ( nb_lfn == 1) entry[i] = 0x41;1525 else entry[i] = 0x01;1526 }1527 else if ( ( ((i >= 1 ) && (i<=10) && ((i&1)==1)) ||1528 ((i >= 14) && (i<=25) && ((i&1)==0)) ||1529 ((i >= 28) && (i<=31) && ((i&1)==0)) ) &&1530 ( c < length ) )1531 {1532 entry[i] = name[c];1533 c++;1534 }1535 else if (i == 11) entry[i] = 0x0F;1536 else if (i == 13) entry[i] = checksum;1537 else entry[i] = 0x00;1538 }1539 step--;1540 break;1541 }1542 case 2: // write NORMAL entry1543 {1544 // scan the 32 bytes in dir_entry1545 for ( i = 0 ; i < 32 ; i++ )1546 {1547 if ( i < 11 ) // 8.3 SFN1548 {1549 entry[i] = sfn[i];1550 }1551 else if (i == 11) // ATTR1552 {1553 if (type == INODE_TYPE_DIR) entry[i] = 0x10;1554 else entry[i] = 0x20;1555 }1556 else if (i == 20) entry[i] = cluster>>16; // cluster.B21557 else if (i == 21) entry[i] = cluster>>24; // cluster.B31558 else if (i == 26) entry[i] = cluster>>0; // cluster.B01559 else if (i == 27) entry[i] = cluster>>8; // cluster.B11560 else if (i == 28) entry[i] = size>>0; // size.B01561 else if (i == 29) entry[i] = size>>8; // size.B11562 else if (i == 30) entry[i] = size>>16; // size.B21563 else if (i == 31) entry[i] = size>>24; // size.B31564 else entry[i] = 0x00;1565 }1566 1567 // update the "extend" field in dentry descriptor1568 dentry->extend = (void*)(intptr_t)(((page_id<<12) + offset)>>5);1569 1570 step--;1571 break;1572 }1573 case 1: // write NOMORE entry1574 {1575 entry [0] = 0x00;1576 step--;1577 break;1578 }1579 } // end switch step1580 1581 offset += 32;1582 1583 } // exit while1584 1585 #if (DEBUG_FATFS_ADD_DENTRY & 1)1586 cycle = (uint32_t)hal_get_cycles();1587 if( DEBUG_FATFS_ADD_DENTRY < cycle )1588 printk("\n[%s] thread[%x,%x] before IOC access / cycle %d\n",1589 __FUNCTION__, this->process->pid, this->trdid, cycle );1590 #endif1591 1592 // copy the modified page to the IOC device1593 fatfs_move_page( page_xp , IOC_SYNC_WRITE );1594 1595 #if DEBUG_FATFS_ADD_DENTRY1596 cycle = (uint32_t)hal_get_cycles();1597 if( DEBUG_FATFS_ADD_DENTRY < cycle )1598 printk("\n[%s] thread[%x,%x] exit / parent <%s> / child <%s> / cycle %d\n",1599 __FUNCTION__, this->process->pid, this->trdid, dir_name, dentry->name, cycle );1600 #endif1601 1602 return 0;1603 1604 } // end fatfs_add_dentry()1605 1606 //////////////////////////////////////////////////1607 error_t fatfs_remove_dentry( vfs_inode_t * inode,1608 vfs_dentry_t * dentry )1609 {1610 xptr_t mapper_xp; // extended pointer on mapper1611 mapper_t * mapper; // local pointer on mapper1612 xptr_t page_xp; // extended pointer on mapper page descriptor1613 xptr_t base_xp; // extended pointer on mapper page base1614 uint8_t * base; // local pointer on mapper page base1615 1616 #if DEBUG_FATFS_REMOVE_DENTRY1617 char dir_name[CONFIG_VFS_MAX_NAME_LENGTH];1618 uint32_t cycle = (uint32_t)hal_get_cycles();1619 thread_t * this = CURRENT_THREAD;1620 vfs_inode_get_name( XPTR( local_cxy , inode ) , dir_name );1621 if( DEBUG_FATFS_REMOVE_DENTRY < cycle )1622 printk("\n[%s] thread[%x,%x] enter / parent <%s> / child <%s> / cycle %d\n",1623 __FUNCTION__, this->process->pid, this->trdid, dir_name, dentry->name, cycle );1624 #endif1625 1626 // check arguments1627 assert( (inode != NULL) , "inode pointer is NULL\n" );1628 assert( (dentry != NULL) , "dentry pointer is NULL\n" );1629 assert( (inode->type == INODE_TYPE_DIR) , "inode is not a directory\n" );1630 assert( (inode->mapper != NULL ) , "mapper pointer is NULL\n" );1631 1632 // get pointers on directory mapper1633 mapper = inode->mapper;1634 mapper_xp = XPTR( local_cxy , mapper );1635 1636 // compute number of LFN entries1637 uint32_t nb_lfn;1638 uint32_t name_length = strlen( dentry->name );1639 1640 if ( name_length <= 13 ) nb_lfn = 1;1641 else if ( name_length <= 26 ) nb_lfn = 2;1642 else nb_lfn = 3;1643 1644 // we must invalidate (2, 3 or 4) 32 bytes entries:1645 // the NORMAL entry (registered in dentry->extend) and all preceding LFN entries1646 // At most two pages are modified:1647 // - the page containing the NORMAL entry is always modified.1648 // - the preceding page is modified when the name spread on two pages.1649 1650 // get 32 bytes directory entry index from dentry->extend1651 uint32_t dentry_id = (uint32_t)(intptr_t)dentry->extend;1652 1653 // get page index and offset in parent directory mapper1654 uint32_t page_id = dentry_id >> 7;1655 uint32_t offset = (dentry_id & 0x7F)<<5;1656 1657 #if DEBUG_FATFS_REMOVE_DENTRY & 11658 if( DEBUG_FATFS_REMOVE_DENTRY < cycle )1659 printk("\n[%s] dentry_id %x / page_id %x / offset %x\n",1660 __FUNCTION__, dentry_id, page_id, offset );1661 #endif1662 1663 // get extended pointer on page descriptor from parent directory mapper1664 page_xp = mapper_remote_get_page( mapper_xp , page_id );1665 1666 if ( page_xp == XPTR_NULL )1667 {1668 printk("\n[ERROR] in %s : cannot extend directory mapper\n", __FUNCTION__ );1669 return -1;1670 }1671 1672 // get pointers on page base1673 base_xp = ppm_page2base( page_xp );1674 base = GET_PTR( base_xp );1675 1676 // invalidate NORMAL entry in directory cache1677 base[offset] = 0xE5;1678 1679 // invalidate LFN entries1680 while ( nb_lfn )1681 {1682 if (offset == 0) // we must load page (page_id - 1)1683 {1684 1685 // check page_id1686 assert( (page_id > 0), "page_id and offset cannot be both 0\n" );1687 1688 // copy the modified page to the IOC device1689 fatfs_move_page( page_xp , IOC_SYNC_WRITE );1690 1691 // get extended pointer on page descriptor from parent directory mapper1692 page_xp = mapper_remote_get_page( mapper_xp , page_id );1693 1694 if ( page_xp == XPTR_NULL )1695 {1696 printk("\n[ERROR] in %s : cannot access directory mapper\n", __FUNCTION__ );1697 return -1;1698 }1699 1700 // get pointers on page base1701 base_xp = ppm_page2base( page_xp );1702 base = GET_PTR( base_xp );1703 1704 // update offset1705 offset = 4096;1706 }1707 1708 offset = offset - 32;1709 1710 // check for LFN entry1711 assert( (fatfs_get_record( DIR_ATTR, base + offset ) == ATTR_LONG_NAME_MASK ),1712 "this directory entry must be a LFN\n");1713 1714 // invalidate LFN entry1715 base[offset] = 0xE5;1716 1717 nb_lfn--;1718 }1719 1720 // copy the modified page to the IOC device1721 fatfs_move_page( page_xp , IOC_SYNC_WRITE );1722 1723 1724 #if DEBUG_FATFS_REMOVE_DENTRY1725 cycle = (uint32_t)hal_get_cycles();1726 if( DEBUG_FATFS_REMOVE_DENTRY < cycle )1727 printk("\n[%s] thread[%x,%x] exit / parent %s / child %s / cycle %d\n",1728 __FUNCTION__, this->process->pid, this->trdid, dir_name, dentry->name, cycle );1729 #endif1730 1731 return 0;1732 1733 } // end fatfs_remove_dentry1734 1735 1736 1218 ////////////////////////////////////////////////////////////////////////////////////////////// 1737 // This static function scan the pages of a mapper containing a FAT32 directory, identified 1738 // by the <mapper> argument, to find the directory entry identified by the <name> argument, 1739 // and return a pointer on the directory entry, described as and array of 32 bytes, and the 1740 // index of this entry in the FAT32 mapper, seen as an array of 32 bytes entries. 1741 // It is called by the fatfs_new_dentry() and fatfs_update_dentry() functions. 1742 // It must be called by a thread running in the cluster containing the mapper. 1219 // This static function scan the pages of a directory mapper, identified by the <mapper_xp> 1220 // argument, to find the directory entry identified by the <name> argument, and returns 1221 // a pointer on the directory entry, described as an array of 32 bytes, and the index of 1222 // this entry in the FAT32 mapper, seen as an array of 32 bytes entries. 1223 // It makes a local copy of each directory entry to reduce the number of remote accesses. 1224 // It is called by the fatfs_new_dentry_from_mapper() function. 1225 // It can be called by a thread running in any cluster. 1743 1226 ////////////////////////////////////////////////////////////////////////////////////////////// 1744 // @ mapper : [in] localpointer on directory mapper.1227 // @ mapper_xp : [in] extended pointer on directory mapper. 1745 1228 // @ name : [in] searched directory entry name. 1746 1229 // @ entry : [out] buffer for the pointer on the 32 bytes directory entry (when found). … … 1748 1231 // @ return 0 if found / return 1 if not found / return -1 if mapper access error. 1749 1232 ////////////////////////////////////////////////////////////////////////////////////////////// 1750 static error_t fatfs_scan_directory( mapper_t * mapper,1233 static error_t fatfs_scan_directory( xptr_t mapper_xp, 1751 1234 char * name, 1752 1235 uint8_t ** entry, 1753 1236 uint32_t * index ) 1754 1237 { 1755 // Two embedded loops to scan the directory mapper: 1756 // - scan the parent directory mapper pages 1757 // - scan the directory entries in each 4 Kbytes page 1758 1759 // check parent_inode and child_inode 1760 assert( (mapper != NULL) , "mapper pointer is NULL\n" ); 1761 assert( (name != NULL ), "child name is undefined\n" ); 1762 assert( (entry != NULL ), "entry buffer undefined\n" ); 1238 uint8_t buf[32]; // local buffer for one FAT32 directory entry 1239 1240 // check arguments 1241 assert( (mapper_xp != XPTR_NULL) , "mapper pointer is NULL\n" ); 1242 assert( (name != NULL ) , "child name is undefined\n" ); 1763 1243 1764 1244 #if DEBUG_FATFS_SCAN_DIRECTORY 1765 char parent_name[CONFIG_VFS_MAX_NAME_LENGTH]; 1766 uint32_t cycle = (uint32_t)hal_get_cycles(); 1767 thread_t * this = CURRENT_THREAD; 1768 vfs_inode_get_name( XPTR( local_cxy , mapper->inode ) , parent_name ); 1245 char parent_name[CONFIG_VFS_MAX_NAME_LENGTH]; 1246 uint32_t cycle = (uint32_t)hal_get_cycles(); 1247 thread_t * this = CURRENT_THREAD; 1248 mapper_t * mapper_ptr = GET_PTR( mapper_xp ); 1249 cxy_t mapper_cxy = GET_CXY( mapper_xp ); 1250 vfs_inode_t * inode_ptr = hal_remote_lpt( XPTR( mapper_cxy , &mapper_ptr->inode ) ); 1251 vfs_inode_get_name( XPTR( mapper_cxy , inode_ptr ) , parent_name ); 1769 1252 if( DEBUG_FATFS_SCAN_DIRECTORY < cycle ) 1770 1253 printk("\n[%s] thread[%x,%x] enter to search child <%s> in parent <%s> / cycle %d\n", … … 1777 1260 char lfn2[16]; // buffer for one partial cname 1778 1261 char lfn3[16]; // buffer for one partial cname 1779 xptr_t mapper_xp; // extended pointer on mapper descriptor 1780 xptr_t page_xp; // extended pointer on page descriptor 1781 xptr_t base_xp; // extended pointer on page base 1782 uint8_t * base; // local pointer on page base 1262 xptr_t page_xp; // extended pointer on one page descriptor 1263 xptr_t base_xp; // extended pointer on one page base 1783 1264 uint8_t attr; // directory entry ATTR field 1784 1265 uint8_t ord; // directory entry ORD field … … 1789 1270 uint32_t offset = 0; // byte offset in page 1790 1271 1791 mapper_xp = XPTR( local_cxy , mapper ); 1272 // Two embedded loops to scan the directory mapper: 1273 // - scan the parent directory mapper pages 1274 // - scan the directory entries in each 4 Kbytes page 1792 1275 1793 1276 // scan the mapper pages … … 1795 1278 { 1796 1279 // get one page 1797 page_xp = mapper_ remote_get_page( mapper_xp , page_id );1280 page_xp = mapper_get_page( mapper_xp , page_id ); 1798 1281 1799 1282 if( page_xp == XPTR_NULL) … … 1804 1287 // get page base 1805 1288 base_xp = ppm_page2base( page_xp ); 1806 base = (uint8_t *)GET_PTR( base_xp ); 1807 1808 #if (DEBUG_FATFS_SCAN_DIRECTORY & 0x1) 1289 1290 #if (DEBUG_FATFS_SCAN_DIRECTORY & 1) 1809 1291 if( DEBUG_FATFS_SCAN_DIRECTORY < cycle ) 1810 1292 mapper_display_page( mapper_xp , page_xp , 256 ); … … 1813 1295 while( (offset < 4096) && (found == 0) ) 1814 1296 { 1815 attr = fatfs_get_record( DIR_ATTR , base + offset ); 1816 ord = fatfs_get_record( LDIR_ORD , base + offset ); 1297 // makes a local copy of current directory entry (32 bytes) 1298 hal_remote_memcpy( XPTR( local_cxy , buf ) , base_xp + offset , 32 ); 1299 1300 // get attr and ord from local buffer 1301 attr = fatfs_get_record( DIR_ATTR , buf ); 1302 ord = fatfs_get_record( LDIR_ORD , buf ); 1817 1303 1818 1304 if (ord == NO_MORE_ENTRY) // no more entry => break … … 1832 1318 seq = ord & 0x3; 1833 1319 lfn = (seq > lfn) ? seq : lfn; 1834 if ( seq == 1 ) fatfs_get_name_from_long( b ase + offset, lfn1 );1835 else if ( seq == 2 ) fatfs_get_name_from_long( b ase + offset, lfn2 );1836 else if ( seq == 3 ) fatfs_get_name_from_long( b ase + offset, lfn3 );1320 if ( seq == 1 ) fatfs_get_name_from_long( buf , lfn1 ); 1321 else if ( seq == 2 ) fatfs_get_name_from_long( buf , lfn2 ); 1322 else if ( seq == 3 ) fatfs_get_name_from_long( buf , lfn3 ); 1837 1323 offset = offset + 32; 1838 1324 } … … 1842 1328 if ( lfn == 0 ) 1843 1329 { 1844 fatfs_get_name_from_short( b ase + offset, cname );1330 fatfs_get_name_from_short( buf , cname ); 1845 1331 } 1846 1332 else if ( lfn == 1 ) … … 1863 1349 if ( strcmp( name , cname ) == 0 ) 1864 1350 { 1351 uint8_t * base = GET_PTR( base_xp ); 1865 1352 *entry = base + offset; 1866 *index = ( (page_id<<12) + offset)>>5;1867 found 1353 *index = ( (page_id << 12) + offset ) >> 5; 1354 found = 1; 1868 1355 } 1869 1356 offset = offset + 32; 1870 1357 lfn = 0; 1871 1358 } 1359 1872 1360 } // end loop on directory entries in page 1873 1361 … … 1881 1369 1882 1370 #if DEBUG_FATFS_SCAN_DIRECTORY 1883 cycle = (uint32_t)hal_get_cycles();1884 1371 if( DEBUG_FATFS_SCAN_DIRECTORY < cycle ) 1885 1372 printk("\n[%s] thread[%x,%x] exit / found child <%s> in <%s>\n", … … 1892 1379 1893 1380 #if DEBUG_FATFS_SCAN_DIRECTORY 1894 cycle = (uint32_t)hal_get_cycles();1895 1381 if( DEBUG_FATFS_SCAN_DIRECTORY < cycle ) 1896 1382 printk("\n[%s] thread[%x,%x] exit / child <%s> in <%s> not found\n", … … 1909 1395 1910 1396 1911 1912 ///////////////////////////////////////////////////// 1913 error_t fatfs_new_dentry( vfs_inode_t * parent_inode, 1914 char * name, 1915 xptr_t child_inode_xp ) 1916 { 1917 uint8_t * entry; // pointer on FAT32 directory entry (array of 32 bytes) 1918 uint32_t index; // index of FAT32 directory entry in mapper 1919 mapper_t * mapper; // pointer on directory mapper 1920 uint32_t cluster; // directory entry cluster 1921 uint32_t size; // directory entry size 1922 bool_t is_dir; // directory entry type (file/dir) 1923 xptr_t root_xp; // extended pointer on root of parent dentries 1924 xptr_t iter_xp; // iterator for this list 1925 cxy_t child_inode_cxy; // child inode cluster 1926 vfs_inode_t * child_inode_ptr; // child inode local pointer 1927 xptr_t dentry_xp; // extended pointer on searched dentry descriptor 1928 cxy_t dentry_cxy; // cluster identifier of dentry (must be local_cxy) 1929 vfs_dentry_t * dentry_ptr; // local pointer 1930 error_t error; 1931 1932 char parent_name[CONFIG_VFS_MAX_NAME_LENGTH]; 1933 1934 // check arguments 1935 assert( (parent_inode != NULL) , "parent_inode is NULL\n" ); 1936 assert( (name != NULL) , "name is NULL\n" ); 1937 assert( (child_inode_xp != XPTR_NULL ) , "child_inode is NULL\n" ); 1938 1939 // get child inode cluster and local pointer 1940 child_inode_cxy = GET_CXY( child_inode_xp ); 1941 child_inode_ptr = GET_PTR( child_inode_xp ); 1942 1943 // build extended pointer on root of list of parent dentries 1944 root_xp = XPTR( child_inode_cxy , &child_inode_ptr->parents ); 1945 1946 // check child inode has at least one parent 1947 assert( (xlist_is_empty( root_xp ) == false ), "child inode must have one parent\n"); 1948 1949 #if DEBUG_FATFS_NEW_DENTRY 1397 ////////////////////////////////////////////////////////////////////////////////////////// 1398 // FATFS debug functions 1399 ////////////////////////////////////////////////////////////////////////////////////////// 1400 1401 /////////////////////////////////// 1402 void fatfs_display_ctx( cxy_t cxy ) 1403 { 1404 // get pointer on local FATFS context 1405 vfs_ctx_t * vfs_ctx = &fs_context[FS_TYPE_FATFS]; 1406 fatfs_ctx_t * ctx = hal_remote_lpt( XPTR( cxy , &vfs_ctx->extend ) ); 1407 1408 uint32_t fat_sectors = hal_remote_l32( XPTR( cxy , &ctx->fat_sectors_count ) ); 1409 uint32_t sector_size = hal_remote_l32( XPTR( cxy , &ctx->bytes_per_sector ) ); 1410 uint32_t sec_per_clus = hal_remote_l32( XPTR( cxy , &ctx->sectors_per_cluster ) ); 1411 uint32_t fat_lba = hal_remote_l32( XPTR( cxy , &ctx->fat_begin_lba ) ); 1412 uint32_t data_lba = hal_remote_l32( XPTR( cxy , &ctx->cluster_begin_lba ) ); 1413 uint32_t fsinfo_lba = hal_remote_l32( XPTR( cxy , &ctx->fs_info_lba ) ); 1414 uint32_t root_dir_clus = hal_remote_l32( XPTR( cxy , &ctx->root_dir_cluster ) ); 1415 uint32_t free_clusters = hal_remote_l32( XPTR( cxy , &ctx->free_clusters ) ); 1416 uint32_t free_cluster_hint = hal_remote_l32( XPTR( cxy , &ctx->free_cluster_hint ) ); 1417 void * fat_mapper = hal_remote_lpt( XPTR( cxy , &ctx->fat_mapper ) ); 1418 void * fs_info_buffer = hal_remote_lpt( XPTR( cxy , &ctx->fs_info_buffer ) ); 1419 1420 printk("\n*** FAT context in cluster %x\n" 1421 "- fat_sectors = %d\n" 1422 "- sector size = %d\n" 1423 "- cluster size = %d\n" 1424 "- fat_lba = %x\n" 1425 "- data_lba = %x\n" 1426 "- fsinfo_lba = %x\n" 1427 "- root_dir_cluster = %x\n" 1428 "- free_clusters = %x\n" 1429 "- free_cluster_hint = %x\n" 1430 "- fat_mapper = %x\n" 1431 "- fs_info_buffer = %x\n", 1432 cxy, 1433 fat_sectors, 1434 sector_size, 1435 sector_size * sec_per_clus, 1436 fat_lba, 1437 data_lba, 1438 fsinfo_lba, 1439 root_dir_clus, 1440 free_clusters, 1441 free_cluster_hint, 1442 fat_mapper, 1443 fs_info_buffer ); 1444 1445 } // end fatfs_display_ctx() 1446 1447 ////////////////////////////////////////// 1448 void fatfs_display_fat( uint32_t min_slot, 1449 uint32_t nb_slots ) 1450 { 1451 // one FAT mapper page contains 1024 slots = 128 lines of 8 slots 1452 1453 uint32_t page_id; 1454 uint32_t line; 1455 cxy_t fat_cxy; // FAT cluster 1456 mapper_t * mapper; // local pointer on FAT mapper 1457 xptr_t mapper_xp; // extended pointer on fat_mapper 1458 uint32_t min_cluster_id; // index of min slot to be displayed 1459 uint32_t min_page_id; // index of min page to be displayed 1460 uint32_t min_line_id; // index of min line in min page ( < 128 ) 1461 uint32_t max_cluster_id; // index of max slot to be displayed 1462 uint32_t max_page_id; // index of max page to be displayed 1463 uint32_t max_line_id; // index of max line in max page ( < 128 ) 1464 1465 // compute min values 1466 min_cluster_id = min_slot & 0xFFFFFFF8; 1467 min_line_id = (min_cluster_id & 0x3FF) >> 3; 1468 min_page_id = min_cluster_id >> 10; 1469 1470 // compute max values 1471 max_cluster_id = min_slot + nb_slots - 1; 1472 max_line_id = (max_cluster_id & 0x3FF) >> 3; 1473 max_page_id = max_cluster_id >> 10; 1474 1475 // get pointer on local FATFS context 1476 vfs_ctx_t * vfs_ctx = &fs_context[FS_TYPE_FATFS]; 1477 fatfs_ctx_t * loc_fatfs_ctx = (fatfs_ctx_t *)vfs_ctx->extend; 1478 1479 // get FAT cluster 1480 fat_cxy = CONFIG_VFS_ROOT_CXY; 1481 1482 // get pointers on FAT mapper (in FAT cluster) 1483 mapper = loc_fatfs_ctx->fat_mapper; 1484 mapper_xp = XPTR( fat_cxy , mapper ); 1485 1486 // get pointer on FATFS context in FAT cluster 1487 fatfs_ctx_t * fat_fatfs_ctx = hal_remote_lpt( XPTR( fat_cxy , &vfs_ctx->extend ) ); 1488 1489 // get current value of hint and free_clusters 1490 uint32_t hint = hal_remote_l32( XPTR( fat_cxy , &fat_fatfs_ctx->free_cluster_hint ) ); 1491 uint32_t free = hal_remote_l32( XPTR( fat_cxy , &fat_fatfs_ctx->free_clusters ) ); 1492 1493 printk("\n***** FAT mapper / cxy %x / free_clusters %x / hint %x\n", fat_cxy, free, hint ); 1494 1495 // scan all pages as required by min_page_id and max_page_id 1496 for( page_id = min_page_id ; page_id <= max_page_id ; page_id++ ) 1497 { 1498 // get extended pointer on requested page descriptor in FAT mapper 1499 xptr_t page_xp = mapper_get_fat_page( mapper_xp , page_id ); 1500 1501 // get extended pointer on requested page base 1502 xptr_t base_xp = ppm_page2base( page_xp ); 1503 1504 // compute min_line & max_line in current page 1505 uint32_t min_line = (page_id == min_page_id) ? min_line_id : 0; 1506 uint32_t max_line = (page_id == max_page_id) ? max_line_id : 127; 1507 1508 // loop on lines in current page 1509 for( line = min_line ; line <= max_line ; line++ ) 1510 { 1511 printk("%x : %X | %X | %X | %X | %X | %X | %X | %X\n", 1512 (page_id << 10) + (line <<3 ), 1513 hal_remote_l32( base_xp + ((line<<5) ) ), 1514 hal_remote_l32( base_xp + ((line<<5) + 4 ) ), 1515 hal_remote_l32( base_xp + ((line<<5) + 8 ) ), 1516 hal_remote_l32( base_xp + ((line<<5) + 12 ) ), 1517 hal_remote_l32( base_xp + ((line<<5) + 16 ) ), 1518 hal_remote_l32( base_xp + ((line<<5) + 20 ) ), 1519 hal_remote_l32( base_xp + ((line<<5) + 24 ) ), 1520 hal_remote_l32( base_xp + ((line<<5) + 28 ) ) ); 1521 } 1522 } 1523 } // end fatfs_display_fat() 1524 1525 ///////////////////////////////////// 1526 error_t fatfs_check_free_info( void ) 1527 { 1528 error_t error; 1529 fatfs_ctx_t * fatfs_ctx_ptr; // local pointer on fatfs context in cluster 0 1530 uint32_t ctx_free_clusters; // number of free clusters from fatfs context 1531 uint32_t ctx_free_cluster_hint; // free cluster hint from fatfs context 1532 uint32_t ioc_free_clusters; // number of free clusters from fatfs context 1533 uint32_t ioc_free_cluster_hint; // free cluster hint from fatfs context 1534 uint32_t fs_info_lba; // lba of FS_INFO sector on IOC device 1535 uint8_t * fs_info_buffer; // local pointer on FS_INFO buffer in cluster 0 1536 xptr_t fs_info_buffer_xp; // extended pointer on FS_INFO buffer in cluster 0 1537 uint8_t tmp_buf[512]; // 512 bytes temporary buffer 1538 xptr_t tmp_buf_xp; // extended pointer on temporary buffer 1539 1540 #if DEBUG_FATFS_SYNC_FSINFO 1950 1541 uint32_t cycle = (uint32_t)hal_get_cycles(); 1951 1542 thread_t * this = CURRENT_THREAD; 1952 vfs_inode_get_name( XPTR( local_cxy , parent_inode ) , parent_name ); 1953 if( DEBUG_FATFS_NEW_DENTRY < cycle ) 1543 if( DEBUG_FATFS_SYNC_FSINFO < cycle ) 1544 printk("\n[%s] thread[%x,%x] enter / cycle %d\n", 1545 __FUNCTION__ , this->process->pid, this->trdid, cycle ); 1546 #endif 1547 1548 // get pointer on fatfs context in cluster 0 1549 fatfs_ctx_ptr = hal_remote_lpt( XPTR( 0 , &fs_context[FS_TYPE_FATFS].extend ) ); 1550 1551 // get "free_clusters" and "free_cluster_hint" from fatfs context in cluster 0 1552 ctx_free_clusters = hal_remote_l32( XPTR( 0 , &fatfs_ctx_ptr->free_clusters ) ); 1553 ctx_free_cluster_hint = hal_remote_l32( XPTR( 0 , &fatfs_ctx_ptr->free_cluster_hint ) ); 1554 1555 // get fs_info_lba 1556 fs_info_lba = hal_remote_l32( XPTR( 0 , &fatfs_ctx_ptr->fs_info_lba ) ); 1557 1558 // build extended pointer on temporary buffer 1559 tmp_buf_xp = XPTR( local_cxy , tmp_buf ); 1560 1561 // copy FS_INFO sector from IOC to local buffer 1562 error = dev_ioc_sync_read( tmp_buf_xp , fs_info_lba , 1 ); 1563 1564 if ( error ) 1565 { 1566 printk("\n[ERROR] in %s : cannot access FS_INFO on IOC device\n", __FUNCTION__ ); 1567 return -1; 1568 } 1569 1570 // get current values of "free_clusters" and "free_cluster_hint" from FS_INFO on IOC 1571 ioc_free_clusters = fatfs_get_remote_record( FS_FREE_CLUSTERS , tmp_buf_xp ); 1572 ioc_free_cluster_hint = fatfs_get_remote_record( FS_FREE_CLUSTER_HINT , tmp_buf_xp ); 1573 1574 #if DEBUG_FATFS_SYNC_FSINFO 1575 if( DEBUG_FATFS_SYNC_FSINFO < cycle ) 1576 printk("\n[%s] thread[%x,%x] / ctx_free %x / ioc_free %x / ctx_hint %x / ioc_hint %x\n", 1577 __FUNCTION__ , this->process->pid, this->trdid, 1578 ctx_free_clusters, ioc_free_clusters, ctx_free_cluster_hint, ioc_free_cluster_hint ); 1579 #endif 1580 1581 // check values 1582 if( (ioc_free_clusters != ctx_free_clusters) || 1583 (ioc_free_cluster_hint != ctx_free_cluster_hint) ) 1584 { 1585 printk("\n[WARNING] in %s : unconsistent free clusters info\n" 1586 " ioc_free %x / ctx_free %x / ioc_hint %x / ctx_hint %x\n", 1587 __FUNCTION__, ioc_free_clusters, ctx_free_clusters, 1588 ioc_free_cluster_hint, ctx_free_cluster_hint ); 1589 1590 // get pointers on FS_INFO buffer in cluster 0 1591 fs_info_buffer = hal_remote_lpt( XPTR( 0 , &fatfs_ctx_ptr->fs_info_buffer ) ); 1592 fs_info_buffer_xp = XPTR( 0 , fs_info_buffer ); 1593 1594 // update FS_INFO buffer in cluster 0 1595 fatfs_set_remote_record(FS_FREE_CLUSTERS ,fs_info_buffer_xp,ctx_free_clusters ); 1596 fatfs_set_remote_record(FS_FREE_CLUSTER_HINT,fs_info_buffer_xp,ctx_free_cluster_hint); 1597 1598 // update the FS_INFO sector on IOC device 1599 error = dev_ioc_sync_write( fs_info_buffer_xp , fs_info_lba , 1 ); 1600 1601 if ( error ) 1602 { 1603 printk("\n[ERROR] in %s : cannot update FS_INFO on IOC device\n", __FUNCTION__ ); 1604 return -1; 1605 } 1606 } 1607 1608 #if DEBUG_FATFS_SYNC_FSINFO 1609 cycle = (uint32_t)hal_get_cycles(); 1610 if( DEBUG_FATFS_SYNC_FSINFO < cycle ) 1611 printk("\n[%s] thread[%x,%x] exit / cycle %d\n", 1612 __FUNCTION__ , this->process->pid, this->trdid, cycle ); 1613 #endif 1614 1615 return 0; 1616 1617 } // end fatfs_check_free_info() 1618 1619 1620 1621 1622 1623 /////////////////////////////////////////////////////////////////////////////////////// 1624 // Generic API : the following functions are called by the kernel VFS 1625 // and must be defined by all supported file systems. 1626 /////////////////////////////////////////////////////////////////////////////////////// 1627 1628 1629 ///////////////////////////////////// 1630 xptr_t fatfs_ctx_alloc( cxy_t cxy ) 1631 { 1632 kmem_req_t req; 1633 1634 // allocate memory from remote cluster 1635 req.type = KMEM_KCM; 1636 req.order = bits_log2( sizeof(fatfs_ctx_t) ); 1637 req.flags = AF_KERNEL | AF_ZERO; 1638 1639 return XPTR( cxy , kmem_remote_alloc( cxy , &req ) ); 1640 1641 } //end faffs_ctx_alloc() 1642 1643 /////////////////////////////////////////////// 1644 error_t fatfs_ctx_init( xptr_t fatfs_ctx_xp ) 1645 { 1646 error_t error; 1647 kmem_req_t req; 1648 cxy_t cxy; // FATFS context cluster identifier 1649 fatfs_ctx_t * fatfs_ctx_ptr; // local pointer on FATFS context 1650 uint8_t * buffer; // local pointer on 512 bytes buffer 1651 xptr_t buffer_xp; // extended pointer on 512 bytes buffer 1652 xptr_t fat_mapper_xp; // extended pointer on FAT mapper 1653 mapper_t * fat_mapper; // local pointer on FAT mapper 1654 1655 // get FATFS context cluster and local pointer 1656 cxy = GET_CXY( fatfs_ctx_xp ); 1657 fatfs_ctx_ptr = GET_PTR( fatfs_ctx_xp ); 1658 1659 #if DEBUG_FATFS_CTX_INIT 1660 uint32_t cycle = (uint32_t)hal_get_cycles(); 1661 thread_t * this = CURRENT_THREAD; 1662 if( DEBUG_FATFS_CTX_INIT < cycle ) 1663 printk("\n[%s] thread[%x,%x] enter for fatfs_ctx (%x,%x) / cycle %d\n", 1664 __FUNCTION__ , this->process->pid, this->trdid, cxy, fatfs_ctx_ptr , cycle ); 1665 #endif 1666 1667 // allocate a 512 bytes buffer in remote cluster, used to store 1668 // temporarily the BOOT sector, and permanently the FS_INFO sector 1669 req.type = KMEM_KCM; 1670 req.order = 9; // 512 bytes 1671 req.flags = AF_KERNEL | AF_ZERO; 1672 buffer = kmem_remote_alloc( cxy , &req ); 1673 1674 if( buffer == NULL ) 1675 { 1676 printk("\n[PANIC] in %s : cannot allocate buffer in cluster %x\n", 1677 __FUNCTION__ , cxy ); 1678 return -1; 1679 } 1680 1681 // build extended pointer on buffer 1682 buffer_xp = XPTR( cxy , buffer ); 1683 1684 // load the BOOT record from device 1685 error = dev_ioc_sync_read( buffer_xp , 0 , 1 ); 1686 1687 if ( error ) 1688 { 1689 printk("\n[PANIC] in %s : cannot access boot record\n", __FUNCTION__ ); 1690 return -1; 1691 } 1692 1693 #if (DEBUG_FATFS_CTX_INIT & 0x1) 1694 uint8_t bs[256]; 1695 hal_remote_memcpy( XPTR( local_cxy , bs ) , buffer_xp , 256 ); 1696 if( DEBUG_FATFS_CTX_INIT < cycle ) 1697 putb( "boot record", bs , 256 ); 1698 #endif 1699 1700 // get sector size from boot record 1701 uint32_t sector_size = fatfs_get_remote_record( BPB_BYTSPERSEC , buffer_xp ); 1702 1703 if ( sector_size != 512 ) 1704 { 1705 printk("\n[PANIC] in %s : sector size must be 512 bytes\n", __FUNCTION__ ); 1706 return -1; 1707 } 1708 1709 // get cluster size from boot record 1710 uint32_t nb_sectors = fatfs_get_remote_record( BPB_SECPERCLUS , buffer_xp ); 1711 1712 if ( nb_sectors != 8 ) 1713 { 1714 printk("\n[PANIC] in %s : cluster size must be 8 sectors\n", __FUNCTION__ ); 1715 return -1; 1716 } 1717 1718 // get number of FAT copies from boot record 1719 uint32_t nb_fats = fatfs_get_remote_record( BPB_NUMFATS , buffer_xp ); 1720 1721 if ( nb_fats != 1 ) 1722 { 1723 printk("\n[PANIC] in %s : number of FAT copies must be 1\n", __FUNCTION__ ); 1724 return -1; 1725 } 1726 1727 // get number of sectors in FAT from boot record 1728 uint32_t fat_sectors = fatfs_get_remote_record( BPB_FAT32_FATSZ32 , buffer_xp ); 1729 1730 if ( (fat_sectors & 0xF) != 0 ) 1731 { 1732 printk("\n[PANIC] in %s : FAT size not multiple of 16 sectors\n", __FUNCTION__ ); 1733 return -1; 1734 } 1735 1736 // get root cluster from boot record 1737 uint32_t root_cluster = fatfs_get_remote_record( BPB_FAT32_ROOTCLUS , buffer_xp ); 1738 1739 if ( root_cluster != 2 ) 1740 { 1741 printk("\n[PANIC] in %s : root cluster index must be 2\n", __FUNCTION__ ); 1742 return -1; 1743 } 1744 1745 // get FAT lba from boot record 1746 uint32_t fat_lba = fatfs_get_remote_record( BPB_RSVDSECCNT , buffer_xp ); 1747 1748 // get FS_INFO sector lba from boot record 1749 uint32_t fs_info_lba = fatfs_get_remote_record( BPB_FAT32_FSINFO , buffer_xp ); 1750 1751 // load the FS_INFO record from device 1752 error = dev_ioc_sync_read( buffer_xp , fs_info_lba , 1 ); 1753 1754 if ( error ) 1755 { 1756 printk("\n[PANIC] in %s : cannot access FS_INFO record\n", __FUNCTION__ ); 1757 return -1; 1758 } 1759 1760 // get free_clusters number from FS_INFO record 1761 uint32_t free_clusters = fatfs_get_remote_record( FS_FREE_CLUSTERS , buffer_xp ); 1762 1763 if ( free_clusters >= fat_sectors << 7 ) 1764 { 1765 printk("\n[PANIC] in %s : unconsistent free_clusters\n", __FUNCTION__ ); 1766 return -1; 1767 } 1768 1769 // get free_cluster_hint from FS_INFO record 1770 uint32_t free_hint = fatfs_get_remote_record( FS_FREE_CLUSTER_HINT , buffer_xp ); 1771 1772 if ( free_hint >= fat_sectors << 7 ) 1773 { 1774 printk("\n[PANIC] in %s : unconsistent free_cluster_hint\n", __FUNCTION__ ); 1775 return -1; 1776 } 1777 1778 // allocate a mapper for the FAT in remote cluster 1779 fat_mapper_xp = mapper_create( cxy , FS_TYPE_FATFS ); 1780 1781 // get local pointer on FAT mapper 1782 fat_mapper = GET_PTR( fat_mapper_xp ); 1783 1784 if ( fat_mapper == NULL ) 1785 { 1786 printk("\n[PANIC] in %s : no memory for FAT mapper in cluster %x\n", 1787 __FUNCTION__ , cxy ); 1788 return -1; 1789 } 1790 1791 #if (DEBUG_FATFS_CTX_INIT & 0x1) 1792 if( DEBUG_FATFS_CTX_INIT < cycle ) 1793 printk("\n[%s] sector_size %d / nb_sectors %d / fat_sectors %x / hint %x\n", 1794 __FUNCTION__, sector_size, nb_sectors, fat_sectors, free_hint ); 1795 #endif 1796 1797 // the inode field is NULL for the FAT mapper 1798 hal_remote_spt( XPTR( cxy , &fat_mapper->inode ) , NULL ); 1799 1800 // initialize the FATFS context 1801 hal_remote_s32( XPTR( cxy , &fatfs_ctx_ptr->fat_begin_lba ), fat_lba ); 1802 hal_remote_s32( XPTR( cxy , &fatfs_ctx_ptr->fat_sectors_count ), fat_sectors ); 1803 hal_remote_s32( XPTR( cxy , &fatfs_ctx_ptr->bytes_per_sector ), sector_size ); 1804 hal_remote_s32( XPTR( cxy , &fatfs_ctx_ptr->sectors_per_cluster ), nb_sectors ); 1805 hal_remote_s32( XPTR( cxy , &fatfs_ctx_ptr->cluster_begin_lba ), fat_lba + fat_sectors ); 1806 hal_remote_s32( XPTR( cxy , &fatfs_ctx_ptr->root_dir_cluster ), 2 ); 1807 hal_remote_spt( XPTR( cxy , &fatfs_ctx_ptr->fat_mapper ), fat_mapper ); 1808 hal_remote_s32( XPTR( cxy , &fatfs_ctx_ptr->fs_info_lba ), fs_info_lba ); 1809 hal_remote_s32( XPTR( cxy , &fatfs_ctx_ptr->free_clusters ), free_clusters ); 1810 hal_remote_s32( XPTR( cxy , &fatfs_ctx_ptr->free_cluster_hint ), free_hint ); 1811 hal_remote_spt( XPTR( cxy , &fatfs_ctx_ptr->fs_info_buffer ), buffer ); 1812 1813 // initialize FATFS lock 1814 remote_rwlock_init( XPTR( cxy , &fatfs_ctx_ptr->lock ) , LOCK_FATFS_FAT ); 1815 1816 #if DEBUG_FATFS_CTX_INIT 1817 if( DEBUG_FATFS_CTX_INIT < cycle ) 1818 printk("\n[%s] thread[%x,%x] exit for fatfs_ctx (%x,%x)\n", 1819 __FUNCTION__, this->process->pid, this->trdid, cxy, fatfs_ctx_ptr ); 1820 #endif 1821 1822 return 0; 1823 1824 } // end fatfs_ctx_init() 1825 1826 ////////////////////////////////////////////// 1827 void fatfs_ctx_destroy( xptr_t fatfs_ctx_xp ) 1828 { 1829 kmem_req_t req; 1830 mapper_t * fat_mapper; 1831 uint8_t * fs_info_buffer; 1832 1833 // get FATFS context cluster and local pointer 1834 fatfs_ctx_t * fatfs_ctx_ptr = GET_PTR( fatfs_ctx_xp ); 1835 cxy_t fatfs_ctx_cxy = GET_CXY( fatfs_ctx_xp ); 1836 1837 // get pointer on FAT mapper 1838 fat_mapper = hal_remote_lpt( XPTR( fatfs_ctx_cxy , &fatfs_ctx_ptr->fat_mapper ) ); 1839 1840 // release FAT mapper 1841 mapper_destroy( XPTR( fatfs_ctx_cxy , fat_mapper ) ); 1842 1843 // get pointer on FS_INFO buffer 1844 fs_info_buffer = hal_remote_lpt( XPTR( fatfs_ctx_cxy , &fatfs_ctx_ptr->fs_info_buffer ) ); 1845 1846 // release FS_INFO buffer 1847 req.type = KMEM_KCM; 1848 req.ptr = fs_info_buffer; 1849 kmem_remote_free( fatfs_ctx_cxy , &req ); 1850 1851 // release FATFS context descriptor 1852 req.type = KMEM_KCM; 1853 req.ptr = fatfs_ctx_ptr; 1854 kmem_remote_free( fatfs_ctx_cxy , &req ); 1855 1856 } // end fatfs_ctx_destroy() 1857 1858 ///////////////////////////////////////////////////////// 1859 error_t fatfs_add_dentry( xptr_t parent_inode_xp, 1860 vfs_dentry_t * dentry_ptr ) 1861 { 1862 error_t error; 1863 vfs_inode_t * parent_inode_ptr; // parent inode local pointer 1864 cxy_t parent_cxy; // pparent inode cluster 1865 xptr_t child_inode_xp; // extended pointer on child inode 1866 cxy_t child_cxy; // child inode cluster 1867 vfs_inode_t * child_inode_ptr; // child inode local pointer 1868 uint32_t length; // dentry name length 1869 uint32_t nb_lfn; // number or required LFN 1870 char sfn[11]; // buffer for SFN name 1871 uint8_t checksum; // name checksum 1872 mapper_t * mapper_ptr; // local pointer on parent directory mapper 1873 xptr_t mapper_xp; // extended pointer on parent directory mapper 1874 uint32_t size; // child inode size 1875 uint32_t type; // child inode type 1876 void * extend; // child inode extension 1877 uint32_t cluster_id; // child inode first cluster_id in FATFS 1878 1879 char child_name[CONFIG_VFS_MAX_NAME_LENGTH]; 1880 1881 uint8_t buf[32]; // local buffer for one FAT32 directory entry 1882 1883 // check arguments 1884 assert( (parent_inode_xp != XPTR_NULL) , "parent_inode_xp argument is NULL\n" ); 1885 assert( (dentry_ptr != NULL) , "dentry_ptr argument is NULL\n" ); 1886 1887 // get directory inode cluster and local pointer 1888 parent_cxy = GET_CXY( parent_inode_xp ); 1889 parent_inode_ptr = GET_PTR( parent_inode_xp ); 1890 1891 // get extended pointers on child inode 1892 child_inode_xp = hal_remote_l64( XPTR( parent_cxy , &dentry_ptr->child_xp ) ); 1893 child_cxy = GET_CXY( child_inode_xp ); 1894 child_inode_ptr = GET_PTR( child_inode_xp ); 1895 1896 // get a local copy of the child name 1897 vfs_inode_get_name( child_inode_xp , child_name ); 1898 1899 #if DEBUG_FATFS_ADD_DENTRY 1900 uint32_t cycle = (uint32_t)hal_get_cycles(); 1901 thread_t * this = CURRENT_THREAD; 1902 char parent_name[CONFIG_VFS_MAX_NAME_LENGTH]; 1903 vfs_inode_get_name( parent_inode_xp , parent_name ); 1904 if( DEBUG_FATFS_ADD_DENTRY < cycle ) 1905 printk("\n[%s] thread[%x,%x] enter for <%s> in <%s> directory / cycle %d\n", 1906 __FUNCTION__, this->process->pid, this->trdid, child_name, parent_name, cycle ); 1907 #endif 1908 1909 // get pointers on parent directory mapper 1910 mapper_ptr = hal_remote_lpt( XPTR( parent_cxy , &parent_inode_ptr->mapper ) ); 1911 mapper_xp = XPTR( parent_cxy , mapper_ptr ); 1912 1913 #if (DEBUG_FATFS_ADD_DENTRY & 1) 1914 mapper_display_page( mapper_xp , 0 , 512 ); 1915 #endif 1916 1917 // get relevant infos from child inode 1918 type = hal_remote_l32( XPTR( child_cxy , &child_inode_ptr->type ) ); 1919 size = hal_remote_l32( XPTR( child_cxy , &child_inode_ptr->size ) ); 1920 extend = hal_remote_lpt( XPTR( child_cxy , &child_inode_ptr->extend ) ); 1921 cluster_id = (uint32_t)(intptr_t)extend; 1922 1923 // analyse child name 1924 error = fatfs_name_format( child_name, 1925 &length, 1926 &nb_lfn, 1927 sfn, 1928 &checksum ); 1929 if ( error ) 1930 { 1931 printk("\n[ERROR] in %s : dentry name > 31 bytes\n", __FUNCTION__ ); 1932 return -1; 1933 } 1934 1935 // Search end of directory with two embedded loops: 1936 // - scan the pages in the mapper 1937 // - scan the entries in each page to find NO_MORE_ENTRY 1938 1939 xptr_t page_xp; // extended pointer on page descriptor 1940 xptr_t base_xp; // extended pointer on page base 1941 1942 // initialise loop variables 1943 uint32_t page_id = 0; // page index in mapper 1944 uint32_t offset = 0; // position in page 1945 uint32_t found = 0; // NO_MORE_ENTRY found 1946 1947 // loop on pages in mapper 1948 while ( found == 0 ) 1949 { 1950 // get extended pointer on page descriptor in mapper 1951 page_xp = mapper_get_page( mapper_xp , page_id ); 1952 1953 if ( page_xp == XPTR_NULL ) 1954 { 1955 printk("\n[ERROR] in %s : cannot extend directory mapper\n", 1956 __FUNCTION__ ); 1957 return -1; 1958 } 1959 1960 // get pointer on page base 1961 base_xp = ppm_page2base( page_xp ); 1962 1963 // loop on directory entries in this page 1964 while ( (offset < 4096) && (found == 0) ) 1965 { 1966 if ( fatfs_get_remote_record( LDIR_ORD, (base_xp + offset) ) == NO_MORE_ENTRY ) 1967 { 1968 found = 1; 1969 } 1970 else 1971 { 1972 offset = offset + 32; 1973 } 1974 } // end loop on entries 1975 1976 if ( found == 0 ) 1977 { 1978 page_id++; 1979 offset = 0; 1980 } 1981 } // end loop on pages 1982 1983 #if (DEBUG_FATFS_ADD_DENTRY & 1) 1984 if( DEBUG_FATFS_ADD_DENTRY < cycle ) 1985 printk("\n[%s] thread[%x,%x] found NO_MORE_ENTRY : page_id %d / offset %d\n", 1986 __FUNCTION__, this->process->pid, this->trdid, page_id, offset ); 1987 #endif 1988 1989 // Modify the directory mapper: depending on the name length, 1990 // the new child requires to write (3, 4, or 5) directory entries. 1991 // We build one complete directory entry in a local buffer 1992 // before copying it the remote mapper. We use use a 5 steps FSM 1993 // (one state per entry to be written), that is traversed as : 1994 // LFN3 -> LFN2 -> LFN1 -> NORMAL -> NOMORE 1995 // At most two pages are modified: 1996 // - the page containing the NO_MORE_ENTRY is always modified 1997 // - the following page can be modified if the name spread on two pages. 1998 1999 uint32_t step; // FSM state 2000 2001 if ( nb_lfn == 1 ) step = 3; 2002 else if ( nb_lfn == 2 ) step = 4; 2003 else if ( nb_lfn == 3 ) step = 5; 2004 2005 uint32_t i; // byte index in one 32 bytes directory 2006 uint32_t c; // character index in name 2007 2008 while ( step ) 2009 { 2010 // this block is only executed when the new name spread 2011 // on two pages, and we need to access a new page in mapper 2012 if ( offset >= 4096 ) 2013 { 2014 // copy the modified page to IOC device 2015 error = fatfs_move_page( page_xp , IOC_SYNC_WRITE ); 2016 2017 if ( error ) 2018 { 2019 printk("\n[ERROR] in %s : cannot update directory on device\n", 2020 __FUNCTION__ ); 2021 return -1; 2022 } 2023 2024 // get the next page in directory mapper 2025 page_xp = mapper_get_page( mapper_xp , page_id + 1 ); 2026 2027 if ( page_xp == XPTR_NULL ) 2028 { 2029 printk("\n[ERROR] in %s : cannot extend directory mapper\n", 2030 __FUNCTION__ ); 2031 return -1; 2032 } 2033 2034 // get pointer on page base 2035 base_xp = ppm_page2base( page_xp ); 2036 2037 // update offset 2038 offset = 0; 2039 } 2040 2041 #if (DEBUG_FATFS_ADD_DENTRY & 1) 2042 cycle = (uint32_t)hal_get_cycles(); 2043 if( DEBUG_FATFS_ADD_DENTRY < cycle ) 2044 printk("\n[%s] FSM step = %d / offset = %x / nb_lfn = %d / cycle %d\n", 2045 __FUNCTION__, step, offset, nb_lfn, cycle ); 2046 #endif 2047 2048 // write one FATFS directory entry (32 bytes) per iteration 2049 switch ( step ) 2050 { 2051 case 5: // write LFN3 entry 2052 { 2053 c = 26; 2054 2055 // write 32 bytes in local buf 2056 for ( i = 0 ; i < 32 ; i++ ) 2057 { 2058 if (i == 0) 2059 { 2060 if ( nb_lfn == 3) buf[i] = 0x43; 2061 else buf[i] = 0x03; 2062 } 2063 else if ( ( ((i >= 1 ) && (i<=10) && ((i&1)==1)) || 2064 ((i >= 14) && (i<=25) && ((i&1)==0)) || 2065 ((i >= 28) && (i<=31) && ((i&1)==0)) ) && 2066 ( c < length ) ) 2067 { 2068 buf[i] = child_name[c]; 2069 c++; 2070 } 2071 else if (i == 11) buf[i] = 0x0F; 2072 else if (i == 13) buf[i] = checksum; 2073 else buf[i] = 0x00; 2074 } 2075 2076 // copy 32 bytes from local buffer to remote mapper 2077 hal_remote_memcpy( base_xp + offset , XPTR( local_cxy , buf ) , 32 ); 2078 2079 step--; 2080 break; 2081 } 2082 case 4: // write LFN2 entry 2083 { 2084 c = 13; 2085 2086 // write 32 bytes in local buf 2087 for ( i = 0 ; i < 32 ; i++ ) 2088 { 2089 if (i == 0) 2090 { 2091 if ( nb_lfn == 2) buf[i] = 0x42; 2092 else buf[i] = 0x02; 2093 } 2094 else if ( ( ((i >= 1 ) && (i<=10) && ((i&1)==1)) || 2095 ((i >= 14) && (i<=25) && ((i&1)==0)) || 2096 ((i >= 28) && (i<=31) && ((i&1)==0)) ) && 2097 ( c < length ) ) 2098 { 2099 buf[i] = child_name[c]; 2100 c++; 2101 } 2102 else if (i == 11) buf[i] = 0x0F; 2103 else if (i == 13) buf[i] = checksum; 2104 else buf[i] = 0x00; 2105 } 2106 2107 // copy 32 bytes from local buffer to remote mapper 2108 hal_remote_memcpy( base_xp + offset , XPTR( local_cxy , buf ) , 32 ); 2109 2110 step--; 2111 break; 2112 } 2113 case 3: // Write LFN1 entry 2114 { 2115 c = 0; 2116 2117 // write 32 bytes in local buf 2118 for ( i = 0 ; i < 32 ; i++ ) 2119 { 2120 if (i == 0) 2121 { 2122 if ( nb_lfn == 1) buf[i] = 0x41; 2123 else buf[i] = 0x01; 2124 } 2125 else if ( ( ((i >= 1 ) && (i<=10) && ((i&1)==1)) || 2126 ((i >= 14) && (i<=25) && ((i&1)==0)) || 2127 ((i >= 28) && (i<=31) && ((i&1)==0)) ) && 2128 ( c < length ) ) 2129 { 2130 buf[i] = child_name[c]; 2131 c++; 2132 } 2133 else if (i == 11) buf[i] = 0x0F; 2134 else if (i == 13) buf[i] = checksum; 2135 else buf[i] = 0x00; 2136 } 2137 2138 // copy 32 bytes from local buffer to remote mapper 2139 hal_remote_memcpy( base_xp + offset , XPTR( local_cxy , buf ) , 32 ); 2140 2141 step--; 2142 break; 2143 } 2144 case 2: // write NORMAL entry 2145 { 2146 // write 32 bytes in local buf 2147 for ( i = 0 ; i < 32 ; i++ ) 2148 { 2149 if ( i < 11 ) // 8.3 SFN 2150 { 2151 buf[i] = sfn[i]; 2152 } 2153 else if (i == 11) // ATTR 2154 { 2155 if (type == INODE_TYPE_DIR) buf[i] = 0x10; 2156 else buf[i] = 0x20; 2157 } 2158 else if (i == 20) buf[i] = cluster_id>>16; // cluster.B2 2159 else if (i == 21) buf[i] = cluster_id>>24; // cluster.B3 2160 else if (i == 26) buf[i] = cluster_id>>0; // cluster.B0 2161 else if (i == 27) buf[i] = cluster_id>>8; // cluster.B1 2162 else if (i == 28) buf[i] = size>>0; // size.B0 2163 else if (i == 29) buf[i] = size>>8; // size.B1 2164 else if (i == 30) buf[i] = size>>16; // size.B2 2165 else if (i == 31) buf[i] = size>>24; // size.B3 2166 else buf[i] = 0x00; 2167 } 2168 2169 // copy 32 bytes from local buffer to remote mapper 2170 hal_remote_memcpy( base_xp + offset , XPTR( local_cxy , buf ) , 32 ); 2171 2172 // set the dentry "extend" field 2173 hal_remote_spt( XPTR( parent_cxy , &dentry_ptr->extend ), 2174 (void *)(intptr_t)(((page_id << 12) + offset) >> 5 ) ); 2175 step--; 2176 break; 2177 } 2178 case 1: // write NOMORE entry 2179 { 2180 hal_remote_s32( base_xp + offset , 0 ); 2181 2182 step--; 2183 break; 2184 } 2185 2186 } // end switch step 2187 2188 offset += 32; 2189 2190 } // end while 2191 2192 // copy the modified page to the IOC device 2193 error = fatfs_move_page( page_xp , IOC_SYNC_WRITE ); 2194 2195 if ( error ) 2196 { 2197 printk("\n[ERROR] in %s : cannot update directory on device\n", 2198 __FUNCTION__ ); 2199 return -1; 2200 } 2201 2202 #if DEBUG_FATFS_ADD_DENTRY 2203 cycle = (uint32_t)hal_get_cycles(); 2204 if( DEBUG_FATFS_ADD_DENTRY < cycle ) 2205 printk("\n[%s] thread[%x,%x] exit for <%s> in <%s> directory\n", 2206 __FUNCTION__, this->process->pid, this->trdid, child_name, parent_name ); 2207 #endif 2208 2209 #if (DEBUG_FATFS_ADD_DENTRY & 1) 2210 mapper_display_page( mapper_xp , 0 , 512 ); 2211 #endif 2212 2213 return 0; 2214 2215 } // end fatfs_add_dentry() 2216 2217 //////////////////////////////////////////////////////////// 2218 error_t fatfs_remove_dentry( xptr_t parent_inode_xp, 2219 vfs_dentry_t * dentry_ptr ) 2220 { 2221 error_t error; 2222 vfs_inode_t * parent_inode_ptr; // parent inode local pointer 2223 cxy_t parent_cxy; // pparent inode cluster 2224 xptr_t child_inode_xp; // extended pointer on child inode 2225 cxy_t child_cxy; // child inode cluster 2226 vfs_inode_t * child_inode_ptr; // child inode local pointer 2227 xptr_t mapper_xp; // extended pointer on mapper 2228 mapper_t * mapper_ptr; // local pointer on mapper 2229 xptr_t page_xp; // extended pointer on mapper page descriptor 2230 xptr_t base_xp; // extended pointer on mapper page base 2231 uint32_t dentry_id; // FAT32 directory entry index 2232 uint32_t page_id; // page index in directory mapper 2233 uint32_t offset; // offset in this mapper page 2234 2235 char child_name[CONFIG_VFS_MAX_NAME_LENGTH]; 2236 2237 // check arguments 2238 assert( (parent_inode_xp != XPTR_NULL) , "parent_inode_xp argument is NULL\n" ); 2239 assert( (dentry_ptr != NULL) , "dentry_ptr argument is NULL\n" ); 2240 2241 // get directory inode cluster and local pointer 2242 parent_cxy = GET_CXY( parent_inode_xp ); 2243 parent_inode_ptr = GET_PTR( parent_inode_xp ); 2244 2245 // get extended pointers on child inode 2246 child_inode_xp = hal_remote_l64( XPTR( parent_cxy , &dentry_ptr->child_xp ) ); 2247 child_cxy = GET_CXY( child_inode_xp ); 2248 child_inode_ptr = GET_PTR( child_inode_xp ); 2249 2250 // get a local copy of the child name 2251 vfs_inode_get_name( child_inode_xp , child_name ); 2252 2253 #if DEBUG_FATFS_REMOVE_DENTRY 2254 uint32_t cycle = (uint32_t)hal_get_cycles(); 2255 thread_t * this = CURRENT_THREAD; 2256 char parent_name[CONFIG_VFS_MAX_NAME_LENGTH]; 2257 vfs_inode_get_name( parent_inode_xp , parent_name ); 2258 if( DEBUG_FATFS_REMOVE_DENTRY < cycle ) 2259 printk("\n[%s] thread[%x,%x] enter for <%s> in <%s> directory / cycle %d\n", 2260 __FUNCTION__, this->process->pid, this->trdid, child_name, parent_name, cycle ); 2261 #endif 2262 2263 // get pointers on directory mapper 2264 mapper_ptr = hal_remote_lpt( XPTR( parent_cxy , &parent_inode_ptr->mapper ) ); 2265 mapper_xp = XPTR( parent_cxy , mapper_ptr ); 2266 2267 // compute number of LFN entries 2268 uint32_t nb_lfn; 2269 uint32_t name_length = strlen( child_name ); 2270 2271 if ( name_length <= 13 ) nb_lfn = 1; 2272 else if ( name_length <= 26 ) nb_lfn = 2; 2273 else nb_lfn = 3; 2274 2275 // We must invalidate (2,3,4) 32 bytes entries: 2276 // - the NORMAL entry, registered in dentry->extend. 2277 // - the (1,2,3) preceding LFN entries. 2278 // At most two pages are modified: 2279 // - the page containing the NORMAL entry is always modified. 2280 // - the preceding page is modified when the name spread on two pages. 2281 2282 // get NORMAL entry index from dentry extension 2283 dentry_id = (uint32_t)(intptr_t)hal_remote_lpt( XPTR( parent_cxy , &dentry_ptr->extend ) ); 2284 2285 // get page index and offset in parent directory mapper 2286 page_id = dentry_id >> 7; 2287 offset = (dentry_id & 0x7F)<<5; 2288 2289 #if DEBUG_FATFS_REMOVE_DENTRY & 1 2290 if( DEBUG_FATFS_REMOVE_DENTRY < cycle ) 2291 printk("\n[%s] dentry_id %x / page_id %x / offset %x\n", 2292 __FUNCTION__, dentry_id, page_id, offset ); 2293 #endif 2294 2295 // get extended pointer on page descriptor 2296 page_xp = mapper_get_page( mapper_xp , page_id ); 2297 2298 if ( page_xp == XPTR_NULL ) 2299 { 2300 printk("\n[ERROR] in %s : cannot access directory mapper\n", __FUNCTION__ ); 2301 return -1; 2302 } 2303 2304 // get extended pointer on page base 2305 base_xp = ppm_page2base( page_xp ); 2306 2307 // invalidate NORMAL entry in directory cache 2308 hal_remote_sb( base_xp + offset , 0xE5 ); 2309 2310 // invalidate LFN entries 2311 while ( nb_lfn ) 2312 { 2313 // this block is only executed when the removed name 2314 // spread on two mapper pages 2315 if (offset == 0) // we must load page (page_id - 1) 2316 { 2317 // copy the modified page to the IOC device 2318 error = fatfs_move_page( page_xp , IOC_SYNC_WRITE ); 2319 2320 if ( error ) 2321 { 2322 printk("\n[ERROR] in %s : cannot update directory on device\n", 2323 __FUNCTION__ ); 2324 return -1; 2325 } 2326 2327 // get extended pointer on page descriptor 2328 page_xp = mapper_get_page( mapper_xp , page_id ); 2329 2330 if ( page_xp == XPTR_NULL ) 2331 { 2332 printk("\n[ERROR] in %s : cannot access directory mapper\n", __FUNCTION__ ); 2333 return -1; 2334 } 2335 2336 // get extended pointer on page base 2337 base_xp = ppm_page2base( page_xp ); 2338 2339 // update offset 2340 offset = 4096; 2341 } 2342 2343 offset = offset - 32; 2344 2345 // check for LFN entry 2346 assert( (fatfs_get_remote_record( DIR_ATTR, base_xp + offset ) == ATTR_LONG_NAME_MASK ), 2347 "this directory entry must be a LFN\n"); 2348 2349 // invalidate LFN entry 2350 hal_remote_sb( base_xp + offset , 0xE5 ); 2351 2352 nb_lfn--; 2353 } 2354 2355 // copy the modified page to the IOC device 2356 error = fatfs_move_page( page_xp , IOC_SYNC_WRITE ); 2357 2358 if ( error ) 2359 { 2360 printk("\n[ERROR] in %s : cannot update directory on device\n", 2361 __FUNCTION__ ); 2362 return -1; 2363 } 2364 2365 #if DEBUG_FATFS_REMOVE_DENTRY 2366 cycle = (uint32_t)hal_get_cycles(); 2367 if( DEBUG_FATFS_REMOVE_DENTRY < cycle ) 2368 printk("\n[%s] thread[%x,%x] exit for <%s> in <%s> directory\n", 2369 __FUNCTION__, this->process->pid, this->trdid, child_name, parent_name ); 2370 #endif 2371 2372 return 0; 2373 2374 } // end fatfs_remove_dentry 2375 2376 ///////////////////////////////////////////////////////////////////// 2377 error_t fatfs_new_dentry_from_mapper( xptr_t parent_inode_xp, 2378 vfs_dentry_t * dentry_ptr ) 2379 { 2380 uint32_t cluster_id; // directory entry first FATFS cluster 2381 uint32_t size; // directory entry size 2382 bool_t is_dir; // directory entry type (file/dir) 2383 cxy_t parent_cxy; // parent inode cluster 2384 vfs_inode_t * parent_inode_ptr; // parent inode local pointer 2385 mapper_t * parent_mapper; // pointer on parent directory mapper 2386 xptr_t child_inode_xp; // extended pointer on child inode 2387 cxy_t child_cxy; // child inode cluster 2388 vfs_inode_t * child_inode_ptr; // child inode local pointer 2389 error_t error; 2390 2391 uint8_t buf[32]; // FAT32 directory entry local copy 2392 2393 char parent_name[CONFIG_VFS_MAX_NAME_LENGTH]; // local parent name copy 2394 char child_name[CONFIG_VFS_MAX_NAME_LENGTH]; // local child name copy 2395 2396 // check arguments 2397 assert( (parent_inode_xp != XPTR_NULL) , "parent_inode_xp is NULL\n" ); 2398 assert( (dentry_ptr != NULL ) , "dentry_ptr is NULL\n" ); 2399 2400 // get parent inode cluster and local pointer 2401 parent_cxy = GET_CXY( parent_inode_xp ); 2402 parent_inode_ptr = GET_PTR( parent_inode_xp ); 2403 2404 // get child inode cluster and pointers 2405 child_inode_xp = hal_remote_l64( XPTR( parent_cxy , &dentry_ptr->child_xp ) ); 2406 child_cxy = GET_CXY( child_inode_xp ); 2407 child_inode_ptr = GET_PTR( child_inode_xp ); 2408 2409 // get child and parent names 2410 vfs_inode_get_name( parent_inode_xp , parent_name ); 2411 vfs_inode_get_name( child_inode_xp , child_name ); 2412 2413 #if DEBUG_FATFS_NEW_DENTRY_FROM 2414 uint32_t cycle = (uint32_t)hal_get_cycles(); 2415 thread_t * this = CURRENT_THREAD; 2416 if( DEBUG_FATFS_NEW_DENTRY_FROM < cycle ) 1954 2417 printk("\n[%s] thread[%x,%x] enter for child <%s> in parent <%s> / cycle %d\n", 1955 __FUNCTION__, this->process->pid, this->trdid, name , parent_name , cycle );2418 __FUNCTION__, this->process->pid, this->trdid, child_name , parent_name , cycle ); 1956 2419 #endif 1957 2420 1958 2421 // get local pointer on parent mapper 1959 mapper = parent_inode->mapper; 1960 1961 // get pointer and index in mapper for searched directory entry 1962 error = fatfs_scan_directory( mapper, name , &entry , &index ); 1963 1964 // return non fatal error if not found 1965 if( error ) 1966 { 1967 vfs_inode_get_name( XPTR( local_cxy , parent_inode ) , parent_name ); 1968 printk("\n[ERROR] in %s : cannot find <%s> entry in <%s> directory mapper\n", 1969 __FUNCTION__, name , parent_name, name ); 1970 return -1; 1971 } 1972 1973 1974 // get relevant infos from FAT32 directory entry 1975 cluster = (fatfs_get_record( DIR_FST_CLUS_HI , entry ) << 16) | 1976 (fatfs_get_record( DIR_FST_CLUS_LO , entry ) ) ; 1977 is_dir = (fatfs_get_record( DIR_ATTR , entry ) & ATTR_DIRECTORY); 1978 size = fatfs_get_record( DIR_FILE_SIZE , entry ); 1979 1980 // scan list of parent dentries to search the parent_inode 1981 bool_t found = false; 1982 XLIST_FOREACH( root_xp , iter_xp ) 1983 { 1984 // get pointers on dentry 1985 dentry_xp = XLIST_ELEMENT( iter_xp , vfs_dentry_t , parents ); 1986 dentry_cxy = GET_CXY( dentry_xp ); 1987 dentry_ptr = GET_PTR( dentry_xp ); 1988 1989 // get local pointer on current parent directory inode 1990 vfs_inode_t * current = hal_remote_lpt( XPTR( dentry_cxy , &dentry_ptr->parent ) ); 1991 1992 // check if current parent is the searched parent 1993 if( XPTR( dentry_cxy , current ) == XPTR( local_cxy , parent_inode ) ) 1994 { 1995 found = true; 1996 break; 1997 } 1998 } 1999 2000 if( found == false ) 2001 { 2002 vfs_inode_get_name( XPTR( local_cxy , parent_inode ) , parent_name ); 2003 printk("\n[ERROR] in %s : cannot find <%s> directory in list of parents for <%s>\n", 2004 __FUNCTION__, parent_name, name ); 2005 return -1; 2006 } 2422 parent_mapper = hal_remote_lpt( XPTR( parent_cxy , &parent_inode_ptr->mapper ) ); 2423 2424 // try to get pointer and index of directory entry in mapper 2425 uint8_t * entry = NULL; 2426 uint32_t index = 0; 2427 2428 error = fatfs_scan_directory( XPTR( parent_cxy , parent_mapper ), 2429 child_name, 2430 &entry, 2431 &index ); 2432 2433 // an error can be non fatal, for a new (created) entry 2434 if( error ) return -1; 2435 2436 // get local copy of found directory entry 2437 hal_remote_memcpy( XPTR( local_cxy , buf ), 2438 XPTR( parent_cxy , entry ), 32 ); 2439 2440 // get relevant infos from directory entry 2441 cluster_id = (fatfs_get_record( DIR_FST_CLUS_HI , buf ) << 16) | 2442 (fatfs_get_record( DIR_FST_CLUS_LO , buf ) ) ; 2443 is_dir = (fatfs_get_record( DIR_ATTR , buf ) & ATTR_DIRECTORY ); 2444 size = fatfs_get_record( DIR_FILE_SIZE , buf ); 2007 2445 2008 2446 // update the child inode "type", "size", and "extend" fields 2009 2447 vfs_inode_type_t type = (is_dir) ? INODE_TYPE_DIR : INODE_TYPE_FILE; 2010 2448 2011 hal_remote_s32( XPTR( child_ inode_cxy , &child_inode_ptr->type ) , type );2012 hal_remote_s32( XPTR( child_ inode_cxy , &child_inode_ptr->size ) , size );2013 hal_remote_s32( XPTR( child_ inode_cxy , &child_inode_ptr->extend ) , cluster);2449 hal_remote_s32( XPTR( child_cxy , &child_inode_ptr->type ) , type ); 2450 hal_remote_s32( XPTR( child_cxy , &child_inode_ptr->size ) , size ); 2451 hal_remote_s32( XPTR( child_cxy , &child_inode_ptr->extend ) , cluster_id ); 2014 2452 2015 2453 // update the dentry "extend" field 2016 dentry_ptr->extend = (void *)(intptr_t)index;2017 2018 #if DEBUG_FATFS_NEW_DENTRY 2454 hal_remote_spt( XPTR( parent_cxy , &dentry_ptr->extend ) , (void *)(intptr_t)index ); 2455 2456 #if DEBUG_FATFS_NEW_DENTRY_FROM 2019 2457 cycle = (uint32_t)hal_get_cycles(); 2020 if( DEBUG_FATFS_NEW_DENTRY < cycle ) 2021 printk("\n[%s] thread[%x,%x] exit for <%s> in <%s> / cluster_id %x / size %d / cycle %d\n", 2022 __FUNCTION__, this->process->pid, this->trdid, name, parent_name, cluster, size, cycle ); 2023 #endif 2024 2025 2026 #if (DEBUG_FATFS_NEW_DENTRY & 1) 2027 if( DEBUG_FATFS_NEW_DENTRY < cycle ) 2028 { 2029 fatfs_display_fat( 0 , 0 , 64 ); 2030 fatfs_display_fat( cluster >> 10 , (cluster & 0x3FF) , 32 ); 2031 } 2458 if( DEBUG_FATFS_NEW_DENTRY_FROM < cycle ) 2459 printk("\n[%s] thread[%x,%x] exit for <%s> in <%s> / cluster_id %x / size %d\n", 2460 __FUNCTION__, this->process->pid, this->trdid, child_name, parent_name, cluster_id, size ); 2461 #endif 2462 2463 #if (DEBUG_FATFS_NEW_DENTRY_FROM & 1) 2464 if( DEBUG_FATFS_NEW_DENTRY_FROM < cycle ) 2465 fatfs_display_fat( cluster_id , 32 ); 2032 2466 #endif 2033 2467 2034 2468 return 0; 2035 2469 2036 } // end fatfs_new_dentry() 2037 2038 ////////////////////////////////////////////////// 2039 error_t fatfs_update_dentry( vfs_inode_t * inode, 2040 vfs_dentry_t * dentry, 2041 uint32_t size ) 2042 { 2043 uint8_t * entry; // pointer on FAT32 directory entry (array of 32 bytes) 2044 uint32_t index; // index of FAT32 directory entry in mapper 2045 mapper_t * mapper; // pointer on directory mapper 2046 error_t error; 2047 2048 char dir_name[CONFIG_VFS_MAX_NAME_LENGTH]; 2470 } // end fatfs_new_dentry_from_mapper() 2471 2472 /////////////////////////////////////////////////////////////////// 2473 error_t fatfs_new_dentry_to_mapper( xptr_t parent_inode_xp, 2474 vfs_dentry_t * dentry_ptr ) 2475 { 2476 uint32_t cluster_id; // directory entry cluster 2477 cxy_t parent_cxy; // parent inode cluster identifier 2478 vfs_inode_t * parent_inode_ptr; // child inode local pointer 2479 xptr_t child_inode_xp; // extended pointer on child inode 2480 cxy_t child_cxy; // child inode cluster identifier 2481 vfs_inode_t * child_inode_ptr; // child inode local pointer 2482 error_t error; 2483 2484 char parent_name[CONFIG_VFS_MAX_NAME_LENGTH]; 2485 char child_name[CONFIG_VFS_MAX_NAME_LENGTH]; 2049 2486 2050 2487 // check arguments 2051 assert( (inode != NULL) , "inode is NULL\n" ); 2052 assert( (dentry != NULL) , "dentry is NULL\n" ); 2488 assert( (parent_inode_xp != XPTR_NULL) , "parent_inode_xp argument is NULL\n" ); 2489 assert( (dentry_ptr != NULL) , "dentry_ptr argument NULL\n" ); 2490 2491 // get child inode cluster and local pointer 2492 parent_cxy = GET_CXY( parent_inode_xp ); 2493 parent_inode_ptr = GET_PTR( parent_inode_xp ); 2494 2495 // get child inode cluster and pointers 2496 child_inode_xp = hal_remote_l64( XPTR( parent_cxy , &dentry_ptr->child_xp ) ); 2497 child_cxy = GET_CXY( child_inode_xp ); 2498 child_inode_ptr = GET_PTR( child_inode_xp ); 2499 2500 // get child and parent names 2501 vfs_inode_get_name( parent_inode_xp , parent_name ); 2502 vfs_inode_get_name( child_inode_xp , child_name ); 2503 2504 #if DEBUG_FATFS_NEW_DENTRY_TO_MAP 2505 uint32_t cycle = (uint32_t)hal_get_cycles(); 2506 thread_t * this = CURRENT_THREAD; 2507 if( DEBUG_FATFS_NEW_DENTRY_TO_MAP < cycle ) 2508 printk("\n[%s] thread[%x,%x] enter for child <%s> in parent <%s> / cycle %d\n", 2509 __FUNCTION__, this->process->pid, this->trdid, child_name , parent_name , cycle ); 2510 #endif 2511 2512 // 1. allocate one FATFS cluster (update FAT and FSINFO) 2513 error = fatfs_cluster_alloc( 0 , &cluster_id ); 2514 2515 if( error ) 2516 { 2517 printk("\n[ERROR] in %s : cannot find a free cluster_id\n", 2518 __FUNCTION__ ); 2519 return -1; 2520 } 2521 2522 // 2. register cluster_id in inode descriptor 2523 hal_remote_spt( XPTR( child_cxy , &child_inode_ptr->extend ), 2524 (void*)(intptr_t)cluster_id ); 2525 2526 // 3. introduce dentry in the directory mapper 2527 error = fatfs_add_dentry( parent_inode_xp , dentry_ptr ); 2528 2529 if( error ) 2530 { 2531 printk("\n[ERROR] in %s : cannot update parent directory mapper\n", 2532 __FUNCTION__ ); 2533 // TODO release cluster_id [AG] 2534 return -1; 2535 } 2536 2537 #if DEBUG_FATFS_NEW_DENTRY_TO_MAP 2538 if( DEBUG_FATFS_NEW_DENTRY_TO_MAP < cycle ) 2539 printk("\n[%s] thread[%x,%x] exit for <%s> in <%s> / cluster_id %x\n", 2540 __FUNCTION__, this->process->pid, this->trdid, child_name, parent_name, cluster_id ); 2541 #endif 2542 2543 return 0; 2544 2545 } // end fatfs_new_dentry_to mapper() 2546 2547 2548 //////////////////////////////////////////////////////////// 2549 error_t fatfs_update_dentry( xptr_t parent_inode_xp, 2550 vfs_dentry_t * dentry_ptr ) 2551 { 2552 cxy_t parent_cxy; // parent directory cluster identifier 2553 vfs_inode_t * parent_inode_ptr; // extended pointer on parent directory inode 2554 mapper_t * parent_mapper_ptr; // local pointer on parent directory mapper 2555 xptr_t parent_mapper_xp; // extended pointer on parent directory mapper 2556 xptr_t child_inode_xp; // extended pointer on child inode 2557 cxy_t child_cxy; // child inode cluster identifier 2558 vfs_inode_t * child_inode_ptr; // extended pointer on child inode 2559 2560 uint32_t current_size; // current size in directory mapper 2561 uint32_t new_size; // new size (from child inode) 2562 2563 uint32_t entry_id; // directory entry index in parent directory mapper 2564 uint32_t page_id; // page_index in parent directory mapper 2565 uint32_t offset; // directory entry offset in page 2566 xptr_t page_xp; // extended pointer on page descriptor 2567 xptr_t base_xp; // extended pointer on page base 2568 xptr_t entry_xp; // extended pointer on directory entry 2569 2570 error_t error; 2571 2572 char parent_name[CONFIG_VFS_MAX_NAME_LENGTH]; 2573 char child_name[CONFIG_VFS_MAX_NAME_LENGTH]; 2574 2575 // check arguments 2576 assert( (parent_inode_xp != XPTR_NULL) , "parent_inode_xp argument is NULL\n" ); 2577 assert( (dentry_ptr != NULL) , "dentry_ptr argument is NULL\n" ); 2578 2579 // get parent directory cluster ans local pointer 2580 parent_inode_ptr = GET_PTR( parent_inode_xp ); 2581 parent_cxy = GET_CXY( parent_inode_xp ); 2582 2583 // get extended pointer on child inode 2584 child_inode_xp = hal_remote_l64( XPTR( parent_cxy , &dentry_ptr->child_xp ) ); 2585 2586 // get child and parent names 2587 vfs_inode_get_name( parent_inode_xp , parent_name ); 2588 vfs_inode_get_name( child_inode_xp , child_name ); 2053 2589 2054 2590 #if DEBUG_FATFS_UPDATE_DENTRY 2055 2591 uint32_t cycle = (uint32_t)hal_get_cycles(); 2056 2592 thread_t * this = CURRENT_THREAD; 2057 vfs_inode_get_name( XPTR( local_cxy , inode ) , dir_name );2058 2593 if( DEBUG_FATFS_UPDATE_DENTRY < cycle ) 2059 printk("\n[%s] thread[%x,%x] enter for <%s/%s> / size %d / cycle %d\n", 2060 __FUNCTION__, this->process->pid, this->trdid, dir_name, dentry->name, size, cycle ); 2061 #endif 2062 2063 // get local pointer on mapper 2064 mapper = inode->mapper; 2065 2066 // get pointer and index in mapper for searched directory entry 2067 error = fatfs_scan_directory( mapper, dentry->name , &entry , &index ); 2068 2069 if( error ) 2070 { 2071 vfs_inode_get_name( XPTR( local_cxy , inode ) , dir_name ); 2072 printk("\n[ERROR] in %s : cannot find <%s> in parent mapper <%s>\n", 2073 __FUNCTION__, dentry->name, dir_name ); 2074 return -1; 2075 } 2076 2077 // get current size value 2078 uint32_t current_size = fatfs_get_record( DIR_FILE_SIZE , entry ); 2594 printk("\n[%s] thread[%x,%x] enter for <%s> in <%s> / new_size %d / cycle %d\n", 2595 __FUNCTION__, this->process->pid, this->trdid, child_name, parent_name, new_size, cycle ); 2596 #endif 2597 2598 // get child inode cluster and local pointer 2599 child_cxy = GET_CXY( child_inode_xp ); 2600 child_inode_ptr = GET_PTR( child_inode_xp ); 2601 2602 // get size from child inode 2603 new_size = hal_remote_l32( XPTR( child_cxy , &child_inode_ptr->size ) ); 2604 2605 // get local and extended pointers on parent directory mapper 2606 parent_mapper_ptr = hal_remote_lpt( XPTR( parent_cxy , &parent_inode_ptr->mapper ) ); 2607 parent_mapper_xp = XPTR( parent_cxy , parent_mapper_ptr ); 2608 2609 // get directory entry index from dentry extension 2610 entry_id = (intptr_t)hal_remote_lpt( XPTR( parent_cxy , &dentry_ptr->extend ) ); 2611 2612 // get page index and offset in parent directory mapper 2613 page_id = entry_id >> 7; 2614 offset = (entry_id & 0x7F) << 5; 2615 2616 // get extended pointers on page descriptor and page base 2617 page_xp = mapper_get_page( parent_mapper_xp , page_id ); 2618 base_xp = ppm_page2base( page_xp ); 2619 2620 // build extended pointer on directory entry 2621 entry_xp = base_xp + offset; 2622 2623 // get current size from directory mapper 2624 current_size = fatfs_get_remote_record( DIR_FILE_SIZE , entry_xp ); 2079 2625 2080 2626 // update dentry in mapper & device only if required 2081 if( size != current_size )2627 if( new_size != current_size ) 2082 2628 { 2083 2629 // set size field in FAT32 directory entry 2084 fatfs_set_record( DIR_FILE_SIZE , entry , size ); 2085 2086 // get pointer on modified page base 2087 void * base = (void *)((intptr_t)entry & (~CONFIG_PPM_PAGE_MASK)); 2088 2089 // get extended pointer on modified page descriptor 2090 xptr_t page_xp = ppm_base2page( XPTR( local_cxy , base ) ); 2091 2092 // synchronously update the modified page on device 2630 fatfs_set_remote_record( DIR_FILE_SIZE , entry_xp , new_size ); 2631 2632 // synchronously update the modified mapper page on device 2093 2633 error = fatfs_move_page( page_xp , IOC_SYNC_WRITE ); 2094 2634 2095 2635 if( error ) 2096 2636 { 2097 vfs_inode_get_name( XPTR( local_cxy , inode ) , dir_name );2098 2637 printk("\n[ERROR] in %s : cannot update parent directory <%s> on device\n", 2099 __FUNCTION__, dir_name );2638 __FUNCTION__, parent_name ); 2100 2639 return -1; 2101 2640 } … … 2105 2644 cycle = (uint32_t)hal_get_cycles(); 2106 2645 if( DEBUG_FATFS_UPDATE_DENTRY < cycle ) 2107 printk("\n[%s] thread[%x,%x] exit / updated size for <%s/%s>/ cycle %d\n",2108 __FUNCTION__, this->process->pid, this->trdid, dir_name, dentry->name, cycle );2646 printk("\n[%s] thread[%x,%x] exit for <%s> in <%s> directory / size %d / cycle %d\n", 2647 __FUNCTION__, this->process->pid, this->trdid, parent_name, child->name, new_size, cycle ); 2109 2648 #endif 2110 2649 … … 2168 2707 { 2169 2708 // get one page from mapper 2170 page_xp = mapper_ remote_get_page( mapper_xp , page_id );2709 page_xp = mapper_get_page( mapper_xp , page_id ); 2171 2710 2172 2711 if( page_xp == XPTR_NULL) return -1; … … 2273 2812 } // end fatfs_get_user_dir() 2274 2813 2275 /////////////////////////////////////////////// 2276 error_t fatfs_sync_inode( vfs_inode_t * inode ) 2277 { 2814 /////////////////////////////////////////// 2815 error_t fatfs_sync_inode( xptr_t inode_xp ) 2816 { 2817 cxy_t inode_cxy; // remote inode cluster 2818 vfs_inode_t * inode_ptr; // remote inode local pointer 2819 mapper_t * mapper; // remote inode mapper local pointer 2820 uint32_t size; // remote inode size in bytes 2821 uint32_t type; // remote inode type 2822 xptr_t rt_xp; // extended pointer on mapper radix tree 2823 uint32_t npages; // number of pages in mapper 2824 uint32_t page_id; // current page index in mapper 2825 xptr_t page_xp; // extended pointer on current page 2826 page_t * page_ptr; // local pointer on current page 2827 uint32_t flags; // current page flags 2828 error_t error; 2278 2829 2279 2830 // check inode pointer and cluster index 2280 assert( (inode != NULL) , "inode pointer undefined\n" ); 2281 assert( (inode->mapper != NULL ) , "mapper pointer undefined\n" ); 2282 assert( (inode->type == INODE_TYPE_FILE) , "inode must be a file\n" ); 2831 assert( (inode_xp != XPTR_NULL) , "inode pointer undefined\n" ); 2283 2832 2284 2833 #if DEBUG_FATFS_SYNC_INODE … … 2286 2835 uint32_t cycle = (uint32_t)hal_get_cycles(); 2287 2836 thread_t * this = CURRENT_THREAD; 2288 vfs_inode_get_name( XPTR( local_cxy , inode ), name );2837 vfs_inode_get_name( inode_xp , name ); 2289 2838 if( DEBUG_FATFS_SYNC_INODE < cycle ) 2290 2839 printk("\n[%s] thread[%x,%x] enter for <%s> / cycle %d\n", … … 2292 2841 #endif 2293 2842 2294 error_t error; 2295 mapper_t * mapper; 2296 page_t * page; 2297 uint32_t page_id; 2298 2299 // get mapper from inode 2300 mapper = inode->mapper; 2301 2302 // compute max number of pages in mapper from file size 2303 uint32_t size = inode->size; 2304 uint32_t pages = size >> CONFIG_PPM_PAGE_SHIFT; 2305 if( size & CONFIG_PPM_PAGE_MASK ) pages++; 2843 // get inode cluster and local pointer 2844 inode_cxy = GET_CXY( inode_xp ); 2845 inode_ptr = GET_PTR( inode_xp ); 2846 2847 //get inode mapper pointer 2848 mapper = hal_remote_lpt( XPTR( inode_cxy , &inode_ptr->mapper ) ); 2849 2850 assert( (mapper != NULL) , "mapper pointer is NULL\n" ); 2851 2852 // get inode type and size 2853 size = hal_remote_l32( XPTR( inode_cxy , &inode_ptr->size ) ); 2854 type = hal_remote_l32( XPTR( inode_cxy , &inode_ptr->type ) ); 2855 2856 assert( (type == INODE_TYPE_FILE) , "inode is not a file\n" ); 2857 2858 // compute number of pages 2859 npages = size >> CONFIG_PPM_PAGE_SHIFT; 2860 if( size & CONFIG_PPM_PAGE_MASK ) npages++; 2306 2861 2307 // get pointeron mapper radix tree2308 grdxt_t * rt = &mapper->rt;2862 // build pointers on mapper radix tree 2863 rt_xp = XPTR( inode_cxy , &mapper->rt ); 2309 2864 2310 2865 // scan all pages 2311 for( page_id = 0 ; page_id < pages ; page_id++ )2866 for( page_id = 0 ; page_id < npages ; page_id++ ) 2312 2867 { 2313 2868 // get page descriptor from mapper 2314 page = grdxt_lookup( rt, page_id );2869 page_xp = grdxt_remote_lookup( rt_xp , page_id ); 2315 2870 2316 2871 // check all existing pages 2317 if ( page != NULL ) 2318 { 2319 if ( page->flags & PG_DIRTY ) 2872 if ( page_xp != XPTR_NULL ) 2873 { 2874 // get page cluster and local pointer 2875 page_ptr = GET_PTR( page_xp ); 2876 2877 // get page flags 2878 flags = hal_remote_l32( XPTR( inode_cxy , &page_ptr->flags ) ); 2879 2880 if ( flags & PG_DIRTY ) 2320 2881 { 2321 2882 2322 2883 #if (DEBUG_FATFS_SYNC_INODE & 1) 2323 2884 if( DEBUG_FATFS_SYNC_INODE < cycle ) 2324 printk("\n[%s] thread[%x,%x] synchronizes page %d from<%s> mapper to IOC device\n",2885 printk("\n[%s] thread[%x,%x] synchronizes page %d of <%s> mapper to IOC device\n", 2325 2886 __FUNCTION__, page_id, name ); 2326 2887 #endif 2327 // build extended pointer on page descriptor2328 xptr_t page_xp = XPTR( local_cxy , page );2329 2330 2888 // move page from mapper to device 2331 2889 error = fatfs_move_page( page_xp , IOC_WRITE ); … … 2342 2900 cycle = (uint32_t)hal_get_cycles(); 2343 2901 if( DEBUG_FATFS_SYNC_INODE < cycle ) 2344 printk("\n[%s] thread[%x,%x] exit for <%s> / cycle %d\n",2345 __FUNCTION__ , this->process->pid, this->trdid, name , cycle);2902 printk("\n[%s] thread[%x,%x] exit for <%s>\n", 2903 __FUNCTION__ , this->process->pid, this->trdid, name ); 2346 2904 #endif 2347 2905 … … 2349 2907 2350 2908 } // end fatfs_sync_inode() 2351 2352 2353 2354 2355 2356 2909 2357 2910 ////////////////////////////// 2358 2911 error_t fatfs_sync_fat( void ) 2359 2912 { 2913 2914 fatfs_ctx_t * fatfs_ctx; 2915 cxy_t fat_cxy; 2916 mapper_t * mapper_ptr; 2917 xptr_t mapper_xp; 2918 uint32_t start_page_id; 2919 uint32_t found_page_id; 2920 page_t * page_ptr; 2921 xptr_t page_xp; 2922 uint32_t flags; 2923 error_t error; 2360 2924 2361 2925 #if DEBUG_FATFS_SYNC_FAT … … 2366 2930 __FUNCTION__ , this->process->pid, this->trdid, cycle ); 2367 2931 #endif 2368 2369 uint32_t page_id; 2370 error_t error; 2371 2372 // get FAT mapper pointers an cluster 2373 fatfs_ctx_t * fatfs_ctx = fs_context[FS_TYPE_FATFS].extend; 2374 xptr_t mapper_xp = fatfs_ctx->fat_mapper_xp; 2375 cxy_t mapper_cxy = GET_CXY( mapper_xp ); 2376 mapper_t * mapper_ptr = GET_PTR( mapper_xp ); 2377 2378 // compute max number of 4 Kbytes pages in FAT mapper 2379 // TODO : this could be improved (see fatfs.h) [AG] 2380 uint32_t pages = fatfs_ctx->fat_sectors_count >> 3; 2381 2932 2933 // get FAT cluster 2934 fat_cxy = CONFIG_VFS_ROOT_CXY; 2935 2936 // get FAT mapper pointers 2937 fatfs_ctx = fs_context[FS_TYPE_FATFS].extend; 2938 mapper_ptr = fatfs_ctx->fat_mapper; 2939 mapper_xp = XPTR( fat_cxy , mapper_ptr ); 2940 2382 2941 // get pointers on remote FAT mapper radix tree 2383 2942 grdxt_t * rt_ptr = &mapper_ptr->rt; 2384 xptr_t rt_xp = XPTR( mapper_cxy , rt_ptr ); 2385 2386 // scan all pages 2387 for( page_id = 0 ; page_id < pages ; page_id++ ) 2388 { 2389 // get extended pointer on page descriptor from FAT mapper 2390 xptr_t page_xp = grdxt_remote_lookup( rt_xp , page_id ); 2391 2392 // check all existing pages 2393 if ( page_xp != XPTR_NULL ) 2394 { 2395 page_t * page_ptr = GET_PTR( page_xp ); 2396 uint32_t flags = hal_remote_l32( XPTR( mapper_cxy , &page_ptr->flags ) ); 2397 2398 if ( flags & PG_DIRTY ) 2399 { 2943 xptr_t rt_xp = XPTR( fat_cxy , rt_ptr ); 2944 2945 // initialise page_id 2946 start_page_id = 0; 2947 2948 // scan FAT mapper 2949 while( 1 ) 2950 { 2951 // get one page 2952 page_xp = grdxt_remote_get_first( rt_xp , start_page_id , &found_page_id ); 2953 2954 // exit loop when no more page found 2955 if ( page_xp != XPTR_NULL ) break; 2956 2957 // get page flags 2958 page_ptr = GET_PTR( page_xp ); 2959 flags = hal_remote_l32( XPTR( fat_cxy , &page_ptr->flags ) ); 2960 2961 if ( flags & PG_DIRTY ) 2962 { 2400 2963 2401 2964 #if (DEBUG_FATFS_SYNC_FAT & 1) … … 2404 2967 __FUNCTION__, page_id ); 2405 2968 #endif 2406 // move page from mapper to device 2407 error = fatfs_move_page( page_xp , IOC_SYNC_WRITE ); 2408 2409 if ( error ) return -1; 2410 2411 // reset page dirty flag 2412 ppm_page_undo_dirty( page_xp ); 2413 } 2414 } 2969 // move page from mapper to device 2970 error = fatfs_move_page( page_xp , IOC_SYNC_WRITE ); 2971 2972 if ( error ) return -1; 2973 2974 // reset page dirty flag 2975 ppm_page_undo_dirty( page_xp ); 2976 } 2977 2978 // update loop variable 2979 start_page_id = found_page_id + 1; 2980 2415 2981 } // end loop on pages 2416 2982 … … 2418 2984 cycle = (uint32_t)hal_get_cycles(); 2419 2985 if( DEBUG_FATFS_SYNC_FAT < cycle ) 2420 printk("\n[%s] thread[%x,%x] exit / cycle %d\n",2421 __FUNCTION__ , this->process->pid, this->trdid , cycle);2986 printk("\n[%s] thread[%x,%x] exit\n", 2987 __FUNCTION__ , this->process->pid, this->trdid ); 2422 2988 #endif 2423 2989 … … 2425 2991 2426 2992 } // end fatfs_sync_fat() 2427 2428 ////////////////////////////////////2429 error_t fatfs_sync_free_info( void )2430 {2431 error_t error;2432 fatfs_ctx_t * fatfs_ctx_ptr; // local pointer on fatfs context in cluster 02433 uint32_t ctx_free_clusters; // number of free clusters from fatfs context2434 uint32_t ctx_free_cluster_hint; // free cluster hint from fatfs context2435 uint32_t ioc_free_clusters; // number of free clusters from fatfs context2436 uint32_t ioc_free_cluster_hint; // free cluster hint from fatfs context2437 uint32_t fs_info_lba; // lba of FS_INFO sector on IOC device2438 uint8_t * fs_info_buffer; // local pointer on FS_INFO buffer in cluster 02439 xptr_t fs_info_buffer_xp; // extended pointer on FS_INFO buffer in cluster 02440 uint8_t tmp_buf[512]; // 512 bytes temporary buffer2441 xptr_t tmp_buf_xp; // extended pointer on temporary buffer2442 2443 #if DEBUG_FATFS_SYNC_FSINFO2444 uint32_t cycle = (uint32_t)hal_get_cycles();2445 thread_t * this = CURRENT_THREAD;2446 if( DEBUG_FATFS_SYNC_FSINFO < cycle )2447 printk("\n[%s] thread[%x,%x] enter / cycle %d\n",2448 __FUNCTION__ , this->process->pid, this->trdid, cycle );2449 #endif2450 2451 // get pointer on fatfs context in cluster 02452 fatfs_ctx_ptr = hal_remote_lpt( XPTR( 0 , &fs_context[FS_TYPE_FATFS].extend ) );2453 2454 // get "free_clusters" and "free_cluster_hint" from fatfs context in cluster 02455 ctx_free_clusters = hal_remote_l32( XPTR( 0 , &fatfs_ctx_ptr->free_clusters ) );2456 ctx_free_cluster_hint = hal_remote_l32( XPTR( 0 , &fatfs_ctx_ptr->free_cluster_hint ) );2457 2458 // get fs_info_lba2459 fs_info_lba = hal_remote_l32( XPTR( 0 , &fatfs_ctx_ptr->fs_info_lba ) );2460 2461 // build extended pointer on temporary buffer2462 tmp_buf_xp = XPTR( local_cxy , tmp_buf );2463 2464 // copy FS_INFO sector from IOC to local buffer2465 error = dev_ioc_move_data( IOC_SYNC_READ , tmp_buf_xp , fs_info_lba , 1 );2466 2467 if ( error )2468 {2469 printk("\n[ERROR] in %s : cannot access FS_INFO on IOC device\n", __FUNCTION__ );2470 return -1;2471 }2472 2473 // get current values of "free_clusters" and "free_cluster_hint" from FS_INFO on IOC2474 ioc_free_clusters = fatfs_get_remote_record( FS_FREE_CLUSTERS , tmp_buf_xp );2475 ioc_free_cluster_hint = fatfs_get_remote_record( FS_FREE_CLUSTER_HINT , tmp_buf_xp );2476 2477 #if DEBUG_FATFS_SYNC_FSINFO2478 if( DEBUG_FATFS_SYNC_FSINFO < cycle )2479 printk("\n[%s] thread[%x,%x] / ctx_free %x / ioc_free %x / ctx_hint %x / ioc_hint %x\n",2480 __FUNCTION__ , this->process->pid, this->trdid,2481 ctx_free_clusters, ioc_free_clusters, ctx_free_cluster_hint, ioc_free_cluster_hint );2482 #endif2483 2484 // check values2485 if( (ioc_free_clusters != ctx_free_clusters) ||2486 (ioc_free_cluster_hint != ctx_free_cluster_hint) )2487 {2488 printk("\n[WARNING] in %s : unconsistent free clusters info\n"2489 " ioc_free %x / ctx_free %x / ioc_hint %x / ctx_hint %x\n",2490 __FUNCTION__, ioc_free_clusters, ctx_free_clusters,2491 ioc_free_cluster_hint, ctx_free_cluster_hint );2492 2493 // get pointers on FS_INFO buffer in cluster 02494 fs_info_buffer = hal_remote_lpt( XPTR( 0 , &fatfs_ctx_ptr->fs_info_buffer ) );2495 fs_info_buffer_xp = XPTR( 0 , fs_info_buffer );2496 2497 // update FS_INFO buffer in cluster 02498 fatfs_set_remote_record(FS_FREE_CLUSTERS ,fs_info_buffer_xp,ctx_free_clusters );2499 fatfs_set_remote_record(FS_FREE_CLUSTER_HINT,fs_info_buffer_xp,ctx_free_cluster_hint);2500 2501 // update the FS_INFO sector on IOC device2502 error = dev_ioc_move_data( IOC_SYNC_WRITE , fs_info_buffer_xp , fs_info_lba , 1 );2503 2504 if ( error )2505 {2506 printk("\n[ERROR] in %s : cannot update FS_INFO on IOC device\n", __FUNCTION__ );2507 return -1;2508 }2509 }2510 2511 #if DEBUG_FATFS_SYNC_FSINFO2512 cycle = (uint32_t)hal_get_cycles();2513 if( DEBUG_FATFS_SYNC_FSINFO < cycle )2514 printk("\n[%s] thread[%x,%x] exit / cycle %d\n",2515 __FUNCTION__ , this->process->pid, this->trdid, cycle );2516 #endif2517 2518 return 0;2519 2520 } // end fatfs_sync_free_info()2521 2522 //////////////////////////////////////////////////////////2523 error_t fatfs_cluster_alloc( uint32_t * searched_cluster )2524 {2525 error_t error;2526 uint32_t page_id; // page index in FAT mapper2527 uint32_t slot_id; // slot index in page (1024 slots per page)2528 uint32_t cluster; // first free cluster index in FAT2529 uint32_t free_clusters; // total number of free clusters2530 vfs_ctx_t * vfs_ctx; // local pointer on VFS context (same in all clusters)2531 fatfs_ctx_t * loc_fatfs_ctx; // local pointer on local FATFS context2532 fatfs_ctx_t * fat_fatfs_ctx; // local pointer on FATFS context in FAT cluster2533 xptr_t fat_mapper_xp; // extended pointer on FAT mapper2534 cxy_t fat_cxy; // Fat mapper cluster identifier2535 xptr_t page_xp; // extended pointer on current page descriptor in mapper2536 xptr_t slot_xp; // extended pointer on FAT slot defined by hint2537 xptr_t lock_xp; // extended pointer on lock protecting free clusters info2538 xptr_t hint_xp; // extended pointer on free_cluster_hint in FAT cluster2539 xptr_t free_xp; // extended pointer on free_clusters_number in FAT cluster2540 2541 #if DEBUG_FATFS_CLUSTER_ALLOC2542 uint32_t cycle = (uint32_t)hal_get_cycles();2543 thread_t * this = CURRENT_THREAD;2544 if( DEBUG_FATFS_CLUSTER_ALLOC < cycle )2545 printk("\n[%s] thread[%x,%x] enter / cycle = %d\n",2546 __FUNCTION__, this->process->pid, this->trdid, cycle );2547 #endif2548 2549 // get local pointer on VFS context (same in all clusters)2550 vfs_ctx = &fs_context[FS_TYPE_FATFS];2551 2552 // get local pointer on local FATFS context2553 loc_fatfs_ctx = vfs_ctx->extend;2554 2555 // get extended pointer on FAT mapper2556 fat_mapper_xp = loc_fatfs_ctx->fat_mapper_xp;2557 2558 // get FAT cluster2559 fat_cxy = GET_CXY( fat_mapper_xp );2560 2561 // get local pointer on FATFS context in FAT cluster2562 fat_fatfs_ctx = hal_remote_lpt( XPTR( fat_cxy , &vfs_ctx->extend ) );2563 2564 // build relevant extended pointers on free clusters info in mapper cluster2565 lock_xp = XPTR( fat_cxy , &fat_fatfs_ctx->lock );2566 hint_xp = XPTR( fat_cxy , &fat_fatfs_ctx->free_cluster_hint );2567 free_xp = XPTR( fat_cxy , &fat_fatfs_ctx->free_clusters );2568 2569 // take the FAT lock in write mode2570 remote_rwlock_wr_acquire( lock_xp );2571 2572 // get hint and free_clusters values from FATFS context in FAT cluster2573 cluster = hal_remote_l32( hint_xp ) + 1;2574 free_clusters = hal_remote_l32( free_xp );2575 2576 #if (DEBUG_FATFS_CLUSTER_ALLOC & 1)2577 if( DEBUG_FATFS_CLUSTER_ALLOC < cycle )2578 printk("\n[%s] thread[%x,%x] get free info : hint %x / free_clusters %x\n",2579 __FUNCTION__, this->process->pid, this->trdid, (cluster - 1), free_clusters );2580 #endif2581 2582 // check "free_clusters"2583 if ( free_clusters == 0 )2584 {2585 printk("\n[ERROR] in %s : no more free FATFS clusters\n", __FUNCTION__ );2586 remote_rwlock_wr_release( lock_xp );2587 return -1;2588 }2589 else if ( free_clusters < CONFIG_VFS_FREE_CLUSTERS_MIN )2590 {2591 printk("\n[WARNING] in %s : only %n free FATFS clusters\n",2592 __FUNCTION__, CONFIG_VFS_FREE_CLUSTERS_MIN );2593 }2594 2595 // get page index & slot index for selected cluster2596 page_id = cluster >> 10;2597 slot_id = cluster & 0x3FF;2598 2599 // get relevant page descriptor from FAT mapper2600 page_xp = mapper_remote_get_page( fat_mapper_xp , page_id );2601 2602 if( page_xp == XPTR_NULL )2603 {2604 printk("\n[ERROR] in %s : cannot acces FAT mapper\n", __FUNCTION__ );2605 remote_rwlock_wr_release( lock_xp );2606 return -1;2607 }2608 2609 // build extended pointer on selected cluster slot in FAT mapper2610 slot_xp = ppm_page2base( page_xp ) + (slot_id << 2);2611 2612 // check selected cluster actually free2613 if( hal_remote_l32( slot_xp ) != FREE_CLUSTER )2614 {2615 printk("\n[ERROR] in %s : selected cluster %x not free\n", __FUNCTION__, cluster );2616 remote_rwlock_wr_release( lock_xp );2617 return -1;2618 }2619 2620 // update free cluster info in FATFS context and in FS_INFO sector2621 error = fatfs_free_clusters_decrement( XPTR( fat_cxy , fat_fatfs_ctx ) , cluster );2622 2623 if( error )2624 {2625 printk("\n[ERROR] in %s : cannot update free cluster info\n", __FUNCTION__ );2626 remote_rwlock_wr_release( lock_xp );2627 return -1;2628 }2629 2630 // update FAT mapper2631 hal_remote_s32( slot_xp , END_OF_CHAIN_CLUSTER_MAX );2632 2633 // we don't mark the FAT mapper page as dirty,2634 // because we synchronously update FAT on IOC device2635 error = fatfs_move_page( page_xp , IOC_SYNC_WRITE );2636 2637 if( error )2638 {2639 printk("\n[ERROR] in %s : cannot update FAT on IOC device\n", __FUNCTION__ );2640 remote_rwlock_wr_release( lock_xp );2641 return -1;2642 }2643 2644 // release FAT lock2645 remote_rwlock_wr_release( lock_xp );2646 2647 #if DEBUG_FATFS_CLUSTER_ALLOC2648 cycle = (uint32_t)hal_get_cycles();2649 if( DEBUG_FATFS_CLUSTER_ALLOC < cycle )2650 printk("\n[%s] thread[%x,%x] exit / allocated cluster %x in FAT / cycle %d\n",2651 __FUNCTION__, this->process->pid, this->trdid, cluster, cycle );2652 #endif2653 2654 *searched_cluster = cluster;2655 return 0;2656 2657 } // end fatfs_cluster_alloc()2658 2993 2659 2994 ////////////////////////////////////////////// 2660 2995 error_t fatfs_release_inode( xptr_t inode_xp ) 2661 2996 { 2662 vfs_ctx_t * vfs_ctx; // local pointer on VFS context (same in all clusters).2663 fatfs_ctx_t * loc_fatfs_ctx; // local pointer on local FATFS context2664 cxy_t fat_cxy; // FAT cluster identifier2665 xptr_t fatfs_ctx_xp; // extended pointer on FATFScontext in FAT cluster2666 fatfs_ctx_t * fatfs_ctx_ptr; // local pointer on FATFS context in FAT cluster2667 xptr_t fat_mapper_xp; // extended pointer on FAT mapper2668 xptr_t lock_xp; // extended pointer on lock protecting FAT.2669 xptr_t first_xp; // extended pointer on inode extension2670 uint32_t first_cluster ; // first cluster index for released inode2671 vfs_inode_t * inode_ptr; // local pointer on target inode2672 cxy_t inode_cxy; // target inode cluster identifier2997 vfs_ctx_t * vfs_ctx; // local pointer on VFS context (same in all clusters) 2998 cxy_t fat_cxy; // FAT cluster identifier 2999 fatfs_ctx_t * fatfs_ctx_ptr; // local pointer on FATFS context in FAT cluster 3000 xptr_t fatfs_ctx_xp; // extended pointer on FATFS-context in FAT cluster 3001 mapper_t * fat_mapper_ptr; // local pointer on FAT mapper 3002 xptr_t fat_mapper_xp; // extended pointer on FAT mapper 3003 xptr_t lock_xp; // extended pointer on lock protecting FAT. 3004 xptr_t first_xp; // extended pointer on inode extension 3005 uint32_t first_cluster_id; // first cluster index for released inode 3006 vfs_inode_t * inode_ptr; // local pointer on target inode 3007 cxy_t inode_cxy; // target inode cluster identifier 2673 3008 error_t error; 2674 3009 … … 2680 3015 inode_cxy = GET_CXY( inode_xp ); 2681 3016 2682 // get first_cluster from inode extension2683 first_xp = XPTR( inode_cxy , &inode_ptr->extend );2684 first_cluster = (uint32_t)(intptr_t)hal_remote_lpt( first_xp );3017 // get first_cluster_id from inode extension 3018 first_xp = XPTR( inode_cxy , &inode_ptr->extend ); 3019 first_cluster_id = (uint32_t)(intptr_t)hal_remote_lpt( first_xp ); 2685 3020 2686 3021 // check first cluster index 2687 assert( (first_cluster != 0) , "inode extend is NULL\n" );3022 assert( (first_cluster_id != 0) , "inode extend is NULL\n" ); 2688 3023 2689 3024 #if DEBUG_FATFS_RELEASE_INODE … … 2693 3028 vfs_inode_get_name( inode_xp , name ); 2694 3029 if( DEBUG_FATFS_RELEASE_INODE < cycle ) 2695 printk("\n[%s] thread[%x,%x] enter for <%s> / first_cluster %x / cycle %d\n",2696 __FUNCTION__ , this->process->pid, this->trdid, name, first_cluster , cycle );3030 printk("\n[%s] thread[%x,%x] enter for <%s> / first_cluster_id %x / cycle %d\n", 3031 __FUNCTION__ , this->process->pid, this->trdid, name, first_cluster_id, cycle ); 2697 3032 #endif 2698 3033 … … 2700 3035 vfs_ctx = &fs_context[FS_TYPE_FATFS]; 2701 3036 2702 // get local pointer on local FATFS context 2703 loc_fatfs_ctx = vfs_ctx->extend; 2704 2705 // get FAT mapper cluster 2706 fat_mapper_xp = loc_fatfs_ctx->fat_mapper_xp; 2707 fat_cxy = GET_CXY( fat_mapper_xp ); 3037 // get FAT cluster 3038 fat_cxy = CONFIG_VFS_ROOT_CXY; 3039 3040 // get pointers on FATFS context in FAT cluster 3041 fatfs_ctx_ptr = hal_remote_lpt( XPTR( fat_cxy , &vfs_ctx->extend ) ); 3042 fatfs_ctx_xp = XPTR( fat_cxy , fatfs_ctx_ptr ); 3043 3044 // get FAT mapper pointers 3045 fat_mapper_ptr = hal_remote_lpt( XPTR( fat_cxy , &fatfs_ctx_ptr->fat_mapper ) ); 3046 fat_mapper_xp = XPTR( fat_cxy , fat_mapper_ptr ); 2708 3047 2709 // get pointers on FATFS context in FAT cluster 2710 fatfs_ctx_ptr = hal_remote_lpt( XPTR( fat_cxy , &vfs_ctx->extend ) ); 2711 fatfs_ctx_xp = XPTR( fat_cxy , fatfs_ctx_ptr ); 2712 2713 // get extended pointer on FAT lock in FAT cluster 3048 // build extended pointer on FAT lock in FAT cluster 2714 3049 lock_xp = XPTR( fat_cxy , &fatfs_ctx_ptr->lock ); 2715 3050 … … 2727 3062 if ( fatfs_recursive_release( fat_mapper_xp, 2728 3063 fatfs_ctx_xp, 2729 first_cluster ,3064 first_cluster_id, 2730 3065 &dirty_page_min, 2731 3066 &dirty_page_max ) ) … … 2791 3126 } // end fatfs_release_inode() 2792 3127 2793 //////////////////////////////////////////// 2794 error_t fatfs_move_page( xptr_t page_xp, 2795 cmd_type_t cmd_type ) 2796 { 2797 error_t error; 3128 ///////////////////////////////////////////////// 3129 error_t fatfs_move_page( xptr_t page_xp, 3130 ioc_cmd_type_t cmd_type ) 3131 { 3132 error_t error = 0; 3133 2798 3134 vfs_inode_t * inode_ptr; 2799 3135 mapper_t * mapper_ptr; … … 2829 3165 #if DEBUG_FATFS_MOVE_PAGE 2830 3166 if( DEBUG_FATFS_MOVE_PAGE < cycle ) 2831 printk("\n[%s] thread[%x,%x] enters for %s /page %d in FAT mapper / cycle %d\n",3167 printk("\n[%s] thread[%x,%x] enters %s for page %d in FAT mapper / cycle %d\n", 2832 3168 __FUNCTION__, this->process->pid, this->trdid, dev_ioc_cmd_str(cmd_type), page_id, cycle ); 2833 3169 #endif … … 2836 3172 2837 3173 // access IOC device 2838 error = dev_ioc_move_data( cmd_type , buffer_xp , lba , 8 ); 3174 if (cmd_type == IOC_SYNC_WRITE) error = dev_ioc_sync_write( buffer_xp, lba, 8 ); 3175 else if(cmd_type == IOC_SYNC_READ ) error = dev_ioc_sync_read( buffer_xp, lba, 8 ); 3176 else 3177 { 3178 printk("\n[ERROR] in %s : illegal asynchronous FAT access\n", __FUNCTION__ ); 3179 } 2839 3180 2840 3181 if( error ) 2841 3182 { 2842 printk("\n[ERROR] in %s : cannot access device\n", __FUNCTION__ );3183 printk("\n[ERROR] in %s : cannot access IOC device\n", __FUNCTION__ ); 2843 3184 return -1; 2844 3185 } … … 2846 3187 #if DEBUG_FATFS_MOVE_PAGE 2847 3188 if( DEBUG_FATFS_MOVE_PAGE < cycle ) 2848 printk("\n[%s] thread[%x,%x] exit /page %d in FAT mapper\n",2849 __FUNCTION__, this->process->pid, this->trdid, page_id, cycle);3189 printk("\n[%s] thread[%x,%x] exit %s for page %d in FAT mapper\n", 3190 __FUNCTION__, this->process->pid, this->trdid, dev_ioc_cmd_str(cmd_type), page_id ); 2850 3191 #endif 2851 3192 … … 2856 3197 2857 3198 #if DEBUG_FATFS_MOVE_PAGE 2858 vfs_inode_get_name( XPTR( page_cxy , inode_ptr ) , name );2859 3199 if( DEBUG_FATFS_MOVE_PAGE < cycle ) 2860 printk("\n[%s] thread[%x,%x] enters for %s / page %d in <%s> mapper/ cycle %d\n", 2861 __FUNCTION__, this->process->pid, this->trdid, 2862 dev_ioc_cmd_str( cmd_type ), page_id, name, cycle ); 3200 { 3201 vfs_inode_get_name( XPTR( page_cxy , inode_ptr ) , name ); 3202 printk("\n[%s] thread[%x,%x] enters %s for page %d in <%s> mapper / cycle %d\n", 3203 __FUNCTION__, this->process->pid, this->trdid, 3204 dev_ioc_cmd_str( cmd_type ), page_id, name, cycle ); 3205 } 2863 3206 #endif 2864 3207 … … 2893 3236 uint32_t lba = fatfs_lba_from_cluster( fatfs_ctx , searched_cluster_id ); 2894 3237 2895 // access IOC device to move 8 blocks 2896 error = dev_ioc_move_data( cmd_type , buffer_xp , lba , 8 ); 3238 // access IOC device 3239 if (cmd_type == IOC_WRITE ) error = dev_ioc_write( buffer_xp, lba, 8 ); 3240 else if(cmd_type == IOC_READ ) error = dev_ioc_read( buffer_xp, lba, 8 ); 3241 else if(cmd_type == IOC_SYNC_READ ) error = dev_ioc_sync_read( buffer_xp, lba, 8 ); 3242 else if(cmd_type == IOC_SYNC_WRITE) error = dev_ioc_sync_write( buffer_xp, lba, 8 ); 3243 else 3244 { 3245 printk("\n[ERROR] in %s : illegal cmd_type\n", __FUNCTION__ ); 3246 } 2897 3247 2898 3248 if( error ) … … 2904 3254 #if DEBUG_FATFS_MOVE_PAGE 2905 3255 if( DEBUG_FATFS_MOVE_PAGE < cycle ) 2906 vfs_inode_get_name( XPTR( page_cxy, inode_ptr ) , name ); 2907 printk("\n[%s] thread[%x,%x] exit / page %d in <%s> mapper / cluster_id %x\n", 2908 __FUNCTION__, this->process->pid, this->trdid, page_id, name, searched_cluster_id ); 3256 { 3257 printk("\n[%s] thread[%x,%x] exit %s for page %d in <%s> mapper / cluster_id %x\n", 3258 __FUNCTION__, this->process->pid, this->trdid, 3259 dev_ioc_cmd_str( cmd_type ), page_id, name, searched_cluster_id ); 3260 } 3261 #endif 3262 3263 #if (DEBUG_FATFS_MOVE_PAGE & 1) 3264 if( DEBUG_FATFS_MOVE_PAGE < cycle ) 3265 fatfs_display_fat( searched_cluster_id , 64 ); 2909 3266 #endif 2910 3267 -
trunk/kernel/fs/fatfs.h
r656 r657 2 2 * fatfs.h - FATFS file system API definition. 3 3 * 4 * Author Mohamed Lamine Karaoui (2014,2015) 5 * Alain Greiner (2016,2017,2018) 4 * Author Alain Greiner (2016,2017,2018,2019,2020) 6 5 * 7 6 * Copyright (c) UPMC Sorbonne Universites … … 27 26 28 27 #include <hal_kernel_types.h> 29 #include <remote_ queuelock.h>28 #include <remote_rwlock.h> 30 29 #include <vfs.h> 31 30 #include <dev_ioc.h> … … 36 35 * 37 36 * The FATFS specific extensions to the generic VFS are the following: 38 * 1) The vfs_ctx_t "extend" field is a void* pointing on the fatfs_ctx_t structure. 39 * This structure contains various general informations such as the total 40 * number of sectors in FAT region, the number of bytes per sector, the number 41 * of sectors per cluster, the lba of FAT region, the lba of data region, or the 42 * cluster index for the root directory. It contains also an extended pointer 43 * on the FAT mapper. 37 * 1) The vfs_ctx_t "extend" field contains a local pointer on the local 38 * fatfs_ctx_t structure. 39 * 44 40 * 2) The vfs_inode_t "extend" contains, for each inode, 45 * the first FAT32 cluster_id (after cast to intptr). 46 * 3) The vfs_dentry_t "extend" field contains, for each dentry, the entry index 47 * in the FATFS directory (32 bytes per FATFS directory entry). 41 * the first FATFS cluster_id (after cast to intptr). 42 * 43 * 3) The vfs_dentry_t "extend" field contains a local pointer on the local 44 * FATFS directory entry (32 bytes) in the directory mapper. 48 45 * 49 46 * In the FAT32 File System, the File Allocation Table is is actually an array … … 57 54 *****************************************************************************************/ 58 55 59 ///////////////////////////////////////////////////////////////////////////////////////////60 61 56 /*************** Partition Boot Sector Format **********************************/ 62 57 // offset | length … … 182 177 * This structure defines a FATFS specific context extension to the VFS context. 183 178 * This fatfs context is replicated in all clusters. 179 * It contains read-only informations such as the total number of sectors in FAT region, 180 * the number of bytes per sector, the number of sectors per cluster, the lba of FAT, 181 * the lba of data region, the cluster_id for the root directory, and an extended 182 * pointer on the FAT mapper. 184 183 * 185 184 * WARNING 1 : All access to the FAT are protected by a remote_rwlock. … … 189 188 * functions to modify the FAT in both the FAT mapper and on IOC device. 190 189 * 191 * WARNING 2 : Most fields are constant values, but the <free_cluster_hint>,192 * < free_clusters>, <lock>, and the <fs_info_buffer> are shared variables,193 * that can be modified by any thread running in any cluster. The <fs_info_buffer>194 * contains a copy of the FS_INFO sector, and is only allocated in the FAT cluster195 * (cluster 0).It is used to synchronously update the free clusters info on IOC device.190 * WARNING 2 : Most fields are constant values, but <free_cluster_hint>, <free_clusters>, 191 * <lock>, and the buffer pointed by the <fs_info_xp> are shared variables, that can 192 * modified by any thread running in any cluster. The <fs_info_buffer> contains 193 * a copy of the FS_INFO sector, and is only allocated in the FAT cluster. 194 * It is used to synchronously update the free clusters info on IOC device. 196 195 * => For all these variables, only the values stored in the FAT cluster must be used. 197 196 ****************************************************************************************/ … … 207 206 uint32_t fs_info_lba; /*! lba of FS_INFO sector */ 208 207 uint32_t root_dir_cluster; /*! cluster index for root directory */ 209 xptr_t fat_mapper_xp; /*! extended pointer on FAT mapper*/208 struct mapper_s * fat_mapper; /*! local pointer on FAT mapper */ 210 209 211 210 /* shared variables (only the copy in FAT cluster must be used) */ 212 uint32_t free_cluster_hint; /*! cluster[hint+1] is the first free*/213 uint32_t free_clusters; /*! free clusters number*/211 uint32_t free_cluster_hint; /*! free_cluster_hint + 1 is first free */ 212 uint32_t free_clusters; /*! number of free clusters */ 214 213 remote_rwlock_t lock; /*! exclusive access to FAT */ 215 214 uint8_t * fs_info_buffer; /*! local pointer on FS_INFO buffer */ … … 224 223 * This debug function display the content of the FATFS context copy in cluster 225 224 * identified by the <cxy> argument. 226 * This function can be called by a thread running in any cluster.225 * This function can be called by any thread running in any cluster. 227 226 ***************************************************************************************** 228 227 * @ cxy : target cluster identifier. … … 232 231 /***************************************************************************************** 233 232 * This debug function access the FAT mapper to display the current FAT state, 234 * as defined by the < page_id>, <min_slot>, and <nb_slots> arguments.235 * It loads the missing pages from IOC to mapper if required.236 * This function can be called by a thread running in any cluster.237 * ****************************************************************************************238 * @ page_id : page index in FAT mapper (one page is 4 Kbytes = 1024 slots).239 * @ min_slot : first slot in page240 * @ nb_slots : number of slots (one slot is 4 bytes).241 * ***************************************************************************************/242 void fatfs_display_fat( uint32_t page_id, 243 233 * as defined by the <min_slot>, and <nb_slots> arguments. 234 * It display as many lines (8 slots par line) as required to display <nb_slots>, 235 * starting from the <min_slot>. The displayed slots can spread on several FAT mapper 236 * pages. It loads the missing pages from IOC to mapper if required. 237 * This function can be called by any thread running in any cluster. 238 ***************************************************************************************** 239 * @ min_slot : first FATFS cluster index. 240 * @ nb_slots : number of slots (one slot is 4 bytes. 241 ****************************************************************************************/ 242 void fatfs_display_fat( uint32_t min_slot, 244 243 uint32_t nb_slots ); 245 244 245 /***************************************************************************************** 246 * This function checks the current values of the "free_clusters" and "free_cluster_hint" 247 * variables in the FS_INFO sector on IOC, versus the values stored in the fatfs context. 248 * As these values are synchronously updated on IOC device at each modification, 249 * it does nothing if the values are equal. It updates the FS_INFO sector on IOC device, 250 * and displays a warning message on TXT0 if they are not equal. 251 * This function can be called by any thread running in any cluster. 252 ***************************************************************************************** 253 * @ return 0 if success / return -1 if failure during IOC device access. 254 ****************************************************************************************/ 255 error_t fatfs_check_free_info( void ); 246 256 247 257 ////////////////////////////////////////////////////////////////////////////////////////// … … 251 261 252 262 /***************************************************************************************** 253 * This fuction allocates memory from local cluster for a FATFS context descriptor. 254 ***************************************************************************************** 255 * @ return a pointer on the created context / return NULL if failure. 256 ****************************************************************************************/ 257 fatfs_ctx_t * fatfs_ctx_alloc( void ); 258 259 /***************************************************************************************** 260 * This function access the boot device, and initialises the local FATFS context, 261 * from informations contained in the boot record. This initialisation includes the 262 * creation of the FAT mapper in cluster 0. 263 ***************************************************************************************** 264 * @ vfs_ctx : local pointer on VFS context for FATFS. 265 ****************************************************************************************/ 266 void fatfs_ctx_init( fatfs_ctx_t * fatfs_ctx ); 267 268 /***************************************************************************************** 269 * This function releases memory dynamically allocated for the FATFS context extension. 270 ***************************************************************************************** 271 * @ vfs_ctx : local pointer on VFS context. 272 ****************************************************************************************/ 273 void fatfs_ctx_destroy( fatfs_ctx_t * fatfs_ctx ); 263 * This fuction allocates memory for a FATFS context descriptor in a cluster 264 * identified by the <cxy> argument. 265 ***************************************************************************************** 266 * @ cxy : target cluster identifier. 267 * @ return an extended pointer on the created context / return XPTR_NULL if failure. 268 ****************************************************************************************/ 269 xptr_t fatfs_ctx_alloc( cxy_t cxy ); 270 271 /***************************************************************************************** 272 * This fuction initialize a fatfs context identified by the <fatfs_ctx_xp> argument 273 * from informations found in the IOC device boot record. This initialisation includes 274 * allocation of the FS_INFO buffer and creation of the FAT mapper in the same cluster. 275 ***************************************************************************************** 276 * @ fatfs_ctx_xp : extended pointer on fatfs context. 277 * @ return 0 if success / return -1 if failure. 278 ****************************************************************************************/ 279 error_t fatfs_ctx_init( xptr_t fatfs_ctx_xp ); 280 281 /***************************************************************************************** 282 * This function releases memory dynamically allocated for the FATFS context. 283 ***************************************************************************************** 284 * @ vfs_ctx_xp : extended pointer on FATFS context. 285 ****************************************************************************************/ 286 void fatfs_ctx_destroy( xptr_t fatfs_ctx_xp ); 274 287 275 288 /***************************************************************************************** 276 289 * This function implements the generic vfs_fs_add_dentry() function for the FATFS. 277 290 ***************************************************************************************** 278 * This function updates a directory mapper identified by the <inode> argument 279 * to add a new directory entry identified by the <dentry> argument. 291 * This function introduces in a directory mapper identified by the <parent_inode_xp> 292 * argument a new directory entry identified by the <dentry_ptr> argument. 293 * The dentry descriptor and the associated inode descriptor must have been previously 294 * allocated, initialized, and registered in the Inode Tree. 295 * The dentry descriptor defines the "name" field. 296 * The inode descriptor defines the "type", "size", and "cluster_id" fields. 297 * The "extension field" in dentry descriptor is set : index in the FAT32 directory. 280 298 * All modified pages in the directory mapper are synchronously updated on IOC device. 281 * It must be called by a thread running in the cluster containing the directory inode.299 * This function can be called by any thread running in any cluster. 282 300 * 283 301 * Implementation note : this function works in two steps: … … 285 303 * to find the end of directory (NO_MORE_ENTRY marker). 286 304 * - Then it writes 3, 4, or 5 directory entries (depending on the name length), using 287 * a 5 steps FSM (one state per entry to be written), updates on IOC device the288 * modified pages , and updates the dentry extension field, that must contain289 * the dentry index in FATFS directory.290 * ****************************************************************************************291 * @ inode : local pointer on directory inode.292 * @ dentry : local pointer on dentry.293 * @ return 0 if success / return ENOENT if not found, or EIO if no access to IOC device.294 ****************************************************************************************/ 295 error_t fatfs_add_dentry( struct vfs_inode_s * inode,296 struct vfs_dentry_s * dentry );305 * a 5 steps FSM (one state per entry to be written), and updates on IOC device the 306 * modified pages. 307 ***************************************************************************************** 308 * @ parent_inode_xp : [in] extended pointer on parent directory inode. 309 * @ dentry_ptr : [in] local pointer on dentry (in parent directory cluster). 310 * @ index : [out] index of the new entry in the FAT32 directory. 311 * @ return 0 if success / return -1 if failure. 312 ****************************************************************************************/ 313 error_t fatfs_add_dentry( xptr_t parent_inode_xp, 314 struct vfs_dentry_s * dentry_ptr ); 297 315 298 316 /***************************************************************************************** 299 317 * This function implements the generic vfs_fs_remove_dentry() function for the FATFS. 300 318 ***************************************************************************************** 301 * This function updates a directory identified by the < inode> argument302 * to remove a directory entry identified by the <dentry > argument.319 * This function updates a directory identified by the <parent_inode_xp> argument 320 * to remove a directory entry identified by the <dentry_ptr> argument. 303 321 * All modified pages in directory mapper are synchronously updated on IOC device. 304 * It must be called by a thread running in the cluster containing the inode.322 * This function can be called by any thread running in any cluster. 305 323 * 306 324 * Implementation note: this function uses the dentry extension to directly access … … 308 326 * updates the modified pages on IOC device. 309 327 ***************************************************************************************** 310 * @ inode : local pointer on directory inode. 311 * @ dentry : local pointer on dentry. 312 * @ return 0 if success / return ENOENT if not found, or EIO if no access to IOC device. 313 ****************************************************************************************/ 314 error_t fatfs_remove_dentry( struct vfs_inode_s * inode, 315 struct vfs_dentry_s * dentry ); 316 317 /***************************************************************************************** 318 * This function implements the generic vfs_fs_new_dentry() function for the FATFS. 319 ***************************************************************************************** 320 * It scan a parent directory mapper, identified by the <parent_inode> argument to find 321 * a directory entry identified by the <name> argument. In case of success, it completes 322 * initialization the inode/dentry couple, identified by the <child_inode_xp> argument. 323 * The child inode descriptor, and the associated dentry descriptor must have been 324 * previously allocated by the caller. 328 * @ parent_inode_xp : [in] extended pointer on parent directory inode. 329 * @ dentry_ptr : [in] local pointer on dentry (in parent directory cluster). 330 * @ return 0 if success / return -1 if failure. 331 ****************************************************************************************/ 332 error_t fatfs_remove_dentry( xptr_t parent_inode_xp, 333 struct vfs_dentry_s * dentry_ptr ); 334 335 /***************************************************************************************** 336 * This function implements the generic vfs_fs_new_dentry_from_mapper() for the FATFS. 337 ***************************************************************************************** 338 * It scan a parent directory mapper, identified by the <parent_inode_xp> argument 339 * to find a directory entry name defined by the <dentry_ptr> argument, and completes 340 * the initialization of the dentry and the associated child_inode descriptors, 341 * from informations found in the parent directory mapper : 325 342 * - It set the "type", "size", and "extend" fields in the child inode descriptor. 326 343 * - It set the " extend" field in the dentry descriptor. 327 * It must be called by a thread running in the cluster containing the parent inode. 328 ***************************************************************************************** 329 * @ parent_inode : local pointer on parent inode (directory). 330 * @ name : child name. 331 * @ child_inode_xp : extended pointer on remote child inode (file or directory). 344 * The child inode descriptor, and the dentry descriptor must have been previously 345 * allocated and introduced in the Inode Tree. 346 * This function can be called by any thread running in any cluster. 347 ***************************************************************************************** 348 * @ parent_inode_xp : extended pointer on parent inode (directory). 349 * @ dentry_ptr : local pointer on new dentry (in parent inode cluster). 350 * @ return 0 if success / return -1 if failure. 351 ****************************************************************************************/ 352 error_t fatfs_new_dentry_from_mapper( xptr_t parent_inode_xp, 353 struct vfs_dentry_s * dentry_ptr ); 354 355 /***************************************************************************************** 356 * This function implements the generic vfs_fs_new_dentry_to_mapper() for the FATFS. 357 ***************************************************************************************** 358 * This function introduces a brand new dentry identified by the <dentry_ptr> argument 359 * in the mapper of a directory identified by the <parent_inode_xp> argument. 360 * It is called by the vfs_lookup() function. 361 * The child inode descriptor, and the dentry descriptor must have been previously 362 * allocated and introduced in the Inode Tree. The dentry descriptor contains the name. 363 * 1. It allocates a new FATFS cluster_id, 364 * 2. It registers the allocated cluster_id in the child inode extension, 365 * 3. It add a new entry (32 bytes) in the directory mapper, 366 * This function can be called by any thread running in any cluster. 367 ***************************************************************************************** 368 * @ parent_inode_xp : [in] extended pointer on parent inode (directory). 369 * @ dentry_ptr : [in] local pointer on dentry (in parent inode cluster). 370 * @ return 0 if success / return -1 if failure. 371 ****************************************************************************************/ 372 error_t fatfs_new_dentry_to_mapper( xptr_t parent_inode_xp, 373 struct vfs_dentry_s * dentry_ptr ); 374 375 /***************************************************************************************** 376 * This function implements the generic vfs_fs_update_dentry() function for the FATFS. 377 ***************************************************************************************** 378 * It update the "size" of a directory entry identified by the <dentry_ptr> argument in 379 * the mapper of a directory identified by the <parent_inode_xp> argument, from the 380 * value registered in the inode descriptor. 381 * It scan the directory mapper to find the entry such as name == dentry_ptr->name. 382 * It set the "size" field in the directory mapper, and updates the modified directory 383 * page on the IOC device. 384 * This function can be called by any thread running in any cluster. 385 * 386 * TODO the current implementation uses the fatfs_scan_directory to access the 387 * FAT32 directory by name. We can access directly this directory entry if we use 388 * the dentry "extend" field... 389 ***************************************************************************************** 390 * @ parent_inode_xp : extended pointer on inode (directory). 391 * @ dentry_ptr : local pointer on dentry (in parent directory cluster). 332 392 * @ return 0 if success / return -1 if child not found. 333 393 ****************************************************************************************/ 334 error_t fatfs_new_dentry( struct vfs_inode_s * parent_inode, 335 char * name, 336 xptr_t child_inode_xp ); 337 338 /***************************************************************************************** 339 * This function implements the generic vfs_fs_update_dentry() function for the FATFS. 340 ***************************************************************************************** 341 * It update the size of a directory entry identified by the <dentry> argument in 342 * the mapper of a directory identified by the <inode> argument, as defined by the 343 * <size> argument. 344 * It scan the mapper to find the entry identified by the dentry "name" field. 345 * It set the "size" field in the in the directory mapper AND marks the page as DIRTY. 346 * It must be called by a thread running in the cluster containing the directory inode. 347 ***************************************************************************************** 348 * @ inode : local pointer on inode (directory). 349 * @ dentry : local pointer on dentry (for name). 350 * @ size : new size value. 351 * @ return 0 if success / return ENOENT if child not found. 352 ****************************************************************************************/ 353 error_t fatfs_update_dentry( struct vfs_inode_s * inode, 354 struct vfs_dentry_s * dentry, 355 uint32_t size ); 394 error_t fatfs_update_dentry( xptr_t parent_inode_xp, 395 struct vfs_dentry_s * dentry_ptr ); 356 396 357 397 /***************************************************************************************** … … 367 407 * the Inode Tree is dynamically created, and all dirent fields are documented in the 368 408 * dirent array. Otherwise, only the dentry name is documented. 369 * It must be called by a thread running in the cluster containing the directory inode. 370 ***************************************************************************************** 371 * @ inode : [in] local pointer on directory inode. 409 * 410 * WARNING : It must be called by a thread running in the cluster containing the 411 * target directory inode. 412 ***************************************************************************************** 413 * @ parent_inode_xp : [in] extended pointer on directory inode. 372 414 * @ array : [in] local pointer on array of dirents. 373 415 * @ max_dirent : [in] max number of slots in dirent array. … … 390 432 ***************************************************************************************** 391 433 * It updates the FATFS on the IOC device for a given inode identified by 392 * the <inode > argument. It scan all pages registered in the associated mapper,434 * the <inode_xp> argument. It scan all pages registered in the associated mapper, 393 435 * and copies from mapper to device each page marked as dirty. 394 436 * WARNING : The target <inode> cannot be a directory, because all modifications in a 395 437 * directory are synchronously done on the IOC device by the two fatfs_add_dentry() 396 438 * and fatfs_remove_dentry() functions. 397 ***************************************************************************************** 398 * @ inode : local pointer on inode. 399 * @ return 0 if success / return -1 if failure during IOC device access. 400 ****************************************************************************************/ 401 error_t fatfs_sync_inode( struct vfs_inode_s * inode ); 439 * This function can be called by any thread running in any cluster. 440 ***************************************************************************************** 441 * @ inode_xp : extended pointer on inode. 442 * @ return 0 if success / return -1 if failure. 443 ****************************************************************************************/ 444 error_t fatfs_sync_inode( xptr_t inode_xp ); 402 445 403 446 /***************************************************************************************** … … 407 450 * It scan all clusters registered in the FAT mapper, and copies from mapper to device 408 451 * each page marked as dirty. 409 * 410 * TODO : the current implementation check ALL pages in the FAT region, even if most 411 * pages are empty, and not copied in mapper. It is sub-optimal. 412 * A solution is to maintain in the FAT context two "dirty_min" and "dirty_max" 413 * variables defining the smallest/largest dirty page index in FAT mapper... 452 * This function can be called by any thread running in any cluster. 453 * 454 * Implementation note : this function uses the grdxt_remote_get_first() function 455 * to test only the pages actually registered in the FAT mapper. 414 456 ***************************************************************************************** 415 457 * @ return 0 if success / return -1 if failure during IOC device access. … … 418 460 419 461 /***************************************************************************************** 420 * This function implements the generic vfs_fs_sync_fsinfo() function for the FATFS.421 *****************************************************************************************422 * It checks the current values of the "free_clusters" and "free_cluster_hint" variables423 * in the FS_INFO sector on IOC, versus the values stored in the fatfs context.424 * As these values are synchronously updated on IOC device at each modification,425 * it does nothing if the values are equal. It updates the FS_INFO sector on IOC device,426 * and displays a warning message on TXT0 if they are not equal.427 * This function can be called by any thread running in any cluster.428 *****************************************************************************************429 * @ return 0 if success / return -1 if failure during IOC device access.430 ****************************************************************************************/431 error_t fatfs_sync_free_info( void );432 433 /*****************************************************************************************434 * This function implements the generic vfs_fs_cluster_alloc() function for the FATFS.435 *****************************************************************************************436 * It access the FAT (File allocation table), stored in the FAT mapper, and returns437 * in <searched_cluster> the FATFS cluster index of a free cluster.438 * It can be called by a thread running in any cluster, as it uses remote access439 * primitives when the FAT mapper is remote. It takes the rwlock stored in the FATFS440 * context located in the same cluster as the FAT mapper itself, to get exclusive441 * access to the FAT. It uses and updates the <free_cluster_hint> and <free_clusters>442 * variables stored in this FATFS context.443 * - it updates the <free_cluster_hint> and <free_clusters> variables in FATFS context.444 * - it updates the FAT mapper (handling miss from IOC device if required).445 * - it synchronously updates the FAT region on IOC device.446 * - it returns the allocated cluster index.447 *****************************************************************************************448 * @ searched_cluster_id : [out] allocated FATFS cluster index.449 * @ return 0 if success / return -1 if no more free clusters on IOC device.450 ****************************************************************************************/451 error_t fatfs_cluster_alloc( uint32_t * searched_cluster_id );452 453 /*****************************************************************************************454 462 * This function implements the generic vfs_fs_release_inode() function for the FATFS. 455 463 ***************************************************************************************** 456 * This function is used to remove a given file or directory from FATFS thefile system.464 * This function is used to remove a given file or directory from the FATFS file system. 457 465 * It releases all clusters allocated to a file/directory identified by the <inode_xp> 458 466 * argument. All released clusters are marked FREE_CLUSTER in the FAT mapper. … … 462 470 * synchronously update all modified pages in the FAT mapper to the IOC device. 463 471 * Finally the FS-INFO sector on the IOC device is updated. 472 * This function can be called by any thread running in any cluster. 464 473 ***************************************************************************************** 465 474 * @ inode_xp : extended pointer on inode. … … 478 487 * - For a regular file, it scan the FAT mapper to get the cluster_id on IOC device, 479 488 * and read/write this cluster. 480 * Itcan be called by any thread running in any cluster.489 * This function can be called by any thread running in any cluster. 481 490 * 482 491 * WARNING : For the FAT mapper, the inode field in the mapper MUST be NULL, as this 483 492 * is used to indicate that the corresponding mapper is the FAT mapper. 484 *485 * TODO : In this first implementation, the entry point in the FAT to get the cluster_id486 * is always the cluster_id of the first page, registered in the inode extension.487 * This can introduce a quadratic cost when trying of acessing all pages of a488 * big file. An optimisation would be to introduce in the inode extension two489 * new fields <other_page_id> & <other_cluster_id>, defining a second entry point490 * in the FAT.491 493 ***************************************************************************************** 492 494 * @ page_xp : extended pointer on page descriptor. … … 494 496 * @ return 0 if success / return EIO if error during device access. 495 497 ****************************************************************************************/ 496 error_t fatfs_move_page( xptr_t page_xp,497 cmd_type_t cmd_type );498 error_t fatfs_move_page( xptr_t page_xp, 499 ioc_cmd_type_t cmd_type ); 498 500 499 501 -
trunk/kernel/fs/ramfs.h
r188 r657 3 3 * 4 4 * Authors Mohamed Lamine Karaoui (2014,2015) 5 * Alain Greiner (2016,2017 )5 * Alain Greiner (2016,2017,2018,2019,2020) 6 6 * 7 7 * Copyright (c) UPMC Sorbonne Universites … … 29 29 // The RAMFS File System does not uses any external device to store data. 30 30 // It stores the dynamically created files and directories in the VFS mappers. 31 // The ramfs_read_page() and ramfs_write_page() functions should never be used.32 31 // The RAMFS cannot be used as the root File System. 33 32 // -
trunk/kernel/fs/vfs.c
r656 r657 3 3 * 4 4 * Author Mohamed Lamine Karaoui (2015) 5 * Alain Greiner (2016,2017,2018,2019 )5 * Alain Greiner (2016,2017,2018,2019,2020) 6 6 * 7 7 * Copyright (c) UPMC Sorbonne Universites … … 33 33 #include <xhtab.h> 34 34 #include <string.h> 35 #include <rpc.h>36 35 #include <errno.h> 37 36 #include <kmem.h> … … 59 58 ////////////////////////////////////////////////////////////////////////////////////////// 60 59 61 /////////////////////////////////////// /62 void vfs_ctx_init( vfs_fs_type_t type,63 uint32_t attr,60 /////////////////////////////////////// 61 void vfs_ctx_init( cxy_t cxy, 62 vfs_fs_type_t fs_type, 64 63 uint32_t total_clusters, 65 64 uint32_t cluster_size, … … 67 66 void * extend ) 68 67 { 69 vfs_ctx_t * vfs_ctx = &fs_context[type]; 70 71 vfs_ctx->type = type; 72 vfs_ctx->attr = attr; 73 vfs_ctx->total_clusters = total_clusters; 74 vfs_ctx->cluster_size = cluster_size; 75 vfs_ctx->vfs_root_xp = vfs_root_xp; 76 vfs_ctx->extend = extend; 77 78 busylock_init( &vfs_ctx->lock , LOCK_VFS_CTX ); 79 80 bitmap_init( vfs_ctx->bitmap , BITMAP_SIZE(CONFIG_VFS_MAX_INODES) ); 81 } 82 83 //////////////////////////////////////////// 84 error_t vfs_ctx_inum_alloc( vfs_ctx_t * ctx, 68 // get pointer on relevant VFS context (same in all clusters) 69 vfs_ctx_t * vfs_ctx_ptr = &fs_context[fs_type]; 70 71 // initialise VFS context fields 72 hal_remote_s32( XPTR( cxy , &vfs_ctx_ptr->type ) , fs_type ); 73 hal_remote_s32( XPTR( cxy , &vfs_ctx_ptr->total_clusters ) , total_clusters ); 74 hal_remote_s32( XPTR( cxy , &vfs_ctx_ptr->cluster_size ) , cluster_size ); 75 hal_remote_s64( XPTR( cxy , &vfs_ctx_ptr->vfs_root_xp ) , vfs_root_xp ); 76 hal_remote_spt( XPTR( cxy , &vfs_ctx_ptr->extend ) , extend ); 77 78 // initialize VFS context lock 79 remote_busylock_init( XPTR( cxy , &vfs_ctx_ptr->lock ) , LOCK_VFS_CTX ); 80 81 // initialize inum allocator 82 bitmap_remote_init( XPTR( cxy , &vfs_ctx_ptr->bitmap ), 83 BITMAP_SIZE(CONFIG_VFS_MAX_INODES) ); 84 85 } // end vfs_ctx_init() 86 87 /////////////////////////////////////////////// 88 error_t vfs_ctx_inum_alloc( xptr_t ctx_xp, 85 89 uint32_t * inum ) 86 90 { 91 // get context cluster and local pointer 92 cxy_t ctx_cxy = GET_CXY( ctx_xp ); 93 vfs_ctx_t * ctx_ptr = GET_PTR( ctx_xp ); 94 95 // build extended pointer on lock protecting the inum allocator 96 xptr_t lock_xp = XPTR( ctx_cxy , &ctx_ptr->lock ); 97 98 // build extended pointer on inum bitmap 99 xptr_t bitmap_xp = XPTR( ctx_cxy , &ctx_ptr->bitmap ); 100 87 101 // get lock on inum allocator 88 busylock_acquire( &ctx->lock);102 remote_busylock_acquire( lock_xp ); 89 103 90 104 // get lid from local inum allocator 91 uint32_t lid = bitmap_ ffc( ctx->bitmap , CONFIG_VFS_MAX_INODES );105 uint32_t lid = bitmap_remote_ffc( bitmap_xp , CONFIG_VFS_MAX_INODES ); 92 106 93 107 if( lid == 0xFFFFFFFF ) // no more free slot => error 94 108 { 95 109 // release lock 96 busylock_release( &ctx->lock);110 remote_busylock_release( lock_xp ); 97 111 98 112 // return error 99 return 1;113 return -1; 100 114 } 101 115 else // found => return inum 102 116 { 103 117 // set slot allocated 104 bitmap_ set( ctx->bitmap , lid );118 bitmap_remote_set( bitmap_xp , lid ); 105 119 106 120 // release lock 107 busylock_release( &ctx->lock);121 remote_busylock_release( lock_xp ); 108 122 109 123 // return inum … … 111 125 return 0; 112 126 } 113 } 114 115 //////////////////////////////////////////// 116 void vfs_ctx_inum_release( vfs_ctx_t * ctx, 117 uint32_t inum ) 118 { 119 bitmap_clear( ctx->bitmap , inum & 0xFFFF ); 120 } 127 } // end vfs_ctx_inum_alloc() 128 129 ///////////////////////////////////////////// 130 void vfs_ctx_inum_release( xptr_t ctx_xp, 131 uint32_t inum ) 132 { 133 // get context cluster and local pointer 134 cxy_t ctx_cxy = GET_CXY( ctx_xp ); 135 vfs_ctx_t * ctx_ptr = GET_PTR( ctx_xp ); 136 137 // build extended pointer on inum bitmap 138 xptr_t bitmap_xp = XPTR( ctx_cxy , &ctx_ptr->bitmap ); 139 140 // build extended pointer on lock 141 xptr_t lock_xp = XPTR( ctx_cxy , &ctx_ptr->lock ); 142 143 // get lock 144 remote_busylock_acquire( lock_xp ); 145 146 bitmap_remote_clear( bitmap_xp , inum & 0xFFFF ); 147 148 // release lock 149 remote_busylock_release( lock_xp ); 150 151 } // end vfs_ctx_inum_release() 121 152 122 153 ////////////////////////////////////////////////////////////////////////////////////////// … … 140 171 } 141 172 142 //////////////////////////////////////////////////// 143 error_t vfs_inode_create( vfs_fs_type_t fs_type, 173 //////////////////////////////////////////////// 174 error_t vfs_inode_create( cxy_t cxy, 175 vfs_fs_type_t fs_type, 144 176 uint32_t attr, 145 177 uint32_t rights, … … 148 180 xptr_t * inode_xp ) 149 181 { 150 mapper_t * mapper; // associated mapper( to be allocated)151 vfs_inode_t * inode; // inode descriptor (to be allocated)152 153 uint32_t inum; // inode identifier (to be allocated)154 vfs_ctx_t * ctx; // file system context155 kmem_req_t req; // request to kernel memory allocator182 xptr_t mapper_xp; // extended pointer on associated mapper 183 mapper_t * mapper_ptr; // local pointer on associated mapper 184 vfs_inode_t * inode_ptr; // local pointer on allocated inode 185 uint32_t inum; // inode identifier (to be allocated) 186 vfs_ctx_t * ctx; // file system context 187 kmem_req_t req; // request to kernel memory allocator 156 188 error_t error; 157 189 … … 166 198 } 167 199 168 // allocate inum169 error = vfs_ctx_inum_alloc( ctx , &inum );170 171 if( error )172 {173 printk("\n[ERROR] in %s : cannot allocate inum\n", __FUNCTION__ );174 return -1;175 }176 177 // allocate memory for mapper178 mapper = mapper_create( fs_type );179 180 if( mapper == NULL )181 {182 printk("\n[ERROR] in %s : cannot allocate mapper\n", __FUNCTION__ );183 vfs_ctx_inum_release( ctx , inum );184 return ENOMEM;185 }186 187 200 // check inode descriptor contained in one page 188 201 assert( (sizeof(vfs_inode_t) <= CONFIG_PPM_PAGE_SIZE), 189 202 "inode descriptor must fit in one page" ); 190 203 204 // allocate inum 205 error = vfs_ctx_inum_alloc( XPTR( cxy , ctx ) , &inum ); 206 207 if( error ) 208 { 209 printk("\n[ERROR] in %s : cannot allocate inum\n", __FUNCTION__ ); 210 return -1; 211 } 212 213 // allocate memory for mapper in cluster cxy 214 mapper_xp = mapper_create( cxy , fs_type ); 215 216 if( mapper_xp == XPTR_NULL ) 217 { 218 printk("\n[ERROR] in %s : cannot allocate mapper\n", __FUNCTION__ ); 219 vfs_ctx_inum_release( XPTR( cxy , ctx ) , inum ); 220 return -1; 221 } 222 223 mapper_ptr = GET_PTR( mapper_xp ); 224 191 225 // allocate one page for VFS inode descriptor 192 // because the embedded "children xhtab footprint193 req.type = KMEM_PPM;194 req.order = 0;195 req.flags = AF_KERNEL | AF_ZERO;196 inode = kmem_alloc(&req );197 198 if( inode == NULL )226 // because the embedded "children" xhtab footprint 227 req.type = KMEM_PPM; 228 req.order = 0; 229 req.flags = AF_KERNEL | AF_ZERO; 230 inode_ptr = kmem_remote_alloc( cxy , &req ); 231 232 if( inode_ptr == NULL ) 199 233 { 200 234 printk("\n[ERROR] in %s : cannot allocate inode descriptor\n", __FUNCTION__ ); 201 vfs_ctx_inum_release( ctx, inum );202 mapper_destroy( mapper );235 vfs_ctx_inum_release( XPTR( cxy , ctx ) , inum ); 236 mapper_destroy( mapper_xp ); 203 237 return -1; 204 238 } 205 239 240 // initialise inode field in mapper 241 hal_remote_spt( XPTR( cxy , &mapper_ptr->inode ) , inode_ptr ); 242 206 243 // initialize inode descriptor 207 inode->type = INODE_TYPE_FILE; // default value 208 inode->inum = inum; 209 inode->attr = attr; 210 inode->rights = rights; 211 inode->uid = uid; 212 inode->gid = gid; 213 inode->ctx = ctx; 214 inode->mapper = mapper; 215 inode->extend = NULL; 216 inode->links = 0; 217 218 // initialise inode field in mapper 219 mapper->inode = inode; 220 244 hal_remote_s32( XPTR( cxy , &inode_ptr->type ) , INODE_TYPE_FILE ); // default value 245 hal_remote_s32( XPTR( cxy , &inode_ptr->inum ) , inum ); 246 hal_remote_s32( XPTR( cxy , &inode_ptr->attr ) , attr ); 247 hal_remote_s32( XPTR( cxy , &inode_ptr->rights ) , rights ); 248 hal_remote_s32( XPTR( cxy , &inode_ptr->links ) , 0 ); 249 hal_remote_s32( XPTR( cxy , &inode_ptr->uid ) , uid ); 250 hal_remote_s32( XPTR( cxy , &inode_ptr->gid ) , gid ); 251 hal_remote_spt( XPTR( cxy , &inode_ptr->ctx ) , ctx ); 252 hal_remote_spt( XPTR( cxy , &inode_ptr->mapper ) , mapper_ptr ); 253 hal_remote_spt( XPTR( cxy , &inode_ptr->extend ) , NULL ); 254 221 255 // initialize chidren dentries xhtab 222 xhtab_init( &inode->children, XHTAB_DENTRY_TYPE );256 xhtab_init( XPTR( cxy , &inode_ptr->children ) , XHTAB_DENTRY_TYPE ); 223 257 224 258 // initialize parents dentries xlist 225 xlist_root_init( XPTR( local_cxy , &inode->parents ) );259 xlist_root_init( XPTR( cxy , &inode_ptr->parents ) ); 226 260 227 261 // initialize lock protecting size 228 remote_rwlock_init( XPTR( local_cxy , &inode->size_lock ), LOCK_VFS_SIZE );262 remote_rwlock_init( XPTR( cxy , &inode_ptr->size_lock ), LOCK_VFS_SIZE ); 229 263 230 264 // initialise lock protecting inode tree traversal 231 remote_rwlock_init( XPTR( local_cxy , &inode->main_lock ), LOCK_VFS_MAIN );265 remote_rwlock_init( XPTR( cxy , &inode_ptr->main_lock ), LOCK_VFS_MAIN ); 232 266 233 267 // return extended pointer on inode 234 *inode_xp = XPTR( local_cxy , inode);268 *inode_xp = XPTR( cxy , inode_ptr ); 235 269 236 270 #if DEBUG_VFS_INODE_CREATE … … 238 272 thread_t * this = CURRENT_THREAD; 239 273 if( DEBUG_VFS_INODE_CREATE < cycle ) 240 printk("\n[%s] thread[%x,%x] created inode (%x,%x) / c ycle %d\n",241 __FUNCTION__, this->process->pid, this->trdid, local_cxy, inode, cycle );274 printk("\n[%s] thread[%x,%x] created inode (%x,%x) / ctx %x / fs_type %d / cycle %d\n", 275 __FUNCTION__, this->process->pid, this->trdid, cxy, inode_ptr, ctx, ctx->type, cycle ); 242 276 #endif 243 277 … … 246 280 } // end vfs_inode_create() 247 281 248 ///////////////////////////////////////////// 249 void vfs_inode_destroy( vfs_inode_t * inode ) 250 { 282 ////////////////////////////////////////// 283 void vfs_inode_destroy( xptr_t inode_xp ) 284 { 285 // get cluster and local pointer 286 vfs_inode_t * inode_ptr = GET_PTR( inode_xp ); 287 cxy_t inode_cxy = GET_CXY( inode_xp ); 288 251 289 // release memory allocated for mapper 252 mapper_destroy( inode->mapper);253 254 // release memory allocate for inode descriptor290 mapper_destroy( XPTR( inode_cxy , &inode_ptr->mapper ) ); 291 292 // release memory allocated for inode descriptor 255 293 kmem_req_t req; 256 294 req.type = KMEM_PPM; 257 req.ptr = inode ;258 kmem_ free(&req );295 req.ptr = inode_ptr; 296 kmem_remote_free( inode_cxy , &req ); 259 297 260 298 } // end vfs_inode_destroy() … … 339 377 340 378 // get inode cluster and local pointer 379 inode_ptr = GET_PTR( inode_xp ); 341 380 inode_cxy = GET_CXY( inode_xp ); 342 inode_ptr = GET_PTR( inode_xp );343 381 344 382 // build extended pointer on parents dentries root … … 367 405 } // end vfs_inode_get_name() 368 406 369 /////////////////////////////////////////////////////// 370 error_t vfs_inode_load_all_pages( vfs_inode_t * inode ) 371 { 372 373 assert( (inode != NULL) , "inode pointer is NULL" ); 374 407 //////////////////////////////////////////////////// 408 error_t vfs_inode_load_all_pages( xptr_t inode_xp ) 409 { 375 410 uint32_t page_id; 376 411 xptr_t page_xp; 377 412 378 mapper_t * mapper = inode->mapper; 379 uint32_t size = inode->size; 380 381 assert( (mapper != NULL) , "mapper pointer is NULL" ); 413 414 // get inode cluster and local pointer 415 vfs_inode_t * inode_ptr = GET_PTR( inode_xp ); 416 cxy_t inode_cxy = GET_CXY( inode_xp ); 417 418 // get pointer on mapper and size 419 mapper_t * mapper = hal_remote_lpt( XPTR( inode_cxy , &inode_ptr->mapper ) ); 420 uint32_t size = hal_remote_l32( XPTR( inode_cxy , &inode_ptr->size ) ); 382 421 383 422 #if DEBUG_VFS_INODE_LOAD_ALL 423 char name[CONFIG_VFS_MAX_NAME_LENGTH]; 384 424 uint32_t cycle = (uint32_t)hal_get_cycles(); 385 425 thread_t * this = CURRENT_THREAD; 386 char name[CONFIG_VFS_MAX_NAME_LENGTH]; 387 vfs_inode_get_name( XPTR( local_cxy , inode ) , name ); 426 vfs_inode_get_name( inode_xp , name ); 388 427 if( DEBUG_VFS_INODE_LOAD_ALL < cycle ) 389 428 printk("\n[%s] thread[%x,%x] enter for <%s> in cluster %x / cycle %d\n", 390 __FUNCTION__, this->process->pid, this->trdid, name, local_cxy, cycle );429 __FUNCTION__, this->process->pid, this->trdid, name, inode_cxy, cycle ); 391 430 #endif 392 431 … … 400 439 // If the mage is missing, this function allocates the missing page, 401 440 // and load the page from IOC device into mapper 402 page_xp = mapper_ remote_get_page( XPTR( local_cxy , mapper ), page_id );441 page_xp = mapper_get_page( XPTR( inode_cxy , mapper ), page_id ); 403 442 404 443 if( page_xp == XPTR_NULL ) return -1; … … 408 447 cycle = (uint32_t)hal_get_cycles(); 409 448 if( DEBUG_VFS_INODE_LOAD_ALL < cycle ) 410 printk("\n[%s] thread[%x,%x] exit for <% x> in cluster %x / cycle %d\n",411 __FUNCTION__, this->process->pid, this->trdid, name, local_cxy, cycle);449 printk("\n[%s] thread[%x,%x] exit for <%s> in cluster %x\n", 450 __FUNCTION__, this->process->pid, this->trdid, name, inode_cxy ); 412 451 #endif 413 452 … … 425 464 vfs_inode_get_name( inode_xp , name ); 426 465 466 // get inode cluster and local pointer 427 467 cxy_t inode_cxy = GET_CXY( inode_xp ); 428 468 vfs_inode_t * inode_ptr = GET_PTR( inode_xp ); … … 461 501 ////////////////////////////////////////////////////////////////////////////////////////// 462 502 463 /////////////////////////////////////////////////// 464 error_t vfs_dentry_create( vfs_fs_type_t fs_type, 503 /////////////////////////////////////////////// 504 error_t vfs_dentry_create( cxy_t cxy, 505 vfs_fs_type_t fs_type, 465 506 char * name, 466 507 xptr_t * dentry_xp ) 467 508 { 468 vfs_ctx_t * ctx; // context descriptor 469 vfs_dentry_t * dentry; // dentry descriptor (to be allocated) 470 kmem_req_t req; // request to kernel memory allocator 509 kmem_req_t req; // request to kernel memory allocator 510 vfs_ctx_t * ctx = NULL; // context descriptor 511 vfs_dentry_t * dentry_ptr; // dentry descriptor (to be allocated) 512 513 #if DEBUG_VFS_DENTRY_CREATE 514 thread_t * this = CURRENT_THREAD; 515 uint32_t cycle = (uint32_t)hal_get_cycles(); 516 if( DEBUG_VFS_DENTRY_CREATE < cycle ) 517 printk("\n[%s] thread[%x,%x] enters for <%s> / fs_type %x / cycle %d\n", 518 __FUNCTION__, this->process->pid, this->trdid, name, fs_type, cycle ); 519 #endif 471 520 472 521 // get pointer on context … … 476 525 else 477 526 { 478 ctx = NULL;527 printk("\n[ERROR] in %s undefined fs_type %d\n", __FUNCTION__, fs_type ); 479 528 return -1; 480 529 } … … 483 532 uint32_t length = strlen( name ); 484 533 485 if( length >= CONFIG_VFS_MAX_NAME_LENGTH ) return EINVAL;534 if( length >= CONFIG_VFS_MAX_NAME_LENGTH ) return -1; 486 535 487 536 // allocate memory for dentry descriptor 488 req.type = KMEM_KCM;489 req.order = bits_log2( sizeof(vfs_dentry_t) );490 req.flags = AF_KERNEL | AF_ZERO;491 dentry = kmem_alloc(&req );492 493 if( dentry == NULL )537 req.type = KMEM_KCM; 538 req.order = bits_log2( sizeof(vfs_dentry_t) ); 539 req.flags = AF_KERNEL | AF_ZERO; 540 dentry_ptr = kmem_remote_alloc( cxy , &req ); 541 542 if( dentry_ptr == NULL ) 494 543 { 495 544 printk("\n[ERROR] in %s : cannot allocate dentry descriptor\n", … … 499 548 500 549 // initialize dentry descriptor 501 dentry->ctx = ctx; 502 dentry->length = length; 503 dentry->extend = NULL; 504 strcpy( dentry->name , name ); 550 hal_remote_spt( XPTR( cxy , &dentry_ptr->ctx ) , ctx ); 551 hal_remote_s32( XPTR( cxy , &dentry_ptr->length ) , length ); 552 hal_remote_spt( XPTR( cxy , &dentry_ptr->extend ) , NULL ); 553 554 // register name 555 hal_remote_strcpy( XPTR( cxy, dentry_ptr->name ), 556 XPTR( local_cxy, name ) ); 505 557 506 558 // return extended pointer on dentry 507 *dentry_xp = XPTR( local_cxy , dentry);559 *dentry_xp = XPTR( cxy , dentry_ptr ); 508 560 509 561 #if DEBUG_VFS_DENTRY_CREATE 510 thread_t * this = CURRENT_THREAD;511 uint32_t cycle = (uint32_t)hal_get_cycles();512 562 if( DEBUG_VFS_DENTRY_CREATE < cycle ) 513 printk("\n[%s] thread[%x,%x] created dentry <%s> : (%x,%x) / cycle %d\n",514 __FUNCTION__, this->process->pid, this->trdid, name, local_cxy, dentry, cycle);563 printk("\n[%s] thread[%x,%x] exit for <%s> / dentry (%x,%x)\n", 564 __FUNCTION__, this->process->pid, this->trdid, name, cxy, dentry_ptr ); 515 565 #endif 516 566 … … 519 569 } // end vfs_dentry_create() 520 570 521 //////////////////////////////////////////////// 522 void vfs_dentry_destroy( vfs_dentry_t * dentry ) 523 { 571 //////////////////////////////////////////// 572 void vfs_dentry_destroy( xptr_t dentry_xp ) 573 { 574 // get cluster and local pointer 575 vfs_dentry_t * dentry_ptr = GET_PTR( dentry_xp ); 576 cxy_t dentry_cxy = GET_CXY( dentry_xp ); 577 524 578 // release memory allocated to dentry 525 579 kmem_req_t req; 526 580 req.type = KMEM_KCM; 527 req.ptr = dentry ;528 kmem_ free(&req );581 req.ptr = dentry_ptr; 582 kmem_remote_free( dentry_cxy , &req ); 529 583 530 584 } // end vfs_dentry_destroy() … … 536 590 537 591 ///////////////////////////////////////////// 538 error_t vfs_file_create( vfs_inode_t * inode,539 uint32_t 540 xptr_t 541 { 542 vfs_file_t * file ;592 error_t vfs_file_create( xptr_t inode_xp, 593 uint32_t attr, 594 xptr_t * file_xp ) 595 { 596 vfs_file_t * file_ptr; 543 597 kmem_req_t req; 598 uint32_t type; 599 mapper_t * mapper; 600 vfs_ctx_t * ctx; 601 602 // get inode cluster and local pointer 603 vfs_inode_t * inode_ptr = GET_PTR( inode_xp ); 604 cxy_t inode_cxy = GET_CXY( inode_xp ); 544 605 545 606 #if DEBUG_VFS_FILE_CREATE … … 547 608 uint32_t cycle = (uint32_t)hal_get_cycles(); 548 609 if( DEBUG_VFS_OPEN < cycle ) 549 printk("\n[%s] thread[%x,%x] enter for inode %x in cluster %x/ cycle %d\n",550 __FUNCTION__, this->process->pid, this->trdid, inode , local_cxy, cycle );610 printk("\n[%s] thread[%x,%x] enter for inode (%x,%x) / cycle %d\n", 611 __FUNCTION__, this->process->pid, this->trdid, inode_cxy, inode_ptr, cycle ); 551 612 #endif 552 613 … … 555 616 req.order = bits_log2( sizeof(vfs_file_t) ); 556 617 req.flags = AF_KERNEL | AF_ZERO; 557 file = kmem_alloc( &req ); 558 559 if( file == NULL ) return ENOMEM; 618 file_ptr = kmem_remote_alloc( inode_cxy , &req ); 619 620 if( file_ptr == NULL ) return -1; 621 622 // get type, ctx and mapper from inode descriptor 623 type = hal_remote_l32( XPTR( inode_cxy , &inode_ptr->type ) ); 624 ctx = hal_remote_lpt( XPTR( inode_cxy , &inode_ptr->ctx ) ); 625 mapper = hal_remote_lpt( XPTR( inode_cxy , &inode_ptr->mapper ) ); 560 626 561 627 // initializes new file descriptor 562 file->gc = 0; 563 file->type = inode->type; 564 file->attr = attr; 565 file->offset = 0; 566 file->refcount = 1; 567 file->inode = inode; 568 file->ctx = inode->ctx; 569 file->mapper = inode->mapper; 570 571 remote_rwlock_init( XPTR( local_cxy , &file->lock ), LOCK_VFS_FILE ); 572 573 *file_xp = XPTR( local_cxy , file ); 628 hal_remote_s32( XPTR( inode_cxy , &file_ptr->type ) , type ); 629 hal_remote_s32( XPTR( inode_cxy , &file_ptr->attr ) , attr ); 630 hal_remote_s32( XPTR( inode_cxy , &file_ptr->offset ) , 0 ); 631 hal_remote_s32( XPTR( inode_cxy , &file_ptr->refcount ) , 1 ); 632 hal_remote_spt( XPTR( inode_cxy , &file_ptr->inode ) , inode_ptr ); 633 hal_remote_spt( XPTR( inode_cxy , &file_ptr->ctx ) , ctx ); 634 hal_remote_spt( XPTR( inode_cxy , &file_ptr->mapper ) , mapper ); 635 636 remote_rwlock_init( XPTR( inode_cxy , &file_ptr->lock ), LOCK_VFS_FILE ); 637 638 *file_xp = XPTR( inode_cxy , file_ptr ); 574 639 575 640 #if DEBUG_VFS_FILE_CREATE 576 641 cycle = (uint32_t)hal_get_cycles(); 577 642 if( DEBUG_VFS_OPEN < cycle ) 578 printk("\n[%s] thread[%x,%x] created file %x in cluster %x / cycle %d\n",579 __FUNCTION__, this->process->pid, this->trdid, file, local_cxy, cycle );643 printk("\n[%s] thread[%x,%x] created file (%x,%x) %x\n", 644 __FUNCTION__, this->process->pid, this->trdid, inode_cxy, file_ptr, cycle ); 580 645 #endif 581 646 … … 584 649 } // end vfs_file_create() 585 650 586 /////////////////////////////////////////// 587 void vfs_file_destroy( vfs_file_t * file ) 588 { 651 //////////////////////////////////////// 652 void vfs_file_destroy( xptr_t file_xp ) 653 { 654 // get file cluster and local pointer 655 vfs_file_t * file_ptr = GET_PTR( file_xp ); 656 cxy_t file_cxy = GET_CXY( file_xp ); 657 658 // release file descriptor 589 659 kmem_req_t req; 590 660 req.type = KMEM_KCM; 591 req.ptr = file ;592 kmem_ free(&req );661 req.ptr = file_ptr; 662 kmem_remote_free( file_cxy , &req ); 593 663 594 664 #if DEBUG_VFS_CLOSE 595 665 char name[CONFIG_VFS_MAX_NAME_LENGTH]; 596 vfs_file_get_name( XPTR( local_cxy , file ), name );666 vfs_file_get_name( file_xp , name ); 597 667 thread_t * this = CURRENT_THREAD; 598 668 uint32_t cycle = (uint32_t)hal_get_cycles(); 599 669 if( DEBUG_VFS_CLOSE < cycle ) 600 670 printk("\n[%s] thread[%x,%x] deleted file <%s> in cluster %x / cycle %d\n", 601 __FUNCTION__, this->process->pid, this->trdid, name, local_cxy, cycle );671 __FUNCTION__, this->process->pid, this->trdid, name, file_cxy, cycle ); 602 672 #endif 603 673 … … 738 808 739 809 // create a new file descriptor in cluster containing inode 740 if( inode_cxy == local_cxy ) // target cluster is local 741 { 742 error = vfs_file_create( inode_ptr , file_attr , &file_xp ); 743 } 744 else // target cluster is remote 745 { 746 rpc_vfs_file_create_client( inode_cxy , inode_ptr , file_attr , &file_xp , &error ); 747 } 810 error = vfs_file_create( inode_xp , file_attr , &file_xp ); 748 811 749 812 if( error ) return error; … … 764 827 cycle = (uint32_t)hal_get_cycles(); 765 828 if( DEBUG_VFS_OPEN < cycle ) 766 printk("\n[%s] thread[%x,%x] exit for <%s> / fdid %d / cxy %x / cycle %d\n", 767 __FUNCTION__, process->pid, this->trdid, path, file_id, GET_CXY( file_xp ), cycle ); 829 printk("\n[%s] thread[%x,%x] exit for <%s> / fdid %d / file(%x,%x) / cycle %d\n", 830 __FUNCTION__, process->pid, this->trdid, path, file_id, 831 GET_CXY( file_xp ), GET_PTR( file_xp ), cycle ); 768 832 #endif 769 833 … … 880 944 __FUNCTION__ , this->process->pid, nbytes ); 881 945 else 882 printk("\n[%s] thread[%x,%x] exit / %d bytes moved from buffer to mapper / size %d\n",883 __FUNCTION__ , this->process->pid, nbytes , hal_remote_l32(XPTR(file_cxy,&inode->size)));946 printk("\n[%s] thread[%x,%x] exit / %d bytes moved from buffer to mapper\n", 947 __FUNCTION__ , this->process->pid, nbytes ); 884 948 } 885 949 #endif … … 1035 1099 { 1036 1100 cxy_t file_cxy; // cluster containing the file descriptor. 1037 vfs_file_t * file_ptr; // local po nter on file descriptor1101 vfs_file_t * file_ptr; // local pointer on file descriptor 1038 1102 cxy_t owner_cxy; // process owner cluster 1039 1103 pid_t pid; // process identifier … … 1076 1140 1077 1141 // copy all dirty pages from mapper to device 1078 if( file_cxy == local_cxy ) 1079 { 1080 error = mapper_sync( mapper_ptr ); 1081 } 1082 else 1083 { 1084 rpc_mapper_sync_client( file_cxy, 1085 mapper_ptr, 1086 &error ); 1087 } 1142 error = mapper_sync( XPTR( file_cxy , mapper_ptr ) ); 1088 1143 1089 1144 if( error ) … … 1128 1183 1129 1184 // update dentry size in parent directory mapper 1130 if( parent_cxy == local_cxy ) 1131 { 1132 error = vfs_fs_update_dentry( parent_inode_ptr, 1133 parent_dentry_ptr, 1134 size ); 1135 } 1136 else 1137 { 1138 rpc_vfs_fs_update_dentry_client( parent_cxy, 1139 parent_inode_ptr, 1140 parent_dentry_ptr, 1141 size, 1142 &error ); 1143 } 1185 error = vfs_fs_update_dentry( XPTR( parent_cxy , parent_inode_ptr ), 1186 parent_dentry_ptr ); 1144 1187 1145 1188 if( error ) … … 1159 1202 1160 1203 // copy all dirty pages from parent mapper to device 1161 if( parent_cxy == local_cxy ) 1162 { 1163 error = mapper_sync( parent_mapper_ptr ); 1164 } 1165 else 1166 { 1167 rpc_mapper_sync_client( parent_cxy, 1168 parent_mapper_ptr, 1169 &error ); 1170 } 1204 error = mapper_sync( XPTR( parent_cxy , parent_mapper_ptr ) ); 1171 1205 1172 1206 if( error ) … … 1222 1256 //////// 4) release memory allocated to file descriptor in remote cluster 1223 1257 1224 if( file_cxy == local_cxy ) // file cluster is local 1225 { 1226 vfs_file_destroy( file_ptr ); 1227 } 1228 else // file cluster is local 1229 { 1230 rpc_vfs_file_destroy_client( file_cxy , file_ptr ); 1231 } 1258 vfs_file_destroy( file_xp ); 1232 1259 1233 1260 #if DEBUG_VFS_CLOSE … … 1320 1347 1321 1348 // 2. create one new dentry in parent cluster 1322 if( parent_cxy == local_cxy ) 1323 { 1324 error = vfs_dentry_create( parent_fs_type, 1325 last_name, 1326 &dentry_xp ); 1327 } 1328 else 1329 { 1330 rpc_vfs_dentry_create_client( parent_cxy, 1331 parent_fs_type, 1332 last_name, 1333 &dentry_xp, 1334 &error ); 1335 } 1336 1349 error = vfs_dentry_create( parent_cxy, 1350 parent_fs_type, 1351 last_name, 1352 &dentry_xp ); 1337 1353 if( error ) 1338 1354 { … … 1361 1377 inode_cxy = cluster_random_select(); 1362 1378 1363 if( inode_cxy == local_cxy ) // target cluster is local 1364 { 1365 error = vfs_inode_create( parent_fs_type, 1366 attr, 1367 rights, 1368 uid, 1369 gid, 1370 &inode_xp ); 1371 } 1372 else // target cluster is remote 1373 { 1374 rpc_vfs_inode_create_client( inode_cxy, 1375 parent_fs_type, 1376 attr, 1377 rights, 1378 uid, 1379 gid, 1380 &inode_xp, 1381 &error ); 1382 } 1383 1379 // create inode 1380 error = vfs_inode_create( inode_cxy, 1381 parent_fs_type, 1382 attr, 1383 rights, 1384 uid, 1385 gid, 1386 &inode_xp ); 1384 1387 if( error ) 1385 1388 { 1386 1389 remote_rwlock_wr_release( lock_xp ); 1387 1390 printk("\n[ERROR] in %s : cannot create new inode in cluster %x for <%s>\n", 1388 __FUNCTION__ , inode_cxy , path ); 1389 if( parent_cxy == local_cxy ) vfs_dentry_destroy( dentry_ptr ); 1390 else rpc_vfs_dentry_destroy_client( parent_cxy , dentry_ptr ); 1391 __FUNCTION__ , inode_cxy , path ); 1392 vfs_dentry_destroy( dentry_xp ); 1391 1393 return -1; 1392 1394 } … … 1434 1436 remote_rwlock_wr_release( lock_xp ); 1435 1437 printk("\n[ERROR] in %s : cannot create new inode in cluster %x for <%s>\n", 1436 __FUNCTION__ , inode_cxy , path ); 1437 if( parent_cxy == local_cxy ) vfs_dentry_destroy( dentry_ptr ); 1438 else rpc_vfs_dentry_destroy_client( parent_cxy , dentry_ptr ); 1438 __FUNCTION__ , inode_cxy , path ); 1439 vfs_dentry_destroy( dentry_xp ); 1439 1440 return -1; 1440 1441 } … … 1445 1446 // 8. update parent directory mapper 1446 1447 // and synchronize the parent directory on IOC device 1447 if (parent_cxy == local_cxy) 1448 { 1449 error = vfs_fs_add_dentry( parent_ptr, 1450 dentry_ptr ); 1451 } 1452 else 1453 { 1454 rpc_vfs_fs_add_dentry_client( parent_cxy, 1455 parent_ptr, 1456 dentry_ptr, 1457 &error ); 1458 } 1459 1448 error = vfs_fs_add_dentry( parent_xp, 1449 dentry_ptr ); 1460 1450 if( error ) 1461 1451 { … … 1589 1579 { 1590 1580 // 1. create one new dentry 1591 if( new_parent_cxy == local_cxy ) 1592 { 1593 error = vfs_dentry_create( inode_fs_type, 1594 new_name, 1595 &dentry_xp ); 1596 } 1597 else 1598 { 1599 rpc_vfs_dentry_create_client( new_parent_cxy, 1600 inode_fs_type, 1601 new_name, 1602 &dentry_xp, 1603 &error ); 1604 } 1605 1581 error = vfs_dentry_create( new_parent_cxy, 1582 inode_fs_type, 1583 new_name, 1584 &dentry_xp ); 1606 1585 if( error ) 1607 1586 { … … 1643 1622 // and synchronize the parent directory on IOC device 1644 1623 if (new_parent_cxy == local_cxy) 1645 { 1646 error = vfs_fs_add_dentry( new_parent_ptr, 1647 dentry_ptr ); 1648 } 1649 else 1650 { 1651 rpc_vfs_fs_add_dentry_client( new_parent_cxy, 1652 new_parent_ptr, 1653 dentry_ptr, 1654 &error ); 1655 } 1624 error = vfs_fs_add_dentry( new_parent_xp, 1625 dentry_ptr ); 1656 1626 if( error ) 1657 1627 { … … 1703 1673 vfs_fs_type_t fs_type; // File system type 1704 1674 1705 char name[CONFIG_VFS_MAX_NAME_LENGTH]; // name of link to remove 1675 char child_name[CONFIG_VFS_MAX_NAME_LENGTH]; // name of link to remove 1676 char parent_name[CONFIG_VFS_MAX_NAME_LENGTH]; // name of parent directory 1706 1677 1707 1678 thread_t * this = CURRENT_THREAD; … … 1731 1702 VFS_LOOKUP_PARENT, 1732 1703 &parent_xp, 1733 name );1704 child_name ); 1734 1705 if( error ) 1735 1706 { 1736 1707 remote_rwlock_wr_release( lock_xp ); 1737 1708 printk("\n[ERROR] in %s : cannot get parent inode for <%s> in <%s>\n", 1738 __FUNCTION__, name, path );1709 __FUNCTION__, child_name, path ); 1739 1710 return -1; 1740 1711 } 1741 1742 // get parent inode cluster and local pointer 1712 1713 // get parent inode name, cluster and local pointer 1714 vfs_inode_get_name( parent_xp , parent_name ); 1743 1715 parent_cxy = GET_CXY( parent_xp ); 1744 1716 parent_ptr = GET_PTR( parent_xp ); 1745 1717 1746 1718 #if( DEBUG_VFS_UNLINK & 1 ) 1747 char parent_name[CONFIG_VFS_MAX_NAME_LENGTH];1748 vfs_inode_get_name( parent_xp , parent_name );1749 1719 if( DEBUG_VFS_UNLINK < cycle ) 1750 1720 printk("\n[%s] thread[%x,%x] : parent inode <%s> is (%x,%x)\n", … … 1756 1726 1757 1727 // try to get extended pointer on dentry from Inode Tree 1758 dentry_xp = xhtab_lookup( children_xp , name );1728 dentry_xp = xhtab_lookup( children_xp , child_name ); 1759 1729 1760 // when dentry not found in Inode Tree, try to get it from inode tree1730 // when dentry not found in Inode Tree, try to get it from mapper 1761 1731 1762 1732 if( dentry_xp == XPTR_NULL ) // miss target dentry in Inode Tree … … 1765 1735 #if( DEBUG_VFS_UNLINK & 1 ) 1766 1736 if( DEBUG_VFS_UNLINK < cycle ) 1767 printk("\n[%s] thread[%x,%x] : inode <%s> not found => scan parent mapper \n",1768 __FUNCTION__, process->pid, this->trdid, name );1737 printk("\n[%s] thread[%x,%x] : inode <%s> not found => scan parent mapper <%s>\n", 1738 __FUNCTION__, process->pid, this->trdid, child_name , parent_name ); 1769 1739 #endif 1770 1740 // get parent inode FS type … … 1779 1749 fs_type, 1780 1750 parent_xp, 1781 name,1751 child_name, 1782 1752 &dentry_xp, 1783 1753 &inode_xp ); 1784 1754 if( error ) 1785 1755 { 1786 printk("\n[ERROR] in %s : cannot create inode <%s> in path <%s>\n", 1787 __FUNCTION__ , name, path ); 1788 1789 vfs_remove_child_from_parent( dentry_xp ); 1756 printk("\n[ERROR] in %s : cannot create inode <%s> in Inode Tree\n", 1757 __FUNCTION__ , child_name ); 1790 1758 return -1; 1791 1759 } … … 1797 1765 // scan parent mapper to find the missing dentry, and complete 1798 1766 // initialisation of new dentry and new inode descriptors In Inode Tree 1799 if( parent_cxy == local_cxy ) 1767 error = vfs_fs_new_dentry_from_mapper( parent_xp, 1768 dentry_ptr ); 1769 if ( error ) 1800 1770 { 1801 error = vfs_fs_new_dentry( parent_ptr, 1802 name, 1803 inode_xp ); 1804 } 1805 else 1806 { 1807 rpc_vfs_fs_new_dentry_client( parent_cxy, 1808 parent_ptr, 1809 name, 1810 inode_xp, 1811 &error ); 1812 } 1813 1814 if ( error ) // dentry not found in parent mapper 1815 { 1816 printk("\n[ERROR] in %s : cannot get dentry <%s> in path <%s>\n", 1817 __FUNCTION__ , name, path ); 1771 printk("\n[ERROR] in %s : cannot get entry <%s> in parent <%s> mapper\n", 1772 __FUNCTION__ , child_name, parent_name ); 1818 1773 return -1; 1819 1774 } … … 1822 1777 if( DEBUG_VFS_UNLINK < cycle ) 1823 1778 printk("\n[%s] thread[%x,%x] : created missing inode & dentry <%s> in cluster %x\n", 1824 __FUNCTION__, process->pid, this->trdid, name, inode_cxy );1779 __FUNCTION__, process->pid, this->trdid, child_name, inode_cxy ); 1825 1780 #endif 1826 1781 … … 1856 1811 if( DEBUG_VFS_UNLINK < cycle ) 1857 1812 printk("\n[%s] thread[%x,%x] : unlink inode <%s> / type %s / %d links\n", 1858 __FUNCTION__, process->pid, this->trdid, name, vfs_inode_type_str(inode_type), inode_links ); 1813 __FUNCTION__, process->pid, this->trdid, child_name, 1814 vfs_inode_type_str(inode_type), inode_links ); 1859 1815 #endif 1860 1816 … … 1898 1854 // 2. update parent directory mapper 1899 1855 // and synchronize the parent directory on IOC device 1900 if (parent_cxy == local_cxy) 1901 { 1902 error = vfs_fs_remove_dentry( parent_ptr, 1903 dentry_ptr ); 1904 } 1905 else 1906 { 1907 rpc_vfs_fs_remove_dentry_client( parent_cxy, 1908 parent_ptr, 1909 dentry_ptr, 1910 &error ); 1911 } 1912 1856 error = vfs_fs_remove_dentry( parent_xp, 1857 dentry_ptr ); 1913 1858 if( error ) 1914 1859 { … … 2172 2117 2173 2118 ////////////////////////////////////////////////////////////////////////// 2174 // This staticfunction is called by the vfs_display() function.2119 // This recursive function is called by the vfs_display() function. 2175 2120 // that is supposed to take the TXT0 lock. 2176 2121 ////////////////////////////////////////////////////////////////////////// … … 2184 2129 uint32_t inode_size; 2185 2130 uint32_t inode_attr; 2186 uint32_t inode_dirty;2187 2131 void * inode_extd; 2188 2132 … … 2234 2178 2235 2179 // compute dirty 2236 inode_dirty = ((inode_attr & INODE_ATTR_DIRTY) != 0);2180 // inode_dirty = ((inode_attr & INODE_ATTR_DIRTY) != 0); unused [AG] dec 2019 2237 2181 2238 2182 // display inode 2239 nolock_printk("%s<%s> : %s / extd %x / %d bytes / dirty %d /cxy %x / inode %x / mapper %x\n",2183 nolock_printk("%s<%s> : %s / extd %x / %d bytes / cxy %x / inode %x / mapper %x\n", 2240 2184 indent_str[indent], name, vfs_inode_type_str( inode_type ), (uint32_t)inode_extd, 2241 inode_size, inode_ dirty, inode_cxy, inode_ptr, mapper_ptr );2185 inode_size, inode_cxy, inode_ptr, mapper_ptr ); 2242 2186 2243 2187 // scan directory entries when current inode is a directory … … 2328 2272 2329 2273 // print header 2330 nolock_printk("\n***** file systemstate\n\n");2274 nolock_printk("\n***** current VFS state\n\n"); 2331 2275 2332 2276 // call recursive function … … 2484 2428 vfs_inode_t * parent_ptr; // local pointer on parent inode 2485 2429 xptr_t dentry_xp; // extended pointer on dentry 2430 vfs_dentry_t * dentry_ptr; // local pointer on dentry 2486 2431 xptr_t child_xp; // extended pointer on child inode 2487 2432 cxy_t child_cxy; // cluster for child inode … … 2532 2477 last = false; 2533 2478 child_xp = XPTR_NULL; 2479 child_cxy = 0; 2480 child_ptr = NULL; 2534 2481 2535 2482 // loop on nodes in pathname … … 2570 2517 &child_xp ); 2571 2518 2572 // get child inode local pointer and cluster 2573 child_ptr = GET_PTR( child_xp ); 2574 child_cxy = GET_CXY( child_xp ); 2575 2576 if( found == false ) // not found in Inode Tree 2519 if( found == false ) // child not found in Inode Tree 2577 2520 { 2578 2521 // when a inode is not found in the Inode Tree: … … 2606 2549 #endif 2607 2550 // get parent inode FS type 2608 ctx_ptr = hal_remote_lpt( XPTR( parent_cxy ,&parent_ptr->ctx ) );2551 ctx_ptr = hal_remote_lpt( XPTR( parent_cxy , &parent_ptr->ctx ) ); 2609 2552 fs_type = hal_remote_l32( XPTR( parent_cxy , &ctx_ptr->type ) ); 2610 2553 … … 2626 2569 } 2627 2570 2628 // get child inode local pointer 2629 child_ptr = GET_PTR( child_xp ); 2571 // get child inode and dentry local pointers 2572 child_ptr = GET_PTR( child_xp ); 2573 dentry_ptr = GET_PTR( dentry_xp ); 2630 2574 2631 2575 #if (DEBUG_VFS_LOOKUP & 1) … … 2636 2580 // scan parent mapper to find the missing dentry, and complete 2637 2581 // the initialisation of dentry and child inode descriptors 2638 if( parent_cxy == local_cxy ) 2639 { 2640 error = vfs_fs_new_dentry( parent_ptr, 2641 name, 2642 child_xp ); 2643 } 2644 else 2645 { 2646 rpc_vfs_fs_new_dentry_client( parent_cxy, 2647 parent_ptr, 2648 name, 2649 child_xp, 2650 &error ); 2651 } 2652 2653 // when the missing dentry is not in the parent mapper, 2654 // a new dentry must be registered in parent directory mapper 2655 if ( error ) 2582 error = vfs_fs_new_dentry_from_mapper( parent_xp, 2583 dentry_ptr ); 2584 2585 if ( error ) // an error can be fatal or non-fatal : 2656 2586 { 2657 2587 if ( last && create ) // add a brand new dentry in parent directory 2658 2588 { 2659 error = vfs_new_dentry_init( parent_xp, 2660 dentry_xp, 2661 child_xp ); 2589 error = vfs_fs_new_dentry_to_mapper( parent_xp, 2590 dentry_ptr ); 2662 2591 if ( error ) 2663 2592 { 2664 printk("\n[ERROR] in %s : cannot init inode <%s> in path <%s>\n",2665 __FUNCTION__, name , pathname);2593 printk("\n[ERROR] in %s : cannot add dentry <%s> in parent dir\n", 2594 __FUNCTION__, name ); 2666 2595 vfs_remove_child_from_parent( dentry_xp ); 2667 2596 return -1; … … 2674 2603 vfs_inode_display( child_xp ); 2675 2604 #endif 2676 2677 2678 2605 } 2679 2606 else // not last or not create => error … … 2704 2631 if( type == INODE_TYPE_DIR ) 2705 2632 { 2706 if( child_cxy == local_cxy ) 2707 { 2708 error = vfs_inode_load_all_pages( child_ptr ); 2709 } 2710 else 2711 { 2712 rpc_vfs_inode_load_all_pages_client( child_cxy, 2713 child_ptr, 2714 &error ); 2715 } 2633 error = vfs_inode_load_all_pages( child_xp ); 2634 2716 2635 if ( error ) 2717 2636 { … … 2731 2650 } 2732 2651 } 2733 else // child directly found in inode tree2652 else // child found in Inode Tree 2734 2653 { 2654 // get child inode local pointer and cluster 2655 child_ptr = GET_PTR( child_xp ); 2656 child_cxy = GET_CXY( child_xp ); 2735 2657 2736 2658 #if (DEBUG_VFS_LOOKUP & 1) … … 2759 2681 // } 2760 2682 2761 // take lock on child inode and release lock on parent2762 // vfs_inode_lock( child_xp );2763 // vfs_inode_unlock( parent_xp );2764 2765 2683 // exit when last 2766 2684 if ( last ) // last inode in path => return relevant info … … 2792 2710 } 2793 2711 } 2794 else // not the last inode in path => update loop variables2712 else // not the last node in path => update loop variables 2795 2713 { 2796 2714 parent_xp = child_xp; 2797 2715 current = next; 2798 2716 } 2799 } 2717 } // end while loop on nodes in pathname 2718 2719 #if ( DEBUG_VFS_LOOKUP & 1 ) 2720 if( DEBUG_VFS_LOOKUP < cycle ) 2721 vfs_display( root_xp ); 2722 #endif 2800 2723 2801 2724 return 0; 2802 2725 2803 2726 } // end vfs_lookup() 2804 2805 ////////////////////////////////////////////////2806 error_t vfs_new_dentry_init( xptr_t parent_xp,2807 xptr_t dentry_xp,2808 xptr_t child_xp )2809 {2810 error_t error;2811 uint32_t cluster_id;2812 uint32_t child_type;2813 uint32_t child_size;2814 2815 #if DEBUG_VFS_NEW_DENTRY_INIT2816 char parent_name[CONFIG_VFS_MAX_NAME_LENGTH];2817 char child_name[CONFIG_VFS_MAX_NAME_LENGTH];2818 vfs_inode_get_name( parent_xp , parent_name );2819 vfs_inode_get_name( child_xp , child_name );2820 uint32_t cycle = (uint32_t)hal_get_cycles();2821 thread_t * this = CURRENT_THREAD;2822 if( DEBUG_VFS_NEW_DENTRY_INIT < cycle )2823 printk("\n[%s] thread[%x,%x] enter / parent <%s> / child <%s> / cycle %d\n",2824 __FUNCTION__ , this->process->pid, this->trdid, parent_name, child_name, cycle );2825 #endif2826 2827 // get parent inode cluster and local pointer2828 cxy_t parent_cxy = GET_CXY( parent_xp );2829 vfs_inode_t * parent_ptr = GET_PTR( parent_xp );2830 2831 // get dentry local pointer2832 vfs_dentry_t * dentry_ptr = GET_PTR( dentry_xp );2833 2834 // get child inode cluster and local pointer2835 cxy_t child_cxy = GET_CXY( child_xp );2836 vfs_inode_t * child_ptr = GET_PTR( child_xp );2837 2838 // 1. allocate one free cluster_id in file system to child inode,2839 // and update the File Allocation Table in both the FAT mapper and IOC device.2840 // It depends on the child inode FS type.2841 vfs_ctx_t * ctx = hal_remote_lpt( XPTR( child_cxy , &child_ptr->ctx ) );2842 2843 error = vfs_fs_cluster_alloc( ctx->type,2844 &cluster_id );2845 if ( error )2846 {2847 printk("\n[ERROR] in %s : cannot find a free VFS cluster_id\n",2848 __FUNCTION__ );2849 return -1;2850 }2851 2852 #if( DEBUG_VFS_NEW_DENTRY_INIT & 1)2853 if( DEBUG_VFS_NEW_DENTRY_INIT < cycle )2854 printk("\n[%s] thread[%x,%x] allocated FS cluster_id %x to <%s>\n",2855 __FUNCTION__ , this->process->pid, this->trdid, cluster_id, child_name );2856 #endif2857 2858 // 2. update the child inode descriptor size and extend2859 child_type = hal_remote_l32( XPTR( child_cxy , &child_ptr->type ) );2860 child_size = 0;2861 2862 hal_remote_s32( XPTR( child_cxy , &child_ptr->size ) , child_size );2863 hal_remote_spt( XPTR( child_cxy , &child_ptr->extend ) , (void*)(intptr_t)cluster_id );2864 2865 // 3. update the parent inode mapper, and2866 // update the dentry extension if required2867 if( local_cxy == parent_cxy )2868 {2869 error = vfs_fs_add_dentry( parent_ptr,2870 dentry_ptr );2871 }2872 else2873 {2874 rpc_vfs_fs_add_dentry_client( parent_cxy,2875 parent_ptr,2876 dentry_ptr,2877 &error );2878 }2879 if ( error )2880 {2881 printk("\n[ERROR] in %s : cannot register child in parent directory\n",2882 __FUNCTION__ );2883 return -1;2884 }2885 2886 #if DEBUG_VFS_NEW_DENTRY_INIT2887 cycle = (uint32_t)hal_get_cycles();2888 if( DEBUG_VFS_NEW_DENTRY_INIT < cycle )2889 printk("\n[%s] thread[%x,%x] exit / parent <%s> / child <%s> / cycle %d\n",2890 __FUNCTION__ , this->process->pid, this->trdid, parent_name, child_name, cycle );2891 #endif2892 2893 return 0;2894 2895 } // end vfs_new_dentry_init()2896 2727 2897 2728 /////////////////////////////////////////////////// … … 2906 2737 xptr_t dentry_xp; // extended pointer on dentry (used for . and ..) 2907 2738 vfs_dentry_t * dentry_ptr; // local pointer on dentry (used for . and ..) 2908 2909 // xptr_t parents_root_xp; // extended pointer on inode "parents" field2910 // xptr_t parents_entry_xp; // extended pointer on dentry "parents" field2911 2739 xptr_t children_xhtab_xp; // extended pointer on inode "children" field 2912 2740 xptr_t children_entry_xp; // extended pointer on dentry "children" field … … 2924 2752 #endif 2925 2753 2926 // get newdirectory cluster and local pointer2754 // get child directory cluster and local pointer 2927 2755 child_cxy = GET_CXY( child_xp ); 2928 2756 child_ptr = GET_PTR( child_xp ); … … 2933 2761 2934 2762 //////////////////////////// create <.> dentry ////////////////////// 2935 if( child_cxy == local_cxy ) 2936 { 2937 error = vfs_dentry_create( fs_type, 2938 ".", 2939 &dentry_xp ); 2940 } 2941 else 2942 { 2943 rpc_vfs_dentry_create_client( child_cxy, 2944 fs_type, 2945 ".", 2946 &dentry_xp, 2947 &error ); 2948 } 2763 error = vfs_dentry_create( child_cxy, 2764 fs_type, 2765 ".", 2766 &dentry_xp ); 2949 2767 if( error ) 2950 2768 { … … 2967 2785 children_xhtab_xp = XPTR( child_cxy , &child_ptr->children ); 2968 2786 children_entry_xp = XPTR( child_cxy , &dentry_ptr->children ); 2787 2969 2788 error = xhtab_insert( children_xhtab_xp , "." , children_entry_xp ); 2789 2970 2790 if( error ) 2971 2791 { … … 2974 2794 return -1; 2975 2795 } 2976 2977 2796 2978 // don't register <.> dentry in child_inode xlist of parents2979 // parents_root_xp = XPTR( child_cxy , &child_ptr->parents );2980 // parents_entry_xp = XPTR( child_cxy , &dentry_ptr->parents );2981 // xlist_add_first( parents_root_xp , parents_entry_xp );2982 // hal_remote_atomic_add( XPTR( child_cxy , &child_ptr->links ) , 1 );2983 2984 2797 // update "parent" and "child_xp" fields in <.> dentry 2985 2798 hal_remote_s64( XPTR( child_cxy , &dentry_ptr->child_xp ) , child_xp ); … … 2997 2810 if( child_xp != parent_xp ) 2998 2811 { 2999 if( child_cxy == local_cxy ) 3000 { 3001 error = vfs_fs_add_dentry( child_ptr, 3002 dentry_ptr ); 3003 } 3004 else 3005 { 3006 rpc_vfs_fs_add_dentry_client( child_cxy, 3007 child_ptr, 3008 dentry_ptr, 3009 &error ); 3010 } 2812 error = vfs_fs_add_dentry( child_xp, 2813 dentry_ptr ); 3011 2814 if( error ) 3012 2815 { … … 3026 2829 3027 2830 ///////////////////////////// create <..> dentry /////////////////////// 3028 if( child_cxy == local_cxy ) 3029 { 3030 error = vfs_dentry_create( fs_type, 3031 "..", 3032 &dentry_xp ); 3033 } 3034 else 3035 { 3036 rpc_vfs_dentry_create_client( child_cxy, 3037 fs_type, 3038 "..", 3039 &dentry_xp, 3040 &error ); 3041 } 2831 error = vfs_dentry_create( child_cxy, 2832 fs_type, 2833 "..", 2834 &dentry_xp ); 3042 2835 if( error ) 3043 2836 { … … 3085 2878 if( child_xp != parent_xp ) 3086 2879 { 3087 if( child_cxy == local_cxy ) 3088 { 3089 error = vfs_fs_add_dentry( child_ptr, 3090 dentry_ptr ); 3091 } 3092 else 3093 { 3094 rpc_vfs_fs_add_dentry_client( child_cxy, 3095 child_ptr, 3096 dentry_ptr, 3097 &error ); 3098 } 2880 error = vfs_fs_add_dentry( child_xp, 2881 dentry_ptr ); 3099 2882 if( error ) 3100 2883 { … … 3259 3042 3260 3043 3261 ////////////////////////////////////////////////////////////// //////3044 ////////////////////////////////////////////////////////////// 3262 3045 error_t vfs_add_child_in_parent( cxy_t child_cxy, 3263 3046 vfs_fs_type_t fs_type, … … 3296 3079 3297 3080 // 1. create dentry in parent cluster 3298 if( parent_cxy == local_cxy ) // parent cluster is local 3299 { 3300 error = vfs_dentry_create( fs_type, 3301 name, 3302 &new_dentry_xp ); 3303 } 3304 else // parent cluster is remote 3305 { 3306 rpc_vfs_dentry_create_client( parent_cxy, 3307 fs_type, 3308 name, 3309 &new_dentry_xp, 3310 &error ); 3311 } 3312 3081 error = vfs_dentry_create( parent_cxy, 3082 fs_type, 3083 name, 3084 &new_dentry_xp ); 3313 3085 if( error ) 3314 3086 { … … 3334 3106 uint32_t gid = 0; 3335 3107 3336 if( child_cxy == local_cxy ) // child cluster is local 3337 { 3338 error = vfs_inode_create( fs_type, 3339 attr, 3340 mode, 3341 uid, 3342 gid, 3343 &new_inode_xp ); 3344 } 3345 else // child cluster is remote 3346 { 3347 rpc_vfs_inode_create_client( child_cxy, 3348 fs_type, 3349 attr, 3350 mode, 3351 uid, 3352 gid, 3353 &new_inode_xp, 3354 &error ); 3355 } 3356 3108 error = vfs_inode_create( child_cxy, 3109 fs_type, 3110 attr, 3111 mode, 3112 uid, 3113 gid, 3114 &new_inode_xp ); 3357 3115 if( error ) 3358 3116 { … … 3360 3118 __FUNCTION__ , child_cxy ); 3361 3119 3362 if( parent_cxy == local_cxy ) vfs_dentry_destroy( new_dentry_ptr ); 3363 else rpc_vfs_dentry_destroy_client( parent_cxy , new_dentry_ptr ); 3120 vfs_dentry_destroy( new_dentry_xp ); 3364 3121 return -1; 3365 3122 } … … 3374 3131 #endif 3375 3132 3376 3377 3133 // 3. register new_dentry in new_inode xlist of parents 3378 3134 parents_root_xp = XPTR( child_cxy , &new_inode_ptr->parents ); … … 3457 3213 3458 3214 // delete dentry descriptor 3459 if( parent_cxy == local_cxy ) 3460 { 3461 vfs_dentry_destroy( dentry_ptr ); 3462 } 3463 else 3464 { 3465 rpc_vfs_dentry_destroy_client( parent_cxy, 3466 dentry_ptr ); 3467 } 3215 vfs_dentry_destroy( dentry_xp ); 3468 3216 3469 3217 // delete child_inode descriptor if last link 3470 if( links == 1 ) 3471 { 3472 if( child_cxy == local_cxy ) 3473 { 3474 vfs_inode_destroy( child_inode_ptr ); 3475 } 3476 else 3477 { 3478 rpc_vfs_inode_destroy_client( child_cxy , child_inode_ptr ); 3479 } 3480 } 3218 if( links == 1 ) vfs_inode_destroy( child_inode_xp ); 3481 3219 3482 3220 } // end vfs_remove_child_from_parent() … … 3489 3227 ////////////////////////////////////////////////////////////////////////////////////////// 3490 3228 3491 ////////////////////////////////////////////// 3492 error_t vfs_fs_ move_page( xptr_t page_xp,3493 cmd_type_t cmd_type)3229 /////////////////////////////////////////////////// 3230 error_t vfs_fs_add_dentry( xptr_t inode_xp, 3231 vfs_dentry_t * dentry_ptr ) 3494 3232 { 3495 3233 error_t error = 0; 3496 3234 3497 assert( (page_xp != XPTR_NULL) , "page pointer is NULL" ); 3498 3499 page_t * page_ptr = GET_PTR( page_xp ); 3500 cxy_t page_cxy = GET_CXY( page_xp ); 3501 3502 // get local pointer on page mapper 3503 mapper_t * mapper = hal_remote_lpt( XPTR( page_cxy , &page_ptr->mapper ) ); 3504 3505 assert( (mapper != NULL) , "no mapper for page" ); 3235 assert( (inode_xp != XPTR_NULL) , "inode_xp argument is NULL" ); 3236 assert( (dentry_ptr != NULL ) , "dentry_ptr argument is NULL" ); 3237 3238 vfs_inode_t * inode_ptr = GET_PTR( inode_xp ); 3239 cxy_t inode_cxy = GET_CXY( inode_xp ); 3240 3241 // get inode mapper 3242 mapper_t * mapper = hal_remote_lpt( XPTR( inode_cxy , &inode_ptr->mapper ) ); 3243 3244 assert( (mapper != NULL) , "mapper pointer is NULL") 3506 3245 3507 3246 // get FS type 3508 vfs_fs_type_t fs_type = hal_remote_l32( XPTR( page_cxy , &mapper->type ) );3247 vfs_fs_type_t fs_type = hal_remote_l32( XPTR( inode_cxy , &mapper->fs_type ) ); 3509 3248 3510 3249 // call relevant FS function 3511 3250 if( fs_type == FS_TYPE_FATFS ) 3512 3251 { 3513 error = fatfs_ move_page( page_xp , cmd_type);3252 error = fatfs_add_dentry( inode_xp , dentry_ptr ); 3514 3253 } 3515 3254 else if( fs_type == FS_TYPE_RAMFS ) 3516 3255 { 3517 assert( false , "should not be called for RAMFS\n" );3256 error = 0; // does nothing for RAMFS 3518 3257 } 3519 3258 else if( fs_type == FS_TYPE_DEVFS ) 3520 3259 { 3521 assert( false , "should not be called for DEVFS\n" );3260 error = 0; // does nothing for DEVFS 3522 3261 } 3523 3262 else … … 3528 3267 return error; 3529 3268 3530 } // end vfs_fs_ move_page()3531 3532 //////////////////////////////////////////////// 3533 error_t vfs_fs_ add_dentry( vfs_inode_t * inode,3534 vfs_dentry_t * dentry)3269 } // end vfs_fs_add_dentry() 3270 3271 ////////////////////////////////////////////////////// 3272 error_t vfs_fs_remove_dentry( xptr_t inode_xp, 3273 vfs_dentry_t * dentry_ptr ) 3535 3274 { 3536 3275 error_t error = 0; 3537 3276 3538 assert( (inode != NULL) , "inode pointer is NULL" ); 3539 assert( (dentry != NULL) , "dentry pointer is NULL" ); 3540 3541 mapper_t * mapper = inode->mapper; 3542 3543 assert( (mapper != NULL) , "mapper pointer is NULL" ); 3277 assert( (inode_xp != XPTR_NULL) , "inode_xp argument is NULL" ); 3278 assert( (dentry_ptr != NULL ) , "dentry_ptr argument is NULL" ); 3279 3280 vfs_inode_t * inode_ptr = GET_PTR( inode_xp ); 3281 cxy_t inode_cxy = GET_CXY( inode_xp ); 3282 3283 // get inode mapper 3284 mapper_t * mapper = hal_remote_lpt( XPTR( inode_cxy , &inode_ptr->mapper ) ); 3285 3286 assert( (mapper != NULL) , "mapper pointer is NULL") 3544 3287 3545 3288 // get FS type 3546 vfs_fs_type_t fs_type = mapper->type;3289 vfs_fs_type_t fs_type = hal_remote_l32( XPTR( inode_cxy , &mapper->fs_type ) ); 3547 3290 3548 3291 // call relevant FS function 3549 3292 if( fs_type == FS_TYPE_FATFS ) 3550 3293 { 3551 error = fatfs_add_dentry( inode , dentry ); 3294 error = fatfs_remove_dentry( inode_xp , dentry_ptr ); 3295 3552 3296 } 3553 3297 else if( fs_type == FS_TYPE_RAMFS ) … … 3566 3310 return error; 3567 3311 3568 } // end vfs_fs_ add_dentry()3569 3570 /////////////////////////////////////////////////// 3571 error_t vfs_fs_ remove_dentry( vfs_inode_t * inode,3572 vfs_dentry_t * dentry)3312 } // end vfs_fs_remove_dentry() 3313 3314 /////////////////////////////////////////////////////////////// 3315 error_t vfs_fs_new_dentry_from_mapper( xptr_t inode_xp, 3316 vfs_dentry_t * dentry_ptr ) 3573 3317 { 3574 3318 error_t error = 0; 3575 3319 3576 assert( (inode != NULL) , "inode pointer is NULL" ); 3577 assert( (dentry != NULL) , "dentry pointer is NULL" ); 3578 3579 mapper_t * mapper = inode->mapper; 3580 3581 assert( (mapper != NULL) , "mapper pointer is NULL" ); 3320 assert( (inode_xp != XPTR_NULL) , "inode_xp argument is NULL" ); 3321 assert( (dentry_ptr != NULL ) , "dentry_ptr argument is NULL" ); 3322 3323 vfs_inode_t * inode_ptr = GET_PTR( inode_xp ); 3324 cxy_t inode_cxy = GET_CXY( inode_xp ); 3325 3326 // get inode mapper 3327 mapper_t * mapper = hal_remote_lpt( XPTR( inode_cxy , &inode_ptr->mapper ) ); 3328 3329 assert( (mapper != NULL) , "mapper pointer is NULL") 3582 3330 3583 3331 // get FS type 3584 vfs_fs_type_t fs_type = mapper->type;3332 vfs_fs_type_t fs_type = hal_remote_l32( XPTR( inode_cxy , &mapper->fs_type ) ); 3585 3333 3586 3334 // call relevant FS function 3587 3335 if( fs_type == FS_TYPE_FATFS ) 3588 3336 { 3589 error = fatfs_ remove_dentry( inode , dentry );3337 error = fatfs_new_dentry_from_mapper( inode_xp , dentry_ptr ); 3590 3338 } 3591 3339 else if( fs_type == FS_TYPE_RAMFS ) 3592 3340 { 3593 error = 0; // does nothing for RAMFS3341 assert( false , "should not be called for RAMFS" ); 3594 3342 } 3595 3343 else if( fs_type == FS_TYPE_DEVFS ) 3596 3344 { 3597 error = 0; // does nothing for DEVFS3345 assert( false , "should not be called for DEVFS" ); 3598 3346 } 3599 3347 else … … 3604 3352 return error; 3605 3353 3606 } // end vfs_fs_remove_dentry() 3607 3608 //////////////////////////////////////////////// 3609 error_t vfs_fs_new_dentry( vfs_inode_t * parent, 3610 char * name, 3611 xptr_t child_xp ) 3354 } // end vfs_fs_new_dentry_from_mapper() 3355 3356 /////////////////////////////////////////////////////////////// 3357 error_t vfs_fs_new_dentry_to_mapper( xptr_t inode_xp, 3358 vfs_dentry_t * dentry_ptr ) 3612 3359 { 3613 3360 error_t error = 0; 3614 3361 3615 // check arguments 3616 assert( (parent != NULL) , "parent pointer is NULL"); 3617 assert( (child_xp != XPTR_NULL) , "child pointer is NULL"); 3618 3619 // get parent inode FS type 3620 vfs_fs_type_t fs_type = parent->ctx->type; 3362 assert( (inode_xp != XPTR_NULL) , "inode_xp argument is NULL" ); 3363 assert( (dentry_ptr != NULL ) , "dentry_ptr argument is NULL" ); 3364 3365 vfs_inode_t * inode_ptr = GET_PTR( inode_xp ); 3366 cxy_t inode_cxy = GET_CXY( inode_xp ); 3367 3368 // get inode mapper 3369 mapper_t * mapper = hal_remote_lpt( XPTR( inode_cxy , &inode_ptr->mapper ) ); 3370 3371 assert( (mapper != NULL) , "mapper pointer is NULL") 3372 3373 // get FS type 3374 vfs_fs_type_t fs_type = hal_remote_l32( XPTR( inode_cxy , &mapper->fs_type ) ); 3621 3375 3622 3376 // call relevant FS function 3623 3377 if( fs_type == FS_TYPE_FATFS ) 3624 3378 { 3625 error = fatfs_new_dentry ( parent , name , child_xp);3379 error = fatfs_new_dentry_to_mapper( inode_xp , dentry_ptr ); 3626 3380 } 3627 3381 else if( fs_type == FS_TYPE_RAMFS ) … … 3640 3394 return error; 3641 3395 3642 } // end vfs_fs_new_dentry() 3643 3644 /////////////////////////////////////////////////// 3645 error_t vfs_fs_update_dentry( vfs_inode_t * inode, 3646 vfs_dentry_t * dentry, 3647 uint32_t size ) 3396 } // end vfs_fs_new_dentry_to_mapper() 3397 3398 ////////////////////////////////////////////////////// 3399 error_t vfs_fs_update_dentry( xptr_t inode_xp, 3400 vfs_dentry_t * dentry_ptr ) 3648 3401 { 3649 3402 error_t error = 0; 3650 3403 3651 // check arguments 3652 assert( (inode != NULL) , "inode pointer is NULL"); 3653 assert( (dentry != NULL) , "dentry pointer is NULL"); 3654 3655 // get parent inode FS type 3656 vfs_fs_type_t fs_type = inode->ctx->type; 3404 assert( (inode_xp != XPTR_NULL) , "inode_xp argument is NULL" ); 3405 assert( (dentry_ptr != NULL ) , "dentry_ptr argument is NULL" ); 3406 3407 vfs_inode_t * inode_ptr = GET_PTR( inode_xp ); 3408 cxy_t inode_cxy = GET_CXY( inode_xp ); 3409 3410 // get inode mapper 3411 mapper_t * mapper = hal_remote_lpt( XPTR( inode_cxy , &inode_ptr->mapper ) ); 3412 3413 assert( (mapper != NULL) , "mapper pointer is NULL") 3414 3415 // get FS type 3416 vfs_fs_type_t fs_type = hal_remote_l32( XPTR( inode_cxy , &mapper->fs_type ) ); 3657 3417 3658 3418 // call relevant FS function 3659 3419 if( fs_type == FS_TYPE_FATFS ) 3660 3420 { 3661 error = fatfs_update_dentry( inode , dentry , size);3421 error = fatfs_update_dentry( inode_xp , dentry_ptr ); 3662 3422 } 3663 3423 else if( fs_type == FS_TYPE_RAMFS ) … … 3739 3499 } // end vfs_fs_get_user_dir() 3740 3500 3741 ///////////////////////////////////////////// ///3742 error_t vfs_fs_sync_inode( vfs_inode_t * inode)3501 ///////////////////////////////////////////// 3502 error_t vfs_fs_sync_inode( xptr_t inode_xp ) 3743 3503 { 3744 3504 error_t error = 0; 3745 3505 3746 // check arguments 3747 assert( (inode != NULL) , "inode pointer is NULL"); 3748 3749 // get inode FS type 3750 vfs_fs_type_t fs_type = inode->ctx->type; 3506 assert( (inode_xp != XPTR_NULL) , "inode_xp argument is NULL"); 3507 3508 vfs_inode_t * inode_ptr = GET_PTR( inode_xp ); 3509 cxy_t inode_cxy = GET_CXY( inode_xp ); 3510 3511 // get inode mapper 3512 mapper_t * mapper = hal_remote_lpt( XPTR( inode_cxy , &inode_ptr->mapper ) ); 3513 3514 assert( (mapper != NULL) , "mapper pointer is NULL") 3515 3516 // get FS type 3517 vfs_fs_type_t fs_type = hal_remote_l32( XPTR( inode_cxy , &mapper->fs_type ) ); 3751 3518 3752 3519 // call relevant FS function 3753 3520 if( fs_type == FS_TYPE_FATFS ) 3754 3521 { 3755 error = fatfs_sync_inode( inode );3522 error = fatfs_sync_inode( inode_xp ); 3756 3523 } 3757 3524 else if( fs_type == FS_TYPE_RAMFS ) … … 3799 3566 } // end vfs_fs_sync_fat() 3800 3567 3801 //////////////////////////////////////////////////////3802 error_t vfs_fs_sync_free_info( vfs_fs_type_t fs_type )3803 {3804 error_t error = 0;3805 3806 // call relevant FS function3807 if( fs_type == FS_TYPE_FATFS )3808 {3809 error = fatfs_sync_free_info();3810 }3811 else if( fs_type == FS_TYPE_RAMFS )3812 {3813 assert( false , "should not be called for RAMFS" );3814 }3815 else if( fs_type == FS_TYPE_DEVFS )3816 {3817 assert( false , "should not be called for DEVFS" );3818 }3819 else3820 {3821 assert( false , "undefined file system type" );3822 }3823 3824 return error;3825 3826 } // end vfs_fs_sync_fat()3827 3828 /////////////////////////////////////////////////3829 error_t vfs_fs_cluster_alloc( uint32_t fs_type,3830 uint32_t * cluster )3831 {3832 error_t error = 0;3833 3834 // call relevant FS function3835 if( fs_type == FS_TYPE_FATFS )3836 {3837 error = fatfs_cluster_alloc( cluster );3838 }3839 else if( fs_type == FS_TYPE_RAMFS )3840 {3841 assert( false , "should not be called for RAMFS" );3842 }3843 else if( fs_type == FS_TYPE_DEVFS )3844 {3845 assert( false , "should not be called for DEVFS" );3846 }3847 else3848 {3849 assert( false , "undefined file system type" );3850 }3851 3852 return error;3853 3854 } // end vfs_fs_cluster_alloc()3855 3856 3568 //////////////////////////////////////////////// 3857 3569 error_t vfs_fs_release_inode( xptr_t inode_xp ) … … 3859 3571 error_t error = 0; 3860 3572 3861 assert( (inode_xp != XPTR_NULL) , "inode pointeris NULL")3573 assert( (inode_xp != XPTR_NULL) , "inode_xp argument is NULL") 3862 3574 3863 3575 vfs_inode_t * inode_ptr = GET_PTR( inode_xp ); 3864 3576 cxy_t inode_cxy = GET_CXY( inode_xp ); 3865 3577 3866 // get local pointer on pagemapper3578 // get local pointer on mapper 3867 3579 mapper_t * mapper = hal_remote_lpt( XPTR( inode_cxy , &inode_ptr->mapper ) ); 3868 3580 … … 3870 3582 3871 3583 // get FS type from mapper 3872 vfs_fs_type_t fs_type = hal_remote_l32( XPTR( inode_cxy , &mapper-> type ) );3584 vfs_fs_type_t fs_type = hal_remote_l32( XPTR( inode_cxy , &mapper->fs_type ) ); 3873 3585 3874 3586 // call relevant FS function … … 3894 3606 } // end vfs_fs_release_inode() 3895 3607 3896 3608 ////////////////////////////////////////////////// 3609 error_t vfs_fs_move_page( xptr_t page_xp, 3610 ioc_cmd_type_t cmd_type ) 3611 { 3612 error_t error = 0; 3613 3614 assert( (page_xp != XPTR_NULL) , "page pointer is NULL" ); 3615 3616 page_t * page_ptr = GET_PTR( page_xp ); 3617 cxy_t page_cxy = GET_CXY( page_xp ); 3618 3619 // get local pointer on mapper 3620 mapper_t * mapper = hal_remote_lpt( XPTR( page_cxy , &page_ptr->mapper ) ); 3621 3622 assert( (mapper != NULL) , "no mapper for page" ); 3623 3624 // get FS type 3625 vfs_fs_type_t fs_type = hal_remote_l32( XPTR( page_cxy , &mapper->fs_type ) ); 3626 3627 // call relevant FS function 3628 if( fs_type == FS_TYPE_FATFS ) 3629 { 3630 error = fatfs_move_page( page_xp , cmd_type ); 3631 } 3632 else if( fs_type == FS_TYPE_RAMFS ) 3633 { 3634 assert( false , "should not be called for RAMFS\n" ); 3635 } 3636 else if( fs_type == FS_TYPE_DEVFS ) 3637 { 3638 assert( false , "should not be called for DEVFS\n" ); 3639 } 3640 else 3641 { 3642 assert( false , "undefined file system type" ); 3643 } 3644 3645 return error; 3646 3647 } // end vfs_fs_move_page() 3648 3649 -
trunk/kernel/fs/vfs.h
r656 r657 3 3 * 4 4 * Author Mohamed Lamine Karaoui (2014,2015) 5 * Alain Greiner (2016,2017,2018 )5 * Alain Greiner (2016,2017,2018,2019,2020) 6 6 * 7 7 * Copyright (c) UPMC Sorbonne Universites … … 55 55 struct vseg_s; 56 56 struct page_s; 57 struct ksock_s; 57 58 58 59 /****************************************************************************************** … … 72 73 * The <extend> field is a pointer on the FS specific context extension. 73 74 * This extension is dynamically allocated by kernel_init in all clusters. 74 * In each cluster, both this VFS context and the FS specific context are handled as75 * private by the local OS intance.75 * In each cluster, the inum allocator can be accessed by any thread runing 76 * in any cluster, and is therefore protected by a remote_busylock. 76 77 *****************************************************************************************/ 77 78 78 79 typedef enum 79 80 { 80 FS_TYPE_ DEVFS = 0,81 FS_TYPE_ FATFS = 1,82 FS_TYPE_ RAMFS = 2,81 FS_TYPE_RAMFS = 0, 82 FS_TYPE_DEVFS = 1, 83 FS_TYPE_FATFS = 2, 83 84 84 85 FS_TYPES_NR = 3, … … 95 96 typedef struct vfs_ctx_s 96 97 { 97 vfs_fs_type_t type; /*! File System type */ 98 uint32_t attr; /*! global attributes for all files in FS */ 99 uint32_t total_clusters; /*! total number of clusters on device */ 100 uint32_t cluster_size; /*! cluster size on device (bytes) */ 101 xptr_t vfs_root_xp; /*! extended pointer on VFS root inode */ 102 busylock_t lock; /*! lock protecting inum allocator */ 103 uint32_t bitmap[BITMAP_SIZE(CONFIG_VFS_MAX_INODES)]; /* inum allocator */ 104 void * extend; /*! FS specific context extension */ 98 vfs_fs_type_t type; /*! File System type */ 99 uint32_t total_clusters; /*! total number of clusters on device */ 100 uint32_t cluster_size; /*! cluster size on device (bytes) */ 101 xptr_t vfs_root_xp; /*! extended pointer on VFS root inode */ 102 remote_busylock_t lock; /*! lock protecting inum allocator */ 103 uint32_t bitmap[BITMAP_SIZE(CONFIG_VFS_MAX_INODES)]; /* inum allocator */ 104 void * extend; /*! FS specific context extension */ 105 105 } 106 106 vfs_ctx_t; … … 109 109 * This structure define a VFS inode. 110 110 * An inode can have several children dentries (if it is a directory), an can have several 111 * parents dentries (if it has sseveral aliases links):111 * parents dentries (if it has several aliases links): 112 112 * - The "parents" field is the root of the xlist of parents dentries, and the "links" 113 113 * fiels define the number of aliases parent dentries. only a FILE inode can have … … 145 145 typedef enum 146 146 { 147 INODE_ATTR_DIRTY = 0x01, /* modified versus the value on device*/148 INODE_ATTR_INLOAD = 0x04, /* loading from device in progress*/149 INODE_ATTR_NEW = 0x08, /* not saved on device yet*/147 INODE_ATTR_DIRTY = 0x01, /*! modified versus the value on device */ 148 INODE_ATTR_INLOAD = 0x04, /*! loading from device in progress */ 149 INODE_ATTR_NEW = 0x08, /*! not saved on device yet */ 150 150 } 151 151 vfs_inode_attr_t; … … 193 193 194 194 /****************************************************************************************** 195 Rpt* This structure defines a directory entry.195 * This structure defines a directory entry. 196 196 * A dentry contains the name of a remote file/dir, an extended pointer on the 197 197 * inode representing this file/dir, a local pointer on the inode representing … … 225 225 typedef enum 226 226 { 227 FD_ATTR_READ_ENABLE = 0x01, /*! read access possible */228 FD_ATTR_WRITE_ENABLE = 0x02, /*! write access possible */229 FD_ATTR_APPEND = 0x04, /*! append on each write */230 FD_ATTR_CLOSE_EXEC = 0x08, /*! close file on exec */231 FD_ATTR_SYNC = 0x10, /*! synchronise FS on each write */232 FD_ATTR_IS_DIR = 0x20, /*! this is a directory */227 FD_ATTR_READ_ENABLE = 0x01, /*! read access possible */ 228 FD_ATTR_WRITE_ENABLE = 0x02, /*! write access possible */ 229 FD_ATTR_APPEND = 0x04, /*! append on each write */ 230 FD_ATTR_CLOSE_EXEC = 0x08, /*! close file on exec */ 231 FD_ATTR_SYNC = 0x10, /*! synchronise FS on each write */ 232 FD_ATTR_IS_DIR = 0x20, /*! this is a directory */ 233 233 } 234 234 vfs_file_attr_t; … … 237 237 { 238 238 struct vfs_ctx_s * ctx; /*! local pointer on FS context. */ 239 uint32_t gc; /*! generation counter */240 239 vfs_file_attr_t attr; /*! file attributes bit vector (see above) */ 241 240 vfs_inode_type_t type; /*! same type as inode */ … … 245 244 struct mapper_s * mapper; /*! associated file cache */ 246 245 struct vfs_inode_s * inode; /*! local pointer on associated inode */ 246 struct socket_s * socket; /*! local pointer on associated socket */ 247 247 void * extend; /*! FS specific extension */ 248 248 } … … 255 255 256 256 /****************************************************************************************** 257 * This function initialise a (statically allocated) VFS context in local cluster. 258 ****************************************************************************************** 257 * This function initialises a (statically allocated) VFS context in cluster identified 258 * by the <cxy> argument. 259 * It is called by the kernel_init() function. 260 ****************************************************************************************** 261 * @ cxy : target cluster identifier. 259 262 * @ fs_type : file system type. 260 * @ attr : global attributes (for all files in FS.261 263 * @ total_clusters : total number of clusters on device. 262 264 * @ cluster_size : cluster size on device (bytes). … … 264 266 * @ extend : fs_type_specific extension. 265 267 *****************************************************************************************/ 266 void vfs_ctx_init( vfs_fs_type_t type,267 uint32_t attr,268 void vfs_ctx_init( cxy_t cxy, 269 vfs_fs_type_t type, 268 270 uint32_t total_clusters, 269 271 uint32_t cluster_size, … … 277 279 * - the 16 LSB bits contains the local inode identifier : lid 278 280 ****************************************************************************************** 279 * @ ctx : localpointer on file system context.280 * @ inum : [ou ] buffer for allocated inode identifier.281 * @ ctx_xp : [in] extended pointer on file system context. 282 * @ inum : [out] buffer for allocated inode identifier. 281 283 * @ return 0 if success / return non-zero if error. 282 284 *****************************************************************************************/ 283 error_t vfs_ctx_inum_alloc( vfs_ctx_t * ctx,284 uint32_t 285 error_t vfs_ctx_inum_alloc( xptr_t ctx_xp, 286 uint32_t * inum ); 285 287 286 288 /****************************************************************************************** 287 289 * This function release an inode identifier. 288 290 ****************************************************************************************** 289 * @ ctx : localpointer on file system context.290 * @ inum : released inode identifier.291 *****************************************************************************************/ 292 void vfs_ctx_inum_release( vfs_ctx_t * ctx,291 * @ ctx_xp : [in] extended pointer on file system context. 292 * @ inum : [in] released inode identifier. 293 *****************************************************************************************/ 294 void vfs_ctx_inum_release( xptr_t ctx_xp, 293 295 uint32_t inum ); 294 296 … … 305 307 306 308 /****************************************************************************************** 307 * This function allocates memory from local cluster for an inode descriptor and the 308 * associated mapper, and partially initialise this inode from arguments values. 309 * This function allocates memory in cluster identified by the <cxy> argument 310 * for an inode descriptor and for the associated mapper, and partially initialise 311 * this inode from arguments values. 309 312 * It does NOT link it to the Inode Tree, as this is done by add_child_in_parent(). 310 * It must called by a local thread. Use the RPC_INODE_CREATE if client thread is remote.311 ****************************************************************************************** 312 * @ fs_type : file system type.313 * @ inode_type : inodetype.314 * @ attr : inode attributes.315 * @ rights : inode access rights.316 * @ uid : user owner ID.317 * @ gid : group owner ID.313 * It can be called by any thread running in any cluster. 314 ****************************************************************************************** 315 * @ cxy : [in] target cluster identifier 316 * @ fs_type : [in] file system type. 317 * @ attr : [in] inode attributes. 318 * @ rights : [in] inode access rights. 319 * @ uid : [in] user owner ID. 320 * @ gid : [in] group owner ID. 318 321 * @ inode_xp : [out] buffer for extended pointer on created inode. 319 * @ return 0 if success / return ENOMEM or EINVAL if error. 320 *****************************************************************************************/ 321 error_t vfs_inode_create( vfs_fs_type_t fs_type, 322 * @ return 0 if success / return -1 if error. 323 *****************************************************************************************/ 324 error_t vfs_inode_create( cxy_t cxy, 325 vfs_fs_type_t fs_type, 322 326 uint32_t attr, 323 327 uint32_t rights, … … 330 334 * all memory allocated to the mapper (both mapper descriptor and radix tree). 331 335 * The mapper should not contain any dirty page (should be synchronized before deletion). 332 * It must be executed by a thread running in the cluster containing the inode. 333 * Use the rpc_vfs_inode_destroy_client() function if required. 336 * It can be called by any thread running in any cluster. 334 337 ****************************************************************************************** 335 * @ inode : localpointer on inode descriptor.336 *****************************************************************************************/ 337 void vfs_inode_destroy( vfs_inode_t * inode);338 * @ inode_xp : extended pointer on inode descriptor. 339 *****************************************************************************************/ 340 void vfs_inode_destroy( xptr_t inode_xp ); 338 341 339 342 /****************************************************************************************** 340 343 * This function returns the <size> of a file/dir from a remote inode, 341 344 * taking the remote_rwlock protecting <size> in READ_MODE. 345 * It can be called by any thread running in any cluster. 342 346 ***************************************************************************************** 343 347 * @ inode_xp : extended pointer on the remote inode. … … 350 354 * It takes the rwlock protecting the file size in WRITE_MODE, and set the "size" field 351 355 * when the current size is smaller than the requested <size> argument. 356 * It can be called by any thread running in any cluster. 352 357 ***************************************************************************************** 353 358 * @ inode_xp : extended pointer on the remote inode. … … 358 363 359 364 /****************************************************************************************** 360 * This function takes the main lock of a remote inode .365 * This function takes the main lock of a remote inode identified by the <inode_xp>. 361 366 * This lock protect all inode fields, including the children dentries. 367 * It can be called by any thread running in any cluster. 362 368 ***************************************************************************************** 363 369 * @ inode_xp : extended pointer on the remote inode. … … 366 372 367 373 /****************************************************************************************** 368 * This function releases the main lock of a remote inode .374 * This function releases the main lock of a remote inode identified by <inode_xp>. 369 375 * This lock protect all inode fiels, including the children dentries. 376 * It can be called by any thread running in any cluster. 370 377 ***************************************************************************************** 371 378 * @ inode_xp : extended pointer on the remote inode. … … 377 384 * argument to a local buffer identified by the <name> argument. 378 385 * The local buffer size must be at least CONFIG_VFS_MAX_NAME_LENGTH. 386 * It can be called by any thread running in any cluster. 379 387 ****************************************************************************************** 380 388 * @ inode_xp : extended pointer on the remote inode. … … 385 393 386 394 /****************************************************************************************** 387 * This function accesses successively all pages of a file identified by the <inode >,395 * This function accesses successively all pages of a file identified by the <inode_xp>, 388 396 * argument, to force misses, and load all pages into mapper. 389 397 * The target inode can be a directory or a file, but this function is mainly used 390 398 * to prefetch a complete directory to the mapper. 391 * It must be executed by a thread running in the cluster containing the inode.392 399 * This function does NOT take any lock. 393 ****************************************************************************************** 394 * @ inode : local pointer on inode. 400 * It can be called by any thread running in any cluster. 401 ****************************************************************************************** 402 * @ inode_xp : extended pointer on inode. 395 403 * @ return 0 if success / return -1 if device access failure. 396 404 *****************************************************************************************/ 397 error_t vfs_inode_load_all_pages( vfs_inode_t * inode);398 399 /****************************************************************************************** 400 * This debug function display the curren state of an inode descriptor identified by401 * the <inode_xp> argument.405 error_t vfs_inode_load_all_pages( xptr_t inode_xp ); 406 407 /****************************************************************************************** 408 * This debug function display the curren state of an inode descriptor. 409 * It can be called by any thread running in any cluster. 402 410 *****************************************************************************************/ 403 411 void vfs_inode_display( xptr_t inode_xp ); … … 408 416 409 417 /****************************************************************************************** 410 * This function allocates memory from local cluster for a dentry descriptor, 411 * initialises it from arguments values, and returns the extended pointer on dentry. 412 * It must called by a local thread. Use the RPC_DENTRY_CREATE if client thread is remote. 413 ****************************************************************************************** 418 * This function allocates memory in cluster identified by the <cxy> argument 419 * for a dentry descriptor, initialises it from arguments values, and returns 420 * in <dentry_xp> the extended pointer on dentry. 421 * It can be called by any thread running in any cluster. 422 ****************************************************************************************** 423 * @ cxy : [in] target cluster identifier 414 424 * @ fs_type : [in] file system type. 415 425 * @ name : [in] directory entry file/dir name. … … 417 427 * @ return 0 if success / return ENOMEM or EINVAL if error. 418 428 *****************************************************************************************/ 419 error_t vfs_dentry_create( vfs_fs_type_t fs_type, 429 error_t vfs_dentry_create( cxy_t cxy, 430 vfs_fs_type_t fs_type, 420 431 char * name, 421 432 xptr_t * dentry_xp ); … … 424 435 * This function removes the dentry from the parent inode xhtab, and releases the memory 425 436 * allocated to the dentry descriptor. 426 * It must be executed by a thread running in the cluster containing the dentry. 427 * Use the RPC_DENTRY_DESTROY if required. 437 * It can be called by any thread running in any cluster. 428 438 ****************************************************************************************** 429 * @ dentry : [in] localpointer on dentry descriptor.430 *****************************************************************************************/ 431 void vfs_dentry_destroy( vfs_dentry_t * dentry);439 * @ dentry_xp : [in] extended pointer on dentry descriptor. 440 *****************************************************************************************/ 441 void vfs_dentry_destroy( xptr_t dentry_xp ); 432 442 433 443 … … 437 447 438 448 /****************************************************************************************** 439 * This function allocates memory and initializes a new local file descriptor. 440 * It must be executed in the cluster containing the inode. 441 * If the client thread is not running in the owner cluster, it must use the 442 * rpc_vfs_file_create_client() function. 449 * This function allocates memory and initializes a new file descriptor in the 450 * cluster defined by the <inode_xp> argument. 451 * It can be called by any thread running in any cluster. 443 452 ****************************************************************************************** 444 * @ inode : localpointer on associated inode.445 * @ attr :file descriptor attributes.446 * @ file_xp : [out] buffer for extended pointer on created file descriptor.453 * @ inode_xp : [in] extended pointer on associated inode. 454 * @ attr : [in] file descriptor attributes. 455 * @ file_xp : [out] buffer for extended pointer on created file descriptor. 447 456 * @ return 0 if success / return ENOMEM if error. 448 457 *****************************************************************************************/ 449 error_t vfs_file_create( vfs_inode_t * inode,458 error_t vfs_file_create( xptr_t inode_xp, 450 459 uint32_t attr, 451 460 xptr_t * file_xp ); 452 461 453 462 /****************************************************************************************** 454 * This function releases memory allocated to a local file descriptor.455 * It must be executed by a thread running in the cluster containing the inode,456 * and the file refcount must be zero. Use the RPC_VFS_FILE_DESTROY if required.463 * This function releases memory allocated to file descriptor identified 464 * by the <file_xp> argument. 465 * It can be called by any thread running in any cluster. 457 466 ****************************************************************************************** 458 * @ file : localpointer on file descriptor.459 *****************************************************************************************/ 460 void vfs_file_destroy( vfs_file_t * file);467 * @ file_xp : [in] extended pointer on file descriptor. 468 *****************************************************************************************/ 469 void vfs_file_destroy( xptr_t file_xp ); 461 470 462 471 /****************************************************************************************** 463 472 * These functions increment (resp. decrement) the count field in a remote file 464 473 * descriptor, using a remote_atomic access. 474 ***************************************************************************************** 475 * @ file_xp : extended pointer on file descriptor. 465 476 *****************************************************************************************/ 466 477 void vfs_file_count_up ( xptr_t file_xp ); … … 472 483 * The local buffer size must be at least CONFIG_VFS_MAX_NAME_LENGTH. 473 484 ***************************************************************************************** 474 * @ file_xp :extended pointer on the remote inode.475 * @ name : local buffer pointer.476 *************************************************************************************** **/485 * @ ionde_xp : [in] extended pointer on the remote inode. 486 * @ name : [out] local string. 487 ***************************************************************************************/ 477 488 void vfs_file_get_name( xptr_t inode_xp, 478 489 char * name ); … … 596 607 597 608 /****************************************************************************************** 598 * This function is called by the vfs_lookup() function when a new (dentry/inode) must 599 * be created from scratch and introduced in both the parent mapper and the IOC device. 600 * The dentry and inode descriptors must have been previously created by the caller. 601 * 1. It allocates one cluster from the relevant FS, updates the FAT mapper, 602 * and synchronously update the IOC device). 603 * 2. It set the "size", and "extend" fields in child inode descriptor. 604 * The size is 4096 for a directory, the size is 0 for a file. 605 * 3. It updates the parent directory mapper to introduce the new child, 606 * and synchronously update the IOC device. 607 * 4. It set the "extend" field in dentry descriptor. 608 * It can be called by a thread running in any cluster. 609 ****************************************************************************************** 610 * @ parent_xp : extended pointer on parent inode descriptor. 611 * @ dentry_xp : extended pointer on new dentry descriptor. 612 * @ child_xp : extended pointer on child inode descriptor. 613 * @ return 0 if success / -1 if failure. 614 *****************************************************************************************/ 615 error_t vfs_new_dentry_init( xptr_t parent_xp, 616 xptr_t dentry_xp, 617 xptr_t child_xp ); 618 619 /****************************************************************************************** 620 * This function creates in the directory identified by the <child_xp> argument, 609 * This function creates in the directory identified by the <child_inode_xp> argument, 621 610 * the two special dentries <.> and <..>. The parent directory inode is defined 622 * by the <parent_ xp> argument. The two dentries are introduced in the Inode Tree.611 * by the <parent_inode_xp> argument. The two dentries are introduced in the Inode Tree. 623 612 * They are also introduced in the child directory mapper, and the IOC device is updated. 624 613 * This function is called by all functions creating a brand new directory : vfs_mkdir(), … … 629 618 * @ return 0 if success / -1 if failure. 630 619 *****************************************************************************************/ 631 error_t vfs_add_special_dentries( xptr_t child_ xp,632 xptr_t parent_ xp );620 error_t vfs_add_special_dentries( xptr_t child_inode_xp, 621 xptr_t parent_inode_xp ); 633 622 634 623 /****************************************************************************************** … … 893 882 894 883 /****************************************************************************************** 895 * These functions define the VFS "FS" API toa specific File System896 *****************************************************************************************/ 897 898 /****************************************************************************************** 899 * This function makes the I/O operation to move one page identified by the <page_xp>900 * argument to/from the IOC device from/to the mapper, as defined by the <cmd_type>.884 * These functions define the VFS "FS" API to access a specific File System 885 *****************************************************************************************/ 886 887 /****************************************************************************************** 888 * This function introduces in a directory mapper identified by the <parent_inode_xp> 889 * argument, a new entry identified by the <dentry_ptr> argument. 901 890 * Depending on the file system type, it calls the proper, FS specific function. 902 * It is used in case of MISS on the mapper (read), or when a dirty page in the mapper 903 * must be updated in the File System (write). 904 * The mapper pointer, and the page index in file are obtained from the page descriptor. 905 * It can be executed by any thread running in any cluster. 906 * This function does NOT take any lock. 907 ****************************************************************************************** 908 * @ page_xp : extended pointer on page descriptor (for mapper and page_id). 909 * @ cmd_type : IOC_READ / IOC_WRITE / IOC_SYNC_READ / IOC_SYNC_WRITE 910 * @ returns 0 if success / return -1 if device access failure. 911 *****************************************************************************************/ 912 error_t vfs_fs_move_page( xptr_t page_xp, 913 cmd_type_t cmd_type ); 914 915 /****************************************************************************************** 916 * This function updates the mapper associated to a directory inode identified by the 917 * <parent> argument, to add a new entry identified by the <dentry> argument. 918 * The directory inode descriptor and the dentry descriptor are in the same cluster. 919 * Depending on the file system type, it calls the proper, FS specific function. 920 * It also updates the dentry descriptor and/or the inode descriptor extensions 921 * as required by the specific file system type. 891 * All informations related to the new directory must be contained in the dentry 892 * descriptor, or in the associated child inode descriptor. 893 * The dentry descriptor "extend" field is updated as required by the specific FS. 922 894 * Finally, it synchronously updates the parent directory on IOC device. 923 * 924 * It must be executed by a thread running in the cluster containing the parent directory. 925 * It can be the RPC_VFS_FS_ADD_DENTRY. This function does NOT take any lock. 895 * This function can be called by any thread running in any cluster. 926 896 ****************************************************************************************** 927 897 * @ parent : local pointer on parent (directory) inode. … … 929 899 * @ return 0 if success / return -1 if device access failure. 930 900 *****************************************************************************************/ 931 error_t vfs_fs_add_dentry( vfs_inode_t * parent, 932 vfs_dentry_t * dentry ); 933 934 /****************************************************************************************** 935 * This function updates the mapper associated to a directory inode identified by the 936 * <parent> argument, to remove an entry identified by the <dentry> argument. 937 * The directory inode descriptor and the dentry descriptor are in the same cluster. 901 error_t vfs_fs_add_dentry( xptr_t parent_inode_xp, 902 vfs_dentry_t * dentry_ptr ); 903 904 /****************************************************************************************** 905 * This function removes from a directory mapper identified by the <parent_inode_xp> 906 * argument, an entry identified by the <dentry_ptr> argument. 938 907 * Depending on the file system type, it calls the proper, FS specific function. 939 908 * Finally, it synchronously updates the parent directory on IOC device. 940 * 941 * Depending on the file system type, it calls the relevant, FS specific function. 942 * It must be executed by a thread running in the cluster containing the parent directory. 943 * It can be the RPC_VFS_FS_REMOVE_DENTRY. This function does NOT take any lock. 944 ****************************************************************************************** 945 * @ parent : local pointer on parent (directory) inode. 946 * @ dentry : local pointer on dentry containing name. 909 * This function can be called by any thread running in any cluster. 910 ****************************************************************************************** 911 * @ parent_inode_xp : extended pointer on parent (directory) inode. 912 * @ dentry_ptr : local pointer on dentry containing name. 947 913 * @ return 0 if success / return -1 if device access failure. 948 914 *****************************************************************************************/ 949 error_t vfs_fs_remove_dentry( vfs_inode_t * parent, 950 vfs_dentry_t * dentry ); 951 952 /****************************************************************************************** 953 * This function scan the mapper of an an existing parent inode directory, identified by 954 * the <parent> argument to find a directory entry identified by the <name> argument, 955 * and updates both the child inode descriptor, identified by the <child_xp> argument, 956 * and the associated dentry descriptor : 915 error_t vfs_fs_remove_dentry( xptr_t parent_inode_xp, 916 vfs_dentry_t * dentry_ptr ); 917 918 /****************************************************************************************** 919 * This function scan a directory mapper, identified by the <parent_inode_xp> argument 920 * to find a directory entry identified by the <dentry_ptr> argument, 921 * and updates both the child inode descriptor, and the associated dentry descriptor: 957 922 * - It set the "size", "type", and "extend" fields in inode descriptor. 958 923 * - It set the "extend" field in dentry descriptor. 959 * It is called by the vfs_lookup() function in case of miss. 960 * 924 * It is called by the vfs_lookup() function in case of miss, and does NOT take any lock. 961 925 * Depending on the file system type, it calls the relevant, FS specific function. 962 * It must be called by a thread running in the cluster containing the parent inode. 963 * It can be the RPC_VFS_FS_NEW_DENTRY. This function does NOT take any lock. 964 ****************************************************************************************** 965 * @ parent : local pointer on parent inode (directory). 966 * @ name : child name. 967 * @ child_xp : extended pointer on remote child inode (file or directory) 926 * This function can be called by any thread running in any cluster. 927 ****************************************************************************************** 928 * @ parent_inode_xp : extended pointer on parent inode (directory). 929 * @ dentry_ptr : local pointer on new entry (in parent inode cluster). 968 930 * @ return 0 if success / return -1 if dentry not found. 969 931 *****************************************************************************************/ 970 error_t vfs_fs_new_dentry( vfs_inode_t * parent, 971 char * name, 972 xptr_t child_xp ); 973 974 /****************************************************************************************** 975 * This function scan the mapper of an an existing inode directory, identified by 976 * the <inode> argument, to find a directory entry identified by the <dentry> argument, 977 * and update the size for this directory entry in mapper, as defined by <size>. 932 error_t vfs_fs_new_dentry_from_mapper( xptr_t parent_inode_xp, 933 vfs_dentry_t * dentry_ptr ); 934 935 /***************************************************************************************** 936 * This function introduces a brand new dentry identified by the <dentry_ptr> argument 937 * in the mapper of a directory identified by the <parent_inode_xp> argument. 938 * It is called by the vfs_lookup() function, and does NOT take any lock. 939 * The child inode descriptor, and the dentry descriptor must have been previously 940 * allocated and introduced in the Inode Tree. The dentry descriptor contains the name. 941 * Depending on the file system type, it calls the relevant, FS specific function. 942 * This function can be called by any thread running in any cluster. 943 ***************************************************************************************** 944 * @ parent_inode_xp : [in] extended pointer on parent inode (directory). 945 * @ dentry_ptr : [in] local pointer on dentry (in parent inode cluster). 946 * @ return 0 if success / return -1 if failure. 947 ****************************************************************************************/ 948 error_t vfs_fs_new_dentry_to_mapper( xptr_t parent_inode_xp, 949 vfs_dentry_t * dentry_ptr ); 950 951 /****************************************************************************************** 952 * This function updates the "size" field of a directory entry identified by the 953 * <dentry_ptr> argument in a directory mapper identified by the <parent_inode_xp> 954 * from the value contained in the inode descriptor. 978 955 * The parent directory on device is synchronously updated. 979 956 * It is called by the vfs_close() function. 980 *981 957 * Depending on the file system type, it calls the relevant, FS specific function. 982 * It must be called by a thread running in the cluster containing the parent inode. 983 * It can be the RPC_VFS_FS_UPDATE_DENTRY. This function does NOT take any lock. 984 ****************************************************************************************** 985 * @ parent : local pointer on parent inode (directory). 986 * @ dentry : local pointer on dentry. 987 * @ size : new size value (bytes). 988 * @ return 0 if success / return ENOENT if not found. 989 *****************************************************************************************/ 990 error_t vfs_fs_update_dentry( vfs_inode_t * inode, 991 vfs_dentry_t * dentry, 992 uint32_t size ); 958 * This function can be called by any thread running in any cluster. 959 ****************************************************************************************** 960 * @ parent_inode_xp : local pointer on parent inode (directory). 961 * @ dentry_ptr : local pointer on dentry (in parent directory cluster). 962 * @ return 0 if success / return -1 if not found. 963 *****************************************************************************************/ 964 error_t vfs_fs_update_dentry( xptr_t parent_inode_xp, 965 vfs_dentry_t * dentry_ptr ); 993 966 994 967 /****************************************************************************************** … … 1002 975 * the Inode Tree is dynamically created, and all dirent fiels are documented in the 1003 976 * dirent array. Otherwise, only the dentry name is documented. 1004 * 977 * This function does NOT take any lock. 1005 978 * Depending on the file system type, it calls the relevant, FS specific function. 1006 * It must be called by a thread running in the cluster containing the parent inode. 1007 * This function does NOT take any lock. 979 * 980 * WARNING : this function must be called by a thread running in the cluster containing 981 * the target directory inode. 1008 982 ****************************************************************************************** 1009 983 * @ inode : [in] local pointer on directory inode. … … 1031 1005 * directory are synchronously done on the IOC device by the two vfs_fs_add_dentry() 1032 1006 * and vfs_fs_remove_dentry() functions. 1033 *1034 1007 * Depending on the file system type, it calls the relevant, FS specific function. 1035 * It must be called by a thread running in the inodecluster.1008 * This function can be called by any thread running in any cluster. 1036 1009 ***************************************************************************************** 1037 * @ inode : localpointer on inode.1038 * @ return 0 if success / return EIO if failure during device access.1010 * @ inode_xp : remote pointer on inode. 1011 * @ return 0 if success / return -1 if failure. 1039 1012 ****************************************************************************************/ 1040 error_t vfs_fs_sync_inode( struct vfs_inode_s * inode);1013 error_t vfs_fs_sync_inode( xptr_t inode_xp ); 1041 1014 1042 1015 /***************************************************************************************** … … 1044 1017 * for the FAT itself. It scan all clusters registered in the FAT mapper, and copies 1045 1018 * to device each page marked as dirty. 1046 *1047 1019 * Depending on the file system type, it calls the relevant, FS specific function. 1048 1020 * It can be called by a thread running in any cluster. … … 1053 1025 error_t vfs_fs_sync_fat( vfs_fs_type_t fs_type ); 1054 1026 1055 /*****************************************************************************************1056 * This function updates the free clusters info on the IOC device for the FS defined1057 * by the <fs_type> argument.1058 *1059 * Depending on the file system type, it calls the relevant, FS specific function.1060 * It can be called by a thread running in any cluster.1061 *****************************************************************************************1062 * @ fs_type : specific file system type.1063 * @ return 0 if success / return EIO if failure during device access.1064 ****************************************************************************************/1065 error_t vfs_fs_sync_free_info( vfs_fs_type_t fs_type );1066 1067 /******************************************************************************************1068 * This function allocates a free cluster from the FS identified by the <fs_type>1069 * argument. It updates the selected FS File Allocation Table.1070 *1071 * Depending on the file system type, it calls the relevant, FS specific function.1072 * It can be called by a thread running in any cluster.1073 ******************************************************************************************1074 * @ fs_type : [in] File System type.1075 * @ cluster : [out] cluster index in File system.1076 * @ return 0 if success / return -1 if no free cluster1077 *****************************************************************************************/1078 error_t vfs_fs_cluster_alloc( uint32_t fs_type,1079 uint32_t * cluster );1080 1081 1027 /****************************************************************************************** 1082 1028 * This function makes all I/O operations required to release all clusters allocated … … 1084 1030 * Depending on the file system type, it calls the proper, FS specific function. 1085 1031 * It is called by the vfs_unlink() function. 1086 * It can be executed by a thread running in any cluster.1087 1032 * This function does NOT take any lock. 1033 * Depending on the file system type, it calls the relevant, FS specific function. 1034 * This function can be executed by any thread running in any cluster. 1088 1035 ****************************************************************************************** 1089 1036 * @ inode_xp : extended pointer on inode. … … 1092 1039 error_t vfs_fs_release_inode( xptr_t inode_xp ); 1093 1040 1041 /****************************************************************************************** 1042 * This function makes the I/O operation to move one page identified by the <page_xp> 1043 * argument to/from the IOC device from/to the mapper, as defined by the <cmd_type>. 1044 * It is used in case of MISS on the mapper (read), or when a dirty page in the mapper 1045 * must be updated in the File System (write). 1046 * The mapper pointer, and the page index in file are obtained from the page descriptor. 1047 * This function does NOT take any lock. 1048 * Depending on the file system type, it calls the proper, FS specific function. 1049 * This function can be executed by any thread running in any cluster. 1050 ****************************************************************************************** 1051 * @ page_xp : extended pointer on page descriptor (for mapper and page_id). 1052 * @ cmd_type : IOC_READ / IOC_WRITE / IOC_SYNC_READ / IOC_SYNC_WRITE 1053 * @ returns 0 if success / return -1 if device access failure. 1054 *****************************************************************************************/ 1055 error_t vfs_fs_move_page( xptr_t page_xp, 1056 ioc_cmd_type_t cmd_type ); 1057 1094 1058 1095 1059 #endif /* _VFS_H_ */
Note: See TracChangeset
for help on using the changeset viewer.