Changeset 656 for trunk/kernel/fs


Ignore:
Timestamp:
Dec 6, 2019, 12:07:51 PM (4 years ago)
Author:
alain
Message:

Fix several bugs in the FATFS and in the VFS,
related to the creation of big files requiring
more than 4 Kbytes (one cluster) on device.

Location:
trunk/kernel/fs
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/kernel/fs/fatfs.c

    r647 r656  
    850850
    851851}  // end fatfs_recursive_release()
     852
     853
     854//////////////////////////////////////////////////////////////////////////////////////////
     855// This static function access the FAT (File Allocation Table), stored in the FAT mapper,
     856// 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 file
     858// (i.e. the page index in file mapper). The entry point in the FAT is defined by the
     859// <first_cluster_id> argument, that is the cluster_id of an already allocated cluster.
     860// It can be the cluster_id of the first page of the file (always registered in the
     861// fatfs_inode extension), or any page of the file whose <first_page_id> argument
     862// 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.
     865// The FAT mapper being a WRITE-THROUGH cache, this function updates the FAT mapper
     866// from informations stored on IOC device in case of miss when scanning the FAT mapper.
     867// The searched inode mapper being a WRITE-BACK cache, this function allocates a new
     868// cluster_id when the searched page exist in the inode mapper, and there is no FATFS
     869// cluster allocated yet for this page. It updates the FAT, but it does NOT copy the
     870// mapper page content to the File System.
     871//////////////////////////////////////////////////////////////////////////////////////////
     872// @ first_page_id       : [in]  index in file mapper for an existing page.
     873// @ first_cluster_id    : [in]  cluster_id for this existing page.
     874// @ searched_page_id    : [in]  index in file mapper for the searched page.
     875// @ searched_cluster_id : [out] cluster_id for the searched page.
     876// @ return 0 if success / return -1 if a FAT mapper miss cannot be solved,
     877//                         or if a missing cluster_id cannot be allocated.
     878//////////////////////////////////////////////////////////////////////////////////////////
     879static error_t fatfs_get_cluster( uint32_t   first_page_id,
     880                                  uint32_t   first_cluster_id,
     881                                  uint32_t   searched_page_id,
     882                                  uint32_t * searched_cluster_id )
     883{
     884    uint32_t   current_page_id;        // index of page in file mapper
     885    uint32_t   current_cluster_id;     // index of cluster in FATFS
     886    xptr_t     lock_xp;                // extended pointer on FAT lock
     887
     888assert( (searched_page_id > first_page_id) ,
     889"searched_page_id must be larger than first_page_id\n");
     890
     891#if DEBUG_FATFS_GET_CLUSTER
     892uint32_t   cycle = (uint32_t)hal_get_cycles();
     893thread_t * this  = CURRENT_THREAD;
     894if( DEBUG_FATFS_GET_CLUSTER < cycle )
     895printk("\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 );
     897#endif
     898
     899    // get local pointer on VFS context (same in all clusters)
     900    vfs_ctx_t * vfs_ctx = &fs_context[FS_TYPE_FATFS];
     901
     902    // get local pointer on local FATFS context
     903    fatfs_ctx_t * loc_fatfs_ctx = vfs_ctx->extend;
     904
     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 );
     908
     909    // get local pointer on FATFS context in FAT cluster
     910    fatfs_ctx_t * fat_fatfs_ctx = hal_remote_lpt( XPTR( fat_cxy , &vfs_ctx->extend ) );
     911
     912    // build extended pointer on FAT lock in FAT cluster
     913    lock_xp = XPTR( fat_cxy , &fat_fatfs_ctx->lock );
     914
     915    // take FAT lock in read mode
     916    remote_rwlock_rd_acquire( lock_xp );
     917
     918    // initialize loop variables
     919    current_page_id    = first_page_id;
     920    current_cluster_id = first_cluster_id;
     921
     922    // scan FAT mapper (i.e. traverse FAT linked list)
     923    // starting from first_page_id until searched_page_id
     924    // each iteration in this loop can change both
     925    // the FAT page index and the slot index in FAT
     926    while( current_page_id < searched_page_id )
     927    {
     928        // FAT mapper page and slot indexes (1024 slots per FAT page)
     929        uint32_t fat_page_index   = current_cluster_id >> 10;
     930        uint32_t fat_slot_index   = current_cluster_id & 0x3FF;
     931
     932        // 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 );
     934
     935        if( current_page_xp == XPTR_NULL )
     936        {
     937            printk("\n[ERROR] in %s : cannot get page %d from FAT mapper\n",
     938            __FUNCTION__ , fat_page_index );
     939            remote_rwlock_rd_release( lock_xp );
     940            return -1;
     941        }
     942
     943        // 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 );
     946
     947        // get next_cluster_id from FAT slot 
     948        uint32_t next_cluster_id = hal_remote_l32( XPTR( fat_cxy, &buffer[fat_slot_index] ) );
     949
     950        // allocate a new FAT cluster when there is no cluster
     951        // allocated on device for the current page
     952        if( next_cluster_id >= END_OF_CHAIN_CLUSTER_MIN )
     953        {
     954            // release the FAT lock in read mode,
     955            remote_rwlock_rd_release( lock_xp );
     956
     957            // 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
     960            if( error )
     961            {
     962                printk("\n[ERROR] in %s : cannot allocate cluster on FAT32 for page %d\n",
     963                __FUNCTION__ , current_page_id );
     964                remote_rwlock_wr_release( lock_xp );
     965                return -1;
     966            }
     967
     968#if (DEBUG_FATFS_GET_CLUSTER & 1)
     969if( DEBUG_FATFS_GET_CLUSTER < cycle )
     970printk("\n[%s] allocated a new cluster_id %d in FATFS\n",
     971__FUNCTION__, next_cluster_id );
     972#endif
     973            // take the FAT lock in read mode,
     974            remote_rwlock_rd_acquire( lock_xp );
     975        }
     976
     977#if (DEBUG_FATFS_GET_CLUSTER & 1)
     978if( DEBUG_FATFS_GET_CLUSTER < cycle )
     979printk("\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 );
     981#endif
     982
     983        // update loop variables
     984        current_cluster_id = next_cluster_id;
     985        current_page_id++;
     986    }
     987   
     988    // release FAT lock
     989    remote_rwlock_rd_release( lock_xp );
     990
     991#if DEBUG_FATFS_GET_CLUSTER
     992if( DEBUG_FATFS_GET_CLUSTER < cycle )
     993printk("\n[%s] thread[%x,%x] exit / searched_cluster_id = %d\n",
     994__FUNCTION__, this->process->pid, this->trdid, current_cluster_id );
     995#endif
     996
     997    *searched_cluster_id = current_cluster_id;
     998    return 0;
     999
     1000}  // end fatfs_get_cluster()
     1001
     1002
     1003
    8521004
    8531005
     
    9041056//////////////////////////////////////////
    9051057void fatfs_display_fat( uint32_t  page_id,
    906                         uint32_t  nentries )
     1058                        uint32_t  min_slot,
     1059                        uint32_t  nb_slots )
    9071060{
    9081061    uint32_t line;
    909     uint32_t maxline;
    9101062
    9111063    // compute number of lines to display
    912     maxline = nentries >> 3;
    913     if( nentries & 0x7 ) maxline++;
     1064    uint32_t min_line = min_slot >> 3;
     1065    uint32_t max_line = (min_slot + nb_slots - 1) >> 3;
    9141066
    9151067    // get pointer on local FATFS context
     
    9171069    fatfs_ctx_t * loc_fatfs_ctx = (fatfs_ctx_t *)vfs_ctx->extend;
    9181070
    919     // get extended pointer on FAT mapper
    920     xptr_t fat_mapper_xp  = loc_fatfs_ctx->fat_mapper_xp;
    921 
    922     // get FAT cluster identifier
    923     cxy_t  fat_cxy = GET_CXY( fat_mapper_xp );
     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 );
    9241074
    9251075    // get pointer on FATFS context in FAT cluster
    926     fatfs_ctx_t * fat_fatfs_ctx = hal_remote_lpt( XPTR( fat_cxy , &vfs_ctx->extend ) );
     1076    fatfs_ctx_t * fat_fatfs_ctx = hal_remote_lpt( XPTR( mapper_cxy , &vfs_ctx->extend ) );
    9271077 
    9281078    // get current value of hint and free_clusters
    929     uint32_t hint = hal_remote_l32( XPTR( fat_cxy , &fat_fatfs_ctx->free_cluster_hint ) );
    930     uint32_t free = hal_remote_l32( XPTR( fat_cxy , &fat_fatfs_ctx->free_clusters ) );
    931  
    932     // get extended pointer on requested page in FAT mapper
    933     xptr_t     page_xp  = mapper_remote_get_page( fat_mapper_xp , page_id );
    934 
    935     // get extended pointer on requested page base
     1079    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 mapper
     1083    xptr_t page_xp = mapper_remote_get_page( mapper_xp , page_id );
     1084
     1085    // get pointers on requested page base
    9361086    xptr_t     base_xp  = ppm_page2base( page_xp );
    9371087    void     * base     = GET_PTR( base_xp );
    9381088
    9391089    printk("\n***** FAT mapper / cxy %x / page_id %d / base %x / free_clusters %x / hint %x\n",
    940     fat_cxy, page_id, base, free, hint );
    941 
    942     for( line = 0 ; line < maxline ; line++ )
    943     {
    944         printk("%x : %X | %X | %X | %X | %X | %X | %X | %X\n", (line<<3),
     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),
    9451095        hal_remote_l32( base_xp + ((line<<5)      ) ),
    9461096        hal_remote_l32( base_xp + ((line<<5) + 4  ) ),
     
    9541104
    9551105}  // end fatfs_display_fat()
    956 
    957 ///////////////////////////////////////////////////////
    958 error_t fatfs_get_cluster( uint32_t   first_cluster_id,
    959                            uint32_t   searched_page_index,
    960                            uint32_t * searched_cluster_id )
    961 {
    962     xptr_t     current_page_xp;        // pointer on current page descriptor
    963     uint32_t * buffer;                 // pointer on current page (array of uint32_t)
    964     uint32_t   current_page_index;     // index of current page in FAT
    965     uint32_t   current_slot_index;     // index of slot in current page
    966     uint32_t   page_count_in_file;     // index of page in file (index in linked list)
    967     uint32_t   next_cluster_id;        // content of current FAT slot
    968     xptr_t     lock_xp;                // extended pointer on FAT lock
    969 
    970 assert( (searched_page_index > 0) ,
    971 "no FAT access required for first page\n");
    972 
    973 #if DEBUG_FATFS_GET_CLUSTER
    974 uint32_t   cycle = (uint32_t)hal_get_cycles();
    975 thread_t * this  = CURRENT_THREAD;
    976 if( DEBUG_FATFS_GET_CLUSTER < cycle )
    977 printk("\n[%s] thread[%x,%x] enter / first_cluster_id %d / searched_index %d / cycle %d\n",
    978 __FUNCTION__, this->process->pid, this->trdid, first_cluster_id, searched_page_index, cycle );
    979 #endif
    980 
    981     // get local pointer on VFS context (same in all clusters)
    982     vfs_ctx_t * vfs_ctx = &fs_context[FS_TYPE_FATFS];
    983 
    984     // get local pointer on local FATFS context
    985     fatfs_ctx_t * loc_fatfs_ctx = vfs_ctx->extend;
    986 
    987     // get extended pointer and cluster on FAT mapper
    988     xptr_t fat_mapper_xp  = loc_fatfs_ctx->fat_mapper_xp;
    989     cxy_t  fat_cxy        = GET_CXY( fat_mapper_xp );
    990 
    991     // get local pointer on FATFS context in FAT cluster
    992     fatfs_ctx_t * fat_fatfs_ctx = hal_remote_lpt( XPTR( fat_cxy , &vfs_ctx->extend ) );
    993 
    994     // build extended pointer on FAT lock in FAT cluster
    995     lock_xp = XPTR( fat_cxy , &fat_fatfs_ctx->lock );
    996 
    997     // take FAT lock in read mode
    998     remote_rwlock_rd_acquire( lock_xp );
    999 
    1000     // initialize loop variable (1024 slots per page)
    1001     current_page_index  = first_cluster_id >> 10;
    1002     current_slot_index  = first_cluster_id & 0x3FF;
    1003     page_count_in_file  = 0;
    1004     next_cluster_id     = 0xFFFFFFFF;
    1005 
    1006     // scan FAT mapper (i.e. traverse FAT linked list)
    1007     while( page_count_in_file < searched_page_index )
    1008     {
    1009         // get pointer on current page descriptor in FAT mapper
    1010         current_page_xp = mapper_remote_get_page( fat_mapper_xp , current_page_index );
    1011 
    1012         if( current_page_xp == XPTR_NULL )
    1013         {
    1014             printk("\n[ERROR] in %s : cannot get next page from FAT mapper\n", __FUNCTION__);
    1015             remote_rwlock_rd_release( lock_xp );
    1016             return -1;
    1017         }
    1018 
    1019         // get pointer on buffer for current page
    1020         xptr_t base_xp = ppm_page2base( current_page_xp );
    1021         buffer = (uint32_t *)GET_PTR( base_xp );
    1022 
    1023         // get FAT slot content
    1024         next_cluster_id = hal_remote_l32( XPTR( fat_cxy, &buffer[current_slot_index] ) );
    1025 
    1026 #if (DEBUG_FATFS_GET_CLUSTER & 1)
    1027 if( DEBUG_FATFS_GET_CLUSTER < cycle )
    1028 printk("\n[%s] traverse FAT / current_page_index = %d\n"
    1029 "current_slot_index = %d / next_cluster_id = %d\n",
    1030 __FUNCTION__, current_page_index, current_slot_index , next_cluster_id );
    1031 #endif
    1032         // update loop variables
    1033         current_page_index = next_cluster_id >> 10;
    1034         current_slot_index = next_cluster_id & 0x3FF;
    1035         page_count_in_file++;
    1036     }
    1037 
    1038     if( next_cluster_id == 0xFFFFFFFF )
    1039     {
    1040         printk("\n[ERROR] in %s : searched_cluster_id not found in FAT\n", __FUNCTION__ );
    1041         remote_rwlock_rd_release( lock_xp );
    1042         return -1;
    1043     }
    1044    
    1045     // release FAT lock
    1046     remote_rwlock_rd_release( lock_xp );
    1047 
    1048 #if DEBUG_FATFS_GET_CLUSTER
    1049 cycle = (uint32_t)hal_get_cycles();
    1050 if( DEBUG_FATFS_GET_CLUSTER < cycle )
    1051 printk("\n[%s] thread[%x,%x] exit / searched_cluster_id = %d / cycle %d\n",
    1052 __FUNCTION__, this->process->pid, this->trdid, next_cluster_id / cycle );
    1053 #endif
    1054 
    1055     *searched_cluster_id = next_cluster_id;
    1056     return 0;
    1057 
    1058 }  // end fatfs_get_cluster()
    10591106
    10601107
     
    16911738// by the <mapper> argument, to find the directory entry identified by the <name> argument,
    16921739// and return a pointer on the directory entry, described as and array of 32 bytes, and the
    1693 // incex of this entry in the FAT32 mapper, seen as an array of 32 bytes entries.
     1740// index of this entry in the FAT32 mapper, seen as an array of 32 bytes entries.
    16941741// It is called by the fatfs_new_dentry() and fatfs_update_dentry() functions.
    16951742// It must be called by a thread running in the cluster containing the mapper.
     
    17011748// @ return 0 if found / return 1 if not found / return -1 if mapper access error.
    17021749//////////////////////////////////////////////////////////////////////////////////////////////
    1703 error_t fatfs_scan_directory( mapper_t *  mapper,
    1704                               char     *  name,
    1705                               uint8_t  ** entry,
    1706                               uint32_t *  index )
     1750static error_t fatfs_scan_directory( mapper_t *  mapper,
     1751                                     char     *  name,
     1752                                     uint8_t  ** entry,
     1753                                     uint32_t *  index )
    17071754{
    17081755    // Two embedded loops to scan the directory mapper:
     
    17251772#endif
    17261773
    1727     char       cname[CONFIG_VFS_MAX_NAME_LENGTH];  // name extracted from each directory entry
     1774    char       cname[CONFIG_VFS_MAX_NAME_LENGTH];  // name extracted from directory entry
    17281775
    17291776    char       lfn1[16];         // buffer for one partial cname
     
    17611808#if (DEBUG_FATFS_SCAN_DIRECTORY & 0x1)
    17621809if( DEBUG_FATFS_SCAN_DIRECTORY < cycle )
    1763 mapper_display_page( mapper_xp , page_id , 256 );
     1810mapper_display_page( mapper_xp , page_xp , 256 );
    17641811#endif
    17651812        // scan this page until end of directory, end of page, or name found
     
    18831930    error_t        error;
    18841931
    1885     char           dir_name[CONFIG_VFS_MAX_NAME_LENGTH];
     1932    char           parent_name[CONFIG_VFS_MAX_NAME_LENGTH];
    18861933
    18871934// check arguments
     
    19001947assert( (xlist_is_empty( root_xp ) == false ), "child inode must have one parent\n");
    19011948
    1902 #if DEBUG_FATFS_GET_DENTRY
     1949#if DEBUG_FATFS_NEW_DENTRY
    19031950uint32_t   cycle = (uint32_t)hal_get_cycles();
    19041951thread_t * this  = CURRENT_THREAD;
    1905 vfs_inode_get_name( XPTR( local_cxy , parent_inode ) , dir_name );
    1906 if( DEBUG_FATFS_GET_DENTRY < cycle )
     1952vfs_inode_get_name( XPTR( local_cxy , parent_inode ) , parent_name );
     1953if( DEBUG_FATFS_NEW_DENTRY < cycle )
    19071954printk("\n[%s]  thread[%x,%x] enter for child <%s> in parent <%s> / cycle %d\n",
    1908 __FUNCTION__, this->process->pid, this->trdid, name , dir_name , cycle );
     1955__FUNCTION__, this->process->pid, this->trdid, name , parent_name , cycle );
    19091956#endif
    19101957
     
    19161963
    19171964    // return non fatal error if not found
    1918     if( error ) return -1;
     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 
    19191973
    19201974    // get relevant infos from FAT32 directory entry
     
    19462000    if( found == false )
    19472001    {
    1948         vfs_inode_get_name( XPTR( local_cxy , parent_inode ) , dir_name );
     2002        vfs_inode_get_name( XPTR( local_cxy , parent_inode ) , parent_name );
    19492003        printk("\n[ERROR] in %s : cannot find <%s> directory in list of parents for <%s>\n",
    1950         __FUNCTION__, dir_name, name );
     2004        __FUNCTION__, parent_name, name );
    19512005        return -1;
    19522006    }
     
    19622016    dentry_ptr->extend = (void *)(intptr_t)index;
    19632017
    1964 #if DEBUG_FATFS_GET_DENTRY
     2018#if DEBUG_FATFS_NEW_DENTRY
    19652019cycle = (uint32_t)hal_get_cycles();
    1966 if( DEBUG_FATFS_GET_DENTRY < cycle )
    1967 printk("\n[%s]  thread[%x,%x] exit / intialised inode & dentry for <%s> in <%s> / cycle %d\n",
    1968 __FUNCTION__, this->process->pid, this->trdid, name, dir_name, cycle );
     2020if( DEBUG_FATFS_NEW_DENTRY < cycle )
     2021printk("\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)
     2027if( DEBUG_FATFS_NEW_DENTRY < cycle )
     2028{
     2029    fatfs_display_fat( 0 , 0 , 64 );
     2030    fatfs_display_fat( cluster >> 10 ,  (cluster & 0x3FF) , 32 );
     2031}
    19692032#endif
    19702033
     
    19882051assert( (inode  != NULL) , "inode is NULL\n" );
    19892052assert( (dentry != NULL) , "dentry is NULL\n" );
    1990 assert( (size   != 0   ) , "size is 0\n" );
    19912053
    19922054#if DEBUG_FATFS_UPDATE_DENTRY
     
    20132075    }
    20142076
    2015     // set size in FAT32 directory entry
    2016     fatfs_set_record( DIR_FILE_SIZE , entry , size );
    2017 
    2018     // get local pointer on modified page base
    2019     void * base = (void *)((intptr_t)entry & (~CONFIG_PPM_PAGE_MASK));
    2020 
    2021     // get extended pointer on modified page descriptor
    2022     xptr_t page_xp = ppm_base2page( XPTR( local_cxy , base ) );
    2023 
    2024     // synchronously update the modified page on device
    2025     error = fatfs_move_page( page_xp , IOC_SYNC_WRITE );
    2026 
    2027     if( error )
    2028     {
    2029         vfs_inode_get_name( XPTR( local_cxy , inode ) , dir_name );
    2030         printk("\n[ERROR] in %s : cannot update parent directory <%s> on device\n",
    2031         __FUNCTION__, dir_name );
    2032         return -1;
     2077    // get current size value
     2078    uint32_t current_size = fatfs_get_record( DIR_FILE_SIZE , entry );
     2079
     2080    // update dentry in mapper & device only if required
     2081    if( size != current_size )
     2082    {
     2083        // 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
     2093        error = fatfs_move_page( page_xp , IOC_SYNC_WRITE );
     2094
     2095        if( error )
     2096        {
     2097            vfs_inode_get_name( XPTR( local_cxy , inode ) , dir_name );
     2098            printk("\n[ERROR] in %s : cannot update parent directory <%s> on device\n",
     2099            __FUNCTION__, dir_name );
     2100            return -1;
     2101        }
    20332102    }
    20342103
     
    25862655    return 0;
    25872656
    2588 }  // end fat_cluster_alloc()
     2657}  // end fatfs_cluster_alloc()
    25892658
    25902659//////////////////////////////////////////////
     
    27372806#endif
    27382807
    2739     // get page cluster an local pointer
     2808    // get page cluster and local pointer
    27402809    cxy_t    page_cxy = GET_CXY( page_xp );
    27412810    page_t * page_ptr = GET_PTR( page_xp );
     
    27542823    inode_ptr  = hal_remote_lpt( XPTR( page_cxy , &mapper_ptr->inode ) );
    27552824
     2825    //////////////////////////////  FAT mapper  /////////////////////////////////////////
     2826    if( inode_ptr == NULL )
     2827    {
     2828
    27562829#if DEBUG_FATFS_MOVE_PAGE
    27572830if( DEBUG_FATFS_MOVE_PAGE < cycle )
    2758 printk("\n[%s] thread[%x,%x] enters : %s / cxy %x / mapper %x / inode %x / page %x\n",
    2759 __FUNCTION__, this->process->pid, this->trdid,
    2760 dev_ioc_cmd_str( cmd_type ), page_cxy, mapper_ptr, inode_ptr, GET_PTR(buffer_xp) );
    2761 #endif
    2762 
    2763     //////////////////////////////  FAT mapper
    2764     if( inode_ptr == NULL )
    2765     {
     2831printk("\n[%s] thread[%x,%x] enters for %s /  page %d in FAT mapper / cycle %d\n",
     2832__FUNCTION__, this->process->pid, this->trdid, dev_ioc_cmd_str(cmd_type), page_id, cycle );
     2833#endif
    27662834        // get lba from FATFS context and page_id
    27672835        uint32_t      lba = fatfs_ctx->fat_begin_lba + (page_id << 3);
     
    27782846#if DEBUG_FATFS_MOVE_PAGE
    27792847if( DEBUG_FATFS_MOVE_PAGE < cycle )
    2780 {
    2781     if ( (cmd_type == IOC_READ) || (cmd_type == IOC_SYNC_READ) )
    2782         printk("\n[%s] thread[%x,%x] load FAT mapper page %d from IOC / cycle %d\n",
    2783         __FUNCTION__, this->process->pid, this->trdid, page_id, cycle );
    2784     else
    2785         printk("\n[%s] thread[%x,%x] sync FAT mapper page %d to IOC / cycle %d\n",
    2786         __FUNCTION__, this->process->pid, this->trdid, page_id, cycle );
    2787 }
    2788 #endif
    2789 
    2790     }
    2791     /////////////////////////  inode mapper
     2848printk("\n[%s] thread[%x,%x] exit / page %d in FAT mapper\n",
     2849__FUNCTION__, this->process->pid, this->trdid, page_id, cycle );
     2850#endif
     2851
     2852    }
     2853    /////////////////////////  inode mapper  ////////////////////////////////////////////
    27922854    else                       
    27932855    {
     
    27952857#if DEBUG_FATFS_MOVE_PAGE
    27962858vfs_inode_get_name( XPTR( page_cxy , inode_ptr ) , name );
    2797 #endif
    2798 
    2799         uint32_t  searched_cluster;
    2800         uint32_t  first_cluster;
    2801 
    2802         // get first_cluster from inode extension
    2803         void * extend = hal_remote_lpt( XPTR( page_cxy , &inode_ptr->extend ) );
    2804         first_cluster = (uint32_t)(intptr_t)extend;
    2805 
    2806         // compute searched_cluster
     2859if( DEBUG_FATFS_MOVE_PAGE < cycle )
     2860printk("\n[%s] thread[%x,%x] enters for %s / page %d in <%s> mapper/ cycle %d\n",
     2861__FUNCTION__, this->process->pid, this->trdid,
     2862dev_ioc_cmd_str( cmd_type ), page_id, name, cycle );
     2863#endif
     2864
     2865        uint32_t  searched_cluster_id;
     2866        uint32_t  first_cluster_id;
     2867
     2868        // get first_cluster_id from inode extension
     2869        void * extend    = hal_remote_lpt( XPTR( page_cxy , &inode_ptr->extend ) );
     2870        first_cluster_id = (uint32_t)(intptr_t)extend;
     2871
     2872        // compute searched_cluster_id
    28072873        if( page_id == 0 )            // no need to access FAT mapper
    28082874        {
    28092875            // searched cluster is first cluster
    2810             searched_cluster = first_cluster;
     2876            searched_cluster_id = first_cluster_id;
    28112877        }
    28122878        else                        // FAT mapper access required
    28132879        {
    2814             // access FAT mapper to get searched cluster
    2815             error = fatfs_get_cluster( first_cluster,
     2880            // scan FAT mapper to get searched_cluster_id
     2881            error = fatfs_get_cluster( 0,                    // first page in mapper
     2882                                       first_cluster_id,
    28162883                                       page_id,
    2817                                        &searched_cluster );
     2884                                       &searched_cluster_id );
    28182885            if( error )
    28192886            {
    2820                 printk("\n[ERROR] in %s : cannot access FAT mapper\n", __FUNCTION__ );
     2887                printk("\n[ERROR] in %s : cannot get cluster_id\n", __FUNCTION__ );
    28212888                return -1;
    28222889            }
     
    28242891
    28252892        // get lba for searched_cluster
    2826         uint32_t lba = fatfs_lba_from_cluster( fatfs_ctx , searched_cluster );
    2827 
    2828         // access IOC device
     2893        uint32_t lba = fatfs_lba_from_cluster( fatfs_ctx , searched_cluster_id );
     2894
     2895        // access IOC device to move 8 blocks
    28292896        error = dev_ioc_move_data( cmd_type , buffer_xp , lba , 8 );
    28302897
     
    28372904#if DEBUG_FATFS_MOVE_PAGE
    28382905if( DEBUG_FATFS_MOVE_PAGE < cycle )
    2839 {
    2840     if ( (cmd_type == IOC_READ) || (cmd_type == IOC_SYNC_READ) )
    2841     printk("\n[%s] thread[%x,%x] load page %d of <%s> / cluster_id %x / cycle %d\n",
    2842     __FUNCTION__, this->process->pid, this->trdid, page_id, name, searched_cluster, cycle );
    2843     else
    2844     printk("\n[%s] thread[%x,%x] sync page %d of <%s> / cluster_id %x / cycle %d\n",
    2845     __FUNCTION__, this->process->pid, this->trdid, page_id, name, searched_cluster, cycle );
    2846 }
     2906vfs_inode_get_name( XPTR( page_cxy, inode_ptr ) , name );
     2907printk("\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 );
    28472909#endif
    28482910
  • trunk/kernel/fs/fatfs.h

    r638 r656  
    3232
    3333
    34 /**************************************************************************************
     34/******************************************************************************************
    3535 * The FATFS File System implements a FAT32 read/write file system.
    3636 *
     
    4343 *    on the FAT mapper.
    4444 * 2) The vfs_inode_t "extend" contains, for each inode,
    45  *    the first FAT cluster index (after cast to intptr).
     45 *    the first FAT32 cluster_id (after cast to intptr).
    4646 * 3) The vfs_dentry_t "extend" field contains, for each dentry, the entry index
    47  *    in the FATFS directory (32 bytes per FATFS entry).
    48  *************************************************************************************/
     47 *    in the FATFS directory (32 bytes per FATFS directory entry).
     48 *
     49 * In the FAT32 File System, the File Allocation Table is is actually an array
     50 * of uint32_t slots. Each slot in this array contains the index (called cluster_id)
     51 * of another slot in this array, to form one linked list for each file stored on
     52 * device in the FAT32 File System. This index in the FAT array is also the index of
     53 * the FATFS cluster on the device. One FATFS cluster is supposed to contain one PPM page.
     54 * For a given file, the entry point in the FAT is the cluster_id of the FATFS cluster
     55 * containing the first page of the file, but it can be any cluster_id already allocated
     56 * to the file.
     57 *****************************************************************************************/
    4958 
    5059///////////////////////////////////////////////////////////////////////////////////////////
     
    213222
    214223/*****************************************************************************************
    215  * This function access the FAT (File Allocation Table), stored in the FAT mapper, and
    216  * returns in <searched_cluster> the FATFS cluster index for a given page of a given
    217  * inode identified by the <first_cluster> and <page_id> arguments.
    218  * It can be called by a thread running in any cluster, as it uses remote access
    219  * primitives when the FAT mapper is remote.
    220  * The FAT is actually an array of uint32_t slots. Each slot in this array contains the
    221  * index of another slot in this array, to form one linked list for each file stored on
    222  * device in the FATFS file system. This index in the FAT array is also the index of the
    223  * FATFS cluster on the device. One FATFS cluster is supposed to contain one PPM page.
    224  * For a given file, the entry point in the FAT is simply the index of the FATFS cluster
    225  * containing the first page of the file. The FAT mapper being a cache, this function
    226  * updates the FAT mapper from informations stored on IOC device in case of miss.
    227  *****************************************************************************************
    228  * @ first_cluster       : [in]  index of first FATFS cluster allocated to the file.
    229  * @ page_id             : [in]  index of searched page in file.
    230  * @ searched_cluster    : [out] found FATFS cluster index.
    231  * @ return 0 if success / return -1 if a FAT mapper miss cannot be solved.
    232  ****************************************************************************************/
    233 error_t fatfs_get_cluster( uint32_t   first_cluster,
    234                            uint32_t   page_id,
    235                            uint32_t * searched_cluster );
    236 
    237 /*****************************************************************************************
    238  * This function display the content of the FATFS context copy in cluster identified
    239  * by the <cxy> argument.
     224 * This debug function display the content of the FATFS context copy in cluster
     225 * identified by the <cxy> argument.
    240226 * This function can be called by a thread running in any cluster.
    241227 *****************************************************************************************
     
    245231
    246232/*****************************************************************************************
    247  * This function access the FAT mapper to display one page of the File Allocation Table.
    248  * It loads the requested page fom IOC device to FAT mapper if required.
     233 * 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.
    249236 * This function can be called by a thread running in any cluster.
    250237 *****************************************************************************************
    251  * @ page_id     : page index in FAT mapper (one page is 4 Kbytes).
    252  * @ nb_entries  : number of entries (one entry is 4 bytes).
     238 * @ page_id   : page index in FAT mapper (one page is 4 Kbytes = 1024 slots).
     239 * @ min_slot  : first slot in page
     240 * @ nb_slots  : number of slots (one slot is 4 bytes).
    253241 ****************************************************************************************/
    254242void fatfs_display_fat( uint32_t  page_id,
    255                         uint32_t  nb_entries );
     243                        uint32_t  min_slot,
     244                        uint32_t  nb_slots );
    256245
    257246
     
    330319 *****************************************************************************************
    331320 * It scan a parent directory mapper, identified by the <parent_inode> argument to find
    332  * a directory entry identified by the <name> argument.  In case of success, it
    333  * initializes the inode/dentry couple, identified by the  <child_inode_xp> argument
    334  * in the Inode Tree. The child inode descriptor, and the associated dentry descriptor
    335  * must have been previously allocated by the caller.
     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.
    336325 * - It set the "type", "size", and "extend" fields in the child inode descriptor.
    337326 * - It set the " extend" field in the dentry descriptor.
     
    421410 * TODO : the current implementation check ALL pages in the FAT region, even if most
    422411 * pages are empty, and not copied in mapper. It is sub-optimal.
    423  * - A first solution is to maintain in the FAT context two "dirty_min" and "dirty_max"
    424  *  variables defining the smallest/largest dirty page index in FAT mapper...
     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...
    425414 *****************************************************************************************
    426415 * @ return 0 if success / return -1 if failure during IOC device access.
     
    448437 * in <searched_cluster> the FATFS cluster index of a free cluster.
    449438 * It can be called by a thread running in any cluster, as it uses remote access
    450  * primitives when the FAT mapper is remote. It takes the queuelock stored in the FATFS
     439 * primitives when the FAT mapper is remote. It takes the rwlock stored in the FATFS
    451440 * context located in the same cluster as the FAT mapper itself, to get exclusive
    452441 * access to the FAT. It uses and updates the <free_cluster_hint> and <free_clusters>
     
    457446 * - it returns the allocated cluster index.
    458447 *****************************************************************************************
    459  * @ searched_cluster    : [out] found FATFS cluster index.
     448 * @ searched_cluster_id  : [out] allocated FATFS cluster index.
    460449 * @ return 0 if success / return -1 if no more free clusters on IOC device.
    461450 ****************************************************************************************/
    462 error_t fatfs_cluster_alloc( uint32_t * searched_cluster );
     451error_t fatfs_cluster_alloc( uint32_t * searched_cluster_id );
    463452
    464453/*****************************************************************************************
    465454 * This function implements the generic vfs_fs_release_inode() function for the FATFS.
    466   *****************************************************************************************
     455 *****************************************************************************************
     456 * This function is used to remove a given file or directory from FATFS the file system.
    467457 * It releases all clusters allocated to a file/directory identified by the <inode_xp>
    468458 * argument. All released clusters are marked FREE_CLUSTER in the FAT mapper.
     
    470460 * the clusters in reverse order of the linked list (from last to first).
    471461 * When the FAT mapper has been updated, it calls the fatfs_sync_fat() function to
    472  * synchronously update all dirty pages in the FAT mapper to the IOC device.
     462 * synchronously update all modified pages in the FAT mapper to the IOC device.
    473463 * Finally the FS-INFO sector on the IOC device is updated.
    474464 *****************************************************************************************
     
    485475 * The pointer on the mapper and the page index in file are found in the page descriptor.
    486476 * It is used for both a regular file/directory mapper, and the FAT mapper.
    487  * - For the FAT mapper, it updates the FAT region on IOC device.
    488  * - For a regular file, it access the FAT mapper to get the cluster index on IOC device.
     477 * - For the FAT mapper, it read/write the FAT region on IOC device.
     478 * - For a regular file, it scan the FAT mapper to get the cluster_id on IOC device,
     479 *   and read/write this cluster.
    489480 * It can be called by any thread running in any cluster.
    490481 *
    491482 * WARNING : For the FAT mapper, the inode field in the mapper MUST be NULL, as this
    492  * is used to indicate that the corresponding mapper is the FAT mapper.
     483 *           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_id
     486 *        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 a
     488 *        big file. An optimisation would be to introduce in the inode extension two
     489 *        new fields <other_page_id> & <other_cluster_id>, defining a second entry point
     490 *        in the FAT.
    493491 *****************************************************************************************
    494492 * @ page_xp   : extended pointer on page descriptor.
  • trunk/kernel/fs/vfs.c

    r651 r656  
    235235
    236236#if DEBUG_VFS_INODE_CREATE
    237 char           name[CONFIG_VFS_MAX_NAME_LENGTH];
    238237uint32_t       cycle      = (uint32_t)hal_get_cycles();
    239238thread_t *     this       = CURRENT_THREAD;
    240 vfs_inode_get_name( *inode_xp , name );
    241239if( DEBUG_VFS_INODE_CREATE < cycle )
    242 printk("\n[%s] thread[%x,%x] created <%s> / inode [%x,%x] / cycle %d\n",
    243 __FUNCTION__, this->process->pid, this->trdid, name, local_cxy, inode, cycle );
     240printk("\n[%s] thread[%x,%x] created inode (%x,%x) / cycle %d\n",
     241__FUNCTION__, this->process->pid, this->trdid, local_cxy, inode, cycle );
    244242#endif
    245243 
     
    513511uint32_t   cycle = (uint32_t)hal_get_cycles();
    514512if( DEBUG_VFS_DENTRY_CREATE < cycle )
    515 printk("\n[%s] thread[%x,%x] created <%s> / dentry [%x,%x] / cycle %d\n",
     513printk("\n[%s] thread[%x,%x] created dentry <%s> : (%x,%x) / cycle %d\n",
    516514__FUNCTION__, this->process->pid, this->trdid, name, local_cxy, dentry, cycle );
    517515#endif
     
    777775}  // end vfs_open()
    778776
    779 //////////////////////////////////////
    780 int vfs_user_move( bool_t   to_buffer,
    781                    xptr_t   file_xp,
    782                    void   * buffer,
    783                    uint32_t size )
    784 {
    785     cxy_t              file_cxy;     // remote file descriptor cluster
    786     vfs_file_t       * file_ptr;     // remote file descriptor local pointer
    787     vfs_inode_type_t   inode_type;
    788     uint32_t           file_offset;  // current offset in file
    789     mapper_t         * mapper;
     777///////////////////////////////////////////
     778uint32_t vfs_user_move( bool_t   to_buffer,
     779                        xptr_t   file_xp,
     780                        void   * buffer,
     781                        uint32_t count )
     782{
     783    cxy_t              file_cxy;       // remote file descriptor cluster
     784    vfs_file_t       * file_ptr;       // remote file descriptor local pointer
     785    mapper_t         * mapper;         // local pointer on file mapper
     786    vfs_inode_t      * inode;          // local pointer on file inode
     787    vfs_inode_type_t   type;           // inode type
     788    uint32_t           offset;         // current offset in file
     789    uint32_t           size;           // current file size
     790    uint32_t           nbytes;         // number of bytes actually transfered
    790791    error_t            error;
    791792
     
    797798    file_ptr  = GET_PTR( file_xp );
    798799
    799     // get inode type from remote file descriptor
    800     inode_type = hal_remote_l32( XPTR( file_cxy , &file_ptr->type   ) );
     800    // get various infos from remote file descriptor
     801    type   = hal_remote_l32( XPTR( file_cxy , &file_ptr->type   ) );
     802    offset = hal_remote_l32( XPTR( file_cxy , &file_ptr->offset ) );
     803    mapper = hal_remote_lpt( XPTR( file_cxy , &file_ptr->mapper ) );
     804    inode  = hal_remote_lpt( XPTR( file_cxy , &file_ptr->inode  ) );
     805    size   = hal_remote_l32( XPTR( file_cxy , &inode->size      ) );
    801806   
    802807// check inode type
    803 assert( (inode_type == INODE_TYPE_FILE), "bad inode type" );
    804 
    805     // get mapper pointer and file offset from file descriptor
    806     file_offset = hal_remote_l32( XPTR( file_cxy , &file_ptr->offset ) );
    807     mapper      = hal_remote_lpt( XPTR( file_cxy , &file_ptr->mapper ) );
     808assert( (type == INODE_TYPE_FILE), "bad inode type" );
    808809
    809810#if DEBUG_VFS_USER_MOVE
     
    811812uint32_t      cycle      = (uint32_t)hal_get_cycles();
    812813thread_t    * this       = CURRENT_THREAD;
    813 vfs_inode_t * inode      = hal_remote_lpt( XPTR( file_cxy , &file_ptr->inode ) );
    814814vfs_inode_get_name( XPTR( file_cxy , inode ) , name );
    815815if( cycle > DEBUG_VFS_USER_MOVE )
     
    817817    if( to_buffer )
    818818    printk("\n[%s] thread[%x,%x] enter / %d bytes / map(%s) -> buf(%x) / offset %d / cycle %d\n",
    819     __FUNCTION__ , this->process->pid, this->trdid, size, name, buffer, file_offset, cycle );
     819    __FUNCTION__ , this->process->pid, this->trdid, count, name, buffer, offset, cycle );
    820820    else           
    821821    printk("\n[%s] thread[%x,%x] enter / %d bytes / buf(%x) -> map(%s) / offset %d / cycle %d\n",
    822     __FUNCTION__ , this->process->pid, this->trdid, size, buffer, name, file_offset, cycle );
     822    __FUNCTION__ , this->process->pid, this->trdid, count, buffer, name, offset, cycle );
    823823}
    824824#endif
    825825
    826     // move data between mapper and buffer
    827     error = mapper_move_user( XPTR( file_cxy , mapper ),
    828                               to_buffer,
    829                               file_offset,
    830                               buffer,
    831                               size );
     826    if( to_buffer ) // => compute the number of bytes to move and make the move
     827    {
     828        // compute number of bytes to move
     829        if     ( size <= offset )         nbytes = 0;
     830        else if( size < offset + count )  nbytes = size - offset;
     831        else                              nbytes = count;
     832
     833        // move data from mapper to buffer when required
     834        if( nbytes > 0 )
     835        {     
     836            error = mapper_move_user( XPTR( file_cxy , mapper ),
     837                                      to_buffer,
     838                                      offset,
     839                                      buffer,
     840                                      nbytes );
     841        }
     842        else
     843        {
     844            error = 0;
     845        }
     846    }
     847    else // to mapper => make the move and update the file size if required
     848    {
     849        nbytes = count;
     850
     851        // move data from buffer to mapper
     852        error = mapper_move_user( XPTR( file_cxy , mapper ),
     853                                  to_buffer,
     854                                  offset,
     855                                  buffer,
     856                                  count );
     857
     858        // update file size in inode if required
     859        if( offset + count > size )
     860        {
     861            vfs_inode_update_size( XPTR( file_cxy , inode ) , offset + count );
     862        }
     863    }
     864       
    832865    if( error )
    833866    {
     
    837870
    838871    // update file offset in file descriptor
    839     hal_remote_atomic_add( XPTR( file_cxy , &file_ptr->offset ) , size );
     872    hal_remote_atomic_add( XPTR( file_cxy , &file_ptr->offset ) , nbytes );
    840873
    841874#if DEBUG_VFS_USER_MOVE
     
    844877{
    845878    if( to_buffer )
    846     printk("\n[%s] thread[%x,%x] exit / cycle %d\n",
    847     __FUNCTION__ , this->process->pid, cycle );
     879    printk("\n[%s] thread[%x,%x] exit / %d bytes moved from mapper to buffer\n",
     880    __FUNCTION__ , this->process->pid, nbytes );
    848881    else           
    849     printk("\n[%s] thread[%x,%x] exit / cycle %d\n",
    850     __FUNCTION__ , this->process->pid, cycle );
     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)) );
    851884}
    852885#endif
    853886
    854     return size;
     887    return nbytes;
    855888
    856889}  // end vfs_user_move()
     
    24832516#endif
    24842517
     2518#if ( DEBUG_VFS_LOOKUP & 1 )
     2519if( DEBUG_VFS_LOOKUP < cycle )
     2520vfs_display( root_xp );
     2521#endif
     2522
    24852523    // compute lookup flags
    24862524    create = (lookup_mode & VFS_LOOKUP_CREATE) == VFS_LOOKUP_CREATE;
     
    25272565#endif
    25282566
    2529         // search the child dentry matching name in parent inode
     2567        // search the child dentry matching name in parent inode XHTAB
    25302568        found = vfs_get_child( parent_xp,
    25312569                               name,
     
    25932631#if (DEBUG_VFS_LOOKUP & 1)
    25942632if( DEBUG_VFS_LOOKUP < cycle )
    2595 printk("\n[%s] thread[%x,%x] created missing inode for <%s> in cluster %x\n",
     2633printk("\n[%s] thread[%x,%x] created missing inode <%s> in cluster %x\n",
    25962634__FUNCTION__, process->pid, this->trdid, name, child_cxy );
    25972635#endif
     
    27712809{
    27722810    error_t     error;
    2773     uint32_t    cluster;
     2811    uint32_t    cluster_id;
    27742812    uint32_t    child_type;
    27752813    uint32_t    child_size;
     
    27982836    vfs_inode_t  * child_ptr  = GET_PTR( child_xp );
    27992837
    2800     // 1. allocate one free cluster in file system to child inode,
     2838    // 1. allocate one free cluster_id in file system to child inode,
    28012839    // and update the File Allocation Table in both the FAT mapper and IOC device.
    28022840    // It depends on the child inode FS type.
     
    28042842
    28052843    error = vfs_fs_cluster_alloc( ctx->type,
    2806                                   &cluster );
     2844                                  &cluster_id );
    28072845    if ( error )
    28082846    {
    2809         printk("\n[ERROR] in %s : cannot find a free VFS cluster\n",
     2847        printk("\n[ERROR] in %s : cannot find a free VFS cluster_id\n",
    28102848        __FUNCTION__ );
    28112849        return -1;
     
    28142852#if( DEBUG_VFS_NEW_DENTRY_INIT & 1)
    28152853if( DEBUG_VFS_NEW_DENTRY_INIT < cycle )
    2816 printk("\n[%s] thread[%x,%x] allocated FS cluster %x to <%s>\n",
    2817 __FUNCTION__ , this->process->pid, this->trdid, cluster, child_name );
     2854printk("\n[%s] thread[%x,%x] allocated FS cluster_id %x to <%s>\n",
     2855__FUNCTION__ , this->process->pid, this->trdid, cluster_id, child_name );
    28182856#endif
    28192857
    28202858    // 2. update the child inode descriptor size and extend
    28212859    child_type = hal_remote_l32( XPTR( child_cxy , &child_ptr->type ) );
    2822     child_size = (child_type == INODE_TYPE_DIR) ? 4096 : 0;
     2860    child_size = 0;
    28232861   
    28242862    hal_remote_s32( XPTR( child_cxy , &child_ptr->size )   , child_size );
    2825     hal_remote_spt( XPTR( child_cxy , &child_ptr->extend ) , (void*)(intptr_t)cluster );
     2863    hal_remote_spt( XPTR( child_cxy , &child_ptr->extend ) , (void*)(intptr_t)cluster_id );
    28262864
    28272865    // 3. update the parent inode mapper, and
     
    32853323#if(DEBUG_VFS_ADD_CHILD & 1)
    32863324if( DEBUG_VFS_ADD_CHILD < cycle )
    3287 printk("\n[%s] thread[%x,%x] / dentry <%s> created (%x,%x)\n",
     3325printk("\n[%s] thread[%x,%x] created dentry <%s> : (%x,%x)\n",
    32883326__FUNCTION__, this->process->pid, this->trdid, name, parent_cxy, new_dentry_ptr );
    32893327#endif
     
    33323370#if(DEBUG_VFS_ADD_CHILD & 1)
    33333371if( DEBUG_VFS_ADD_CHILD < cycle )
    3334 printk("\n[%s] thread[%x,%x] / inode <%s> created (%x,%x)\n",
     3372printk("\n[%s] thread[%x,%x] created inode <%s> : (%x,%x)\n",
    33353373__FUNCTION__ , this->process->pid, this->trdid, name , child_cxy, new_inode_ptr );
    33363374#endif
     
    33453383#if(DEBUG_VFS_ADD_CHILD & 1)
    33463384if( DEBUG_VFS_ADD_CHILD < cycle )
    3347 printk("\n[%s] thread[%x,%x] link dentry(%x,%x) to child inode(%x,%x)\n",
     3385printk("\n[%s] thread[%x,%x] linked dentry(%x,%x) to child inode(%x,%x)\n",
    33483386__FUNCTION__, this->process->pid, this->trdid,
    33493387parent_cxy, new_dentry_ptr, child_cxy, new_inode_ptr );
     
    33573395#if(DEBUG_VFS_ADD_CHILD & 1)
    33583396if( DEBUG_VFS_ADD_CHILD < cycle )
    3359 printk("\n[%s] thread[%x,%x] link dentry(%x,%x) to parent inode(%x,%x)\n",
     3397printk("\n[%s] thread[%x,%x] linked dentry(%x,%x) to parent inode(%x,%x)\n",
    33603398__FUNCTION__, this->process->pid, this->trdid,
    33613399parent_cxy, new_dentry_ptr, parent_cxy, parent_inode_ptr );
     
    38143852    return error;
    38153853
    3816 } // end vfs_fs_alloc_cluster()
     3854} // end vfs_fs_cluster_alloc()
    38173855
    38183856////////////////////////////////////////////////
  • trunk/kernel/fs/vfs.h

    r635 r656  
    602602 *    and synchronously update the IOC device).
    603603 * 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.
    604605 * 3. It updates the parent directory mapper to introduce the new child,
    605606 *    and synchronously update the IOC device.
     
    660661 * account the offset in <file_xp>. The transfer direction is defined by <to_buffer>.
    661662 * It is called by the sys_read() and sys_write() functions.
     663 * - for a read, it checks the actual file size (registered in the inode descriptor),
     664 *   against the (offset + count), and moves only the significant bytes.
     665 * - for a write, it updates the the file size in inode descriptor if required.
     666 * In case of write to the mapper, the "inode.size" field is updated as required.
    662667 ******************************************************************************************
    663668 * @ to_buffer : mapper -> buffer if true / buffer -> mapper if false.
    664669 * @ file_xp   : extended pointer on the remote file descriptor.
    665670 * @ buffer    : user space pointer on buffer (can be physically distributed).
    666  * @ size      : requested number of bytes from offset.
     671 * @ count     : requested number of bytes from offset.
    667672 * @ returns number of bytes actually moved if success / -1 if error.
    668673 *****************************************************************************************/
    669 int vfs_user_move( bool_t   to_buffer,
    670                    xptr_t   file_xp,
    671                    void   * buffer,
    672                    uint32_t size );
     674uint32_t vfs_user_move( bool_t   to_buffer,
     675                        xptr_t   file_xp,
     676                        void   * buffer,
     677                        uint32_t count );
    673678
    674679/******************************************************************************************
     
    745750 *    to the file, and removes these pages from the dirty list, using an RPC if required.
    746751 * 2) It updates the file size in all parent directory mapper(s), and update the modified
    747  *    pages on the block device, using RPCs if required.
     752 *    pages on the block device, using RPCs if required, only if the size is modified.
    748753 * 3) All entries in the fd_array copies are directly reset by the calling thread,
    749754 *    using remote accesses.
     
    895900 * argument to/from the IOC device from/to the mapper, as defined by the <cmd_type>.
    896901 * Depending on the file system type, it calls the proper, FS specific function.
    897  * It is used in case of MISS on the mapper, or when a dirty page in the mapper must
    898  * be updated in the File System.
    899  * The mapper pointer is obtained from the page descriptor.
     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.
    900905 * It can be executed by any thread running in any cluster.
    901906 * This function does NOT take any lock.
Note: See TracChangeset for help on using the changeset viewer.