Changeset 783 for soft/giet_vm


Ignore:
Timestamp:
Feb 7, 2016, 8:25:16 PM (9 years ago)
Author:
alain
Message:

Fix various bugs.

Location:
soft/giet_vm/giet_fat32
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • soft/giet_vm/giet_fat32/fat32.c

    r773 r783  
    116116                                               char*             string );
    117117
     118static unsigned int _set_fs_info();
     119
    118120static unsigned int _update_fs_info();
    119121
     
    154156                                      fat_inode_t* parent );
    155157
    156 static unsigned int _clusters_release( fat_inode_t* inode );
    157 
    158 static unsigned int _cluster_allocate( fat_inode_t*   inode,
    159                                        unsigned int*  cluster );
     158static unsigned int _one_cluster_allocate( fat_inode_t*   inode,
     159                                           unsigned int*  cluster );
     160
     161static unsigned int _all_clusters_release( fat_inode_t* inode );
    160162
    161163static void _release_cache_memory( fat_cache_node_t*  root,
     
    176178                                  unsigned int    cluster );
    177179
    178 static unsigned int _allocate_one_cluster( unsigned int*  cluster );
     180static unsigned int _get_free_cluster( unsigned int*  cluster );
    179181
    180182static unsigned int _remove_node_from_fs( fat_inode_t* inode );
     
    224226            _fat.data_sectors,
    225227            _fat.free_clusters_number,
    226             _fat.first_free_cluster,
     228            _fat.free_cluster_hint,
    227229            _fat.fat_cache_levels );
    228230
     
    563565
    564566
    565 /////////////////////////////////////
    566 static unsigned int _update_fs_info()
    567 {
    568     // update buffer if miss
    569     if ( _fat.fs_info_lba != _fat.block_buffer_lba )
    570     {
    571         if ( _fat_ioc_access( 1,                 // descheduling
    572                               1,                 // read
    573                               _fat.fs_info_lba,
    574                               (unsigned int)_fat.block_buffer,
    575                               1 ) )              // one block
    576         {
    577             _printf("\n[FAT_ERROR] _update_fs_info(): cannot read block\n");
    578             return 1;
    579         }
    580         _fat.block_buffer_lba = _fat.fs_info_lba;
    581     }
    582 
    583     // update FAT buffer
    584     unsigned int* ptr;
    585     ptr  = (unsigned int*)(_fat.block_buffer + get_offset(FS_FREE_CLUSTERS) );
    586     *ptr = _fat.free_clusters_number;
    587 
    588     ptr  = (unsigned int*)(_fat.block_buffer + get_offset(FS_FREE_CLUSTER_HINT) );
    589     *ptr = _fat.first_free_cluster;
    590    
    591     // write bloc to FAT
    592     if ( _fat_ioc_access( 1,                // descheduling
    593                           0,                // write
    594                           _fat.fs_info_lba,
    595                           (unsigned int)_fat.block_buffer,
    596                           1 ) )             // one block
    597     {
    598         _printf("\n[FAT_ERROR] _update_fs_info(): cannot write block\n");
    599         return 1;
    600     }
    601 
    602 #if GIET_DEBUG_FAT
    603 if ( _get_proctime() > GIET_DEBUG_FAT )
    604 _printf("\n[DEBUG FAT] _update_fs_info(): nb_free = %x / first_free = %x\n",
    605         _fat.free_clusters_number , _fat.first_free_cluster );
    606 #endif
    607 
    608     return 0;
    609 }  // end _update_fs_info()
    610 
    611567
    612568/////////////////////////////////////////////////////////////////
     
    739695
    740696///////////////////////////////////////////////////////////////////
    741 static unsigned int _allocate_one_cluster( unsigned int*  cluster ) 
    742 {
    743     unsigned int nb_free = _fat.free_clusters_number;
    744     unsigned int free    = _fat.first_free_cluster;
    745 
     697static unsigned int _get_free_cluster( unsigned int*  cluster ) 
     698{
    746699    // scan FAT to get next free cluster index
    747     unsigned int current = free;
    748     unsigned int found   = 0;
     700    unsigned int current = _fat.free_cluster_hint;
    749701    unsigned int max     = (_fat.data_sectors >> 3);
    750702    unsigned int value;
    751     do
    752     {
     703    while ( current < max )
     704    {
     705        // get FAT entry indexed by current
     706        if ( _get_fat_entry( current , &value ) ) return 1;
     707
     708        // return if free
     709        if ( value == FREE_CLUSTER )
     710        {
     711            *cluster = current;
     712            return 0;
     713        }
     714
    753715        // increment current
    754716        current++;
    755 
    756         // get FAT entry indexed by current
    757         if ( _get_fat_entry( current , &value ) ) return 1;
    758 
    759         // test if free
    760         if ( value == FREE_CLUSTER ) found = 1;
    761     }
    762     while ( (current < max) && (found == 0) );
     717    }
    763718       
    764     // check found 
    765     if ( found == 0 )
    766     {
    767         _printf("\n[FAT_ERROR] _allocate_one_cluster(): unconsistent FAT state");
    768         return 1;
    769     }
    770 
    771     // update allocated FAT slot
    772     if ( _set_fat_entry( free , END_OF_CHAIN_CLUSTER_MAX ) ) return 1;
    773 
    774     // update FAT descriptor global variables
    775     _fat.free_clusters_number = nb_free - 1;
    776     _fat.first_free_cluster   = current;
    777 
    778 #if GIET_DEBUG_FAT
    779 if ( _get_proctime() > GIET_DEBUG_FAT )
    780 _printf("\n[DEBUG FAT] _allocate_one_cluster(): allocated cluster = %x / first_free = %x\n",
    781         free , current );
    782 #endif
    783 
    784     // returns free cluster index
    785     *cluster = free;
    786     return 0;
    787 
    788 }  // end _allocate_one_cluster()
     719    // return error if not found 
     720    return 1;
     721
     722}  // end _get_free_cluster()
    789723
    790724
     
    896830
    897831
    898 ////////////////////////////////////////////////////////////
    899 static unsigned int _cluster_allocate( fat_inode_t*   inode,
    900                                        unsigned int*  cluster )
     832////////////////////////////////////////////////////////////////
     833static unsigned int _one_cluster_allocate( fat_inode_t*   inode,
     834                                           unsigned int*  cluster )
    901835{
    902836    // Check free cluster available
    903837    if ( _fat.free_clusters_number == 0 )
    904838    {
    905         _printf("\n[FAT ERROR] in _cluster_allocate(): no more free clusters\n");
     839        _printf("\n[FAT ERROR] in _one_cluster_allocate(): no more free clusters\n");
    906840        return 1;
    907841    }
    908842
    909     // compute number of already allocated clusters
    910     // and last allocated cluster index
     843    // scan the Fat-Cache to get last allocated cluster index
    911844    unsigned int nb_current_clusters = 0;
    912845    unsigned int current = inode->cluster;
     
    914847    unsigned int next    = 0;
    915848    unsigned int new     = 0;
    916 
    917849    while ( current < END_OF_CHAIN_CLUSTER_MIN )
    918850    {
    919851        // get next cluster
    920         if ( _get_fat_entry( current , &next ) )  return 1;
     852        if ( _get_fat_entry( current , &next ) )
     853        {
     854            _printf("\n[FAT ERROR] in _one_cluster_allocate() scanning FAT\n");
     855            return 1;
     856        }
    921857       
    922858        // increment number of allocated clusters
     
    929865
    930866    // allocate one free cluster from FAT
    931     if ( _allocate_one_cluster( &new ) ) return 1;
     867    if ( _get_free_cluster( &new ) )
     868    {
     869        _printf("\n[FAT ERROR] in _one_cluster_allocate() : no more free clusters\n");
     870        return 1;
     871    }
    932872
    933873    // allocate one 4K buffer to File-Cache
     
    936876                          new );
    937877
     878    // update allocated FAT slot
     879    if ( _set_fat_entry( new , END_OF_CHAIN_CLUSTER_MAX ) )
     880    {
     881        _printf("\n[FAT ERROR] in _one_cluster_allocate() accessing FAT\n");
     882        return 1;
     883    }
     884
     885    // update FAT descriptor global variables
     886    _fat.free_clusters_number--;
     887    _fat.free_cluster_hint = new;
     888
    938889    if ( nb_current_clusters == 0 )  // first cluster : inode and directory entry
    939890    {
     
    946897    else                             // update previous last cluster in FAT
    947898    {
    948         if ( _set_fat_entry( last , new ) ) return 1;
     899        if ( _set_fat_entry( last , new ) )
     900        {
     901            _printf("\n[FAT ERROR] in _one_cluster_allocate() accessing FAT\n");
     902            return 1;
     903        }
    949904    }
    950905
     
    952907    if ( _update_device_from_cache( _fat.fat_cache_levels,
    953908                                    _fat.fat_cache_root,
    954                                     "FAT" ) )              return 1;
     909                                    "FAT" ) )
     910    {
     911        _printf("\n[FAT ERROR] in _one_cluster_allocate() updating FAT on device\n");
     912        return 1;
     913    }
    955914
    956915    // update FS-INFO sector on device
    957     if ( _update_fs_info() )  return 1;
    958 
    959 #if GIET_DEBUG_FAT
    960 if ( _get_proctime() > GIET_DEBUG_FAT )
    961 _printf("\n[DEBUG FAT] _cluster_allocate(): for <%s>\n"
     916    if ( _update_fs_info() )
     917    {
     918        _printf("\n[FAT ERROR] in _one_cluster_allocate() updating FS-INFO sector on device\n");
     919        return 1;
     920    }
     921
     922#if GIET_DEBUG_FAT
     923if ( _get_proctime() > GIET_DEBUG_FAT )
     924_printf("\n[DEBUG FAT] _one_cluster_allocate(): for <%s>\n"
    962925        " nb_clusters = %d / last_cluster = %x / new_cluster = %x\n",
    963926        inode->name , nb_current_clusters , last , new );
     
    966929    // returns allocated cluster index
    967930    *cluster = new;
    968 
    969931    return 0;
    970 }  // end _cluster_allocate()
    971 
    972 
    973 
    974 ///////////////////////////////////////////////////////////
    975 static unsigned int _clusters_release( fat_inode_t* inode )
    976 {
    977     // scan the FAT
    978     unsigned int current = inode->cluster;
    979     unsigned int next;
    980     do
    981     {
    982         // get next_cluster index
    983         if ( _get_fat_entry( current , &next ) )  return 1;
    984 
    985         // release current_cluster
    986         if ( _set_fat_entry( current , FREE_CLUSTER ) )   return 1;
    987 
    988         // update first_free_cluster and free_clusters_number in FAT descriptor
    989         _fat.free_clusters_number = _fat.free_clusters_number + 1;
    990         if ( _fat.first_free_cluster > current ) _fat.first_free_cluster = current;
    991 
    992         // update loop variable
    993         current = next;
    994     }
    995     while ( next < END_OF_CHAIN_CLUSTER_MIN );
    996 
    997     // update the FAT on block device
     932
     933}  // end _one_cluster_allocate()
     934
     935////////////////////////////////////////////////////////////
     936static unsigned int _cluster_release( unsigned int cluster )
     937{
     938    if ( cluster >= END_OF_CHAIN_CLUSTER_MIN )  // terminal case : nothing to do
     939    {
     940        return 0;       
     941    }
     942    else                 // non terminal case : recursive call, then release cluster
     943    {
     944        // get next cluster
     945        unsigned int next;
     946        if ( _get_fat_entry( cluster , &next ) )
     947        {
     948            _printf("\n[FAT ERROR] in _cluster_release() accessing Fat-Cache"
     949                    " for cluster %x\n", cluster );
     950            return 1;
     951        }
     952
     953        // call _cluster_release() on next
     954        if ( _cluster_release( next ) ) return 1;
     955       
     956        // release current cluster
     957        if ( _set_fat_entry( cluster , FREE_CLUSTER ) )
     958        {
     959            _printf("\n[FAT ERROR] in _cluster_release() updating Fat-Cache"
     960                    " for cluster %x\n", cluster );
     961            return 1;
     962        }
     963
     964        // update free_cluster _hint and free_clusters_number in FAT descriptor
     965        _fat.free_clusters_number++;
     966        if ( cluster < _fat.free_cluster_hint ) _fat.free_cluster_hint = cluster;
     967
     968        return 0;
     969    }
     970}  // end _cluster_release()
     971
     972///////////////////////////////////////////////////////////////
     973static unsigned int _all_clusters_release( fat_inode_t* inode )
     974{
     975    // release recursively all clusters in FAT chaining,
     976    // starting from last cluster in chain, ending by first.
     977    if ( _cluster_release( inode->cluster ) )
     978    {
     979        _printf("\n[FAT ERROR] in _all_clusters_release() releasing clusters\n");
     980        return 1;
     981    }
     982
     983    // update FAT on device
    998984    if ( _update_device_from_cache( _fat.fat_cache_levels,
    999985                                    _fat.fat_cache_root,
    1000                                     "FAT" ) )                return 1;
     986                                    "FAT" ) )
     987    {
     988        _printf("\n[FAT ERROR] in _all_clusters_release() updating FAT on device\n");
     989        return 1;
     990    }
    1001991
    1002992    // update FS-INFO sector on device
    1003     if ( _update_fs_info() )  return 1;
    1004 
    1005 #if GIET_DEBUG_FAT
    1006 if ( _get_proctime() > GIET_DEBUG_FAT )
    1007 _printf("\n[DEBUG FAT] _clusters_release(): for file <%s>\n", inode->name );
     993    if ( _update_fs_info() )
     994    {
     995        _printf("\n[FAT ERROR] in _all_clusters_release() updating FS_INFO sector on device\n");
     996        return 1;
     997    }
     998
     999#if GIET_DEBUG_FAT
     1000if ( _get_proctime() > GIET_DEBUG_FAT )
     1001_printf("\n[DEBUG FAT] _all_clusters_release() done for file <%s>\n", inode->name );
    10081002#endif
    10091003
    10101004    return 0;
    1011 }  // end _clusters_release()
     1005}  // end _all_clusters_release()
    10121006
    10131007
     
    19311925
    19321926    // release clusters allocated to file/dir in DATA region
    1933     if ( _clusters_release( inode ) ) return 1;
     1927    if ( _all_clusters_release( inode ) ) return 1;
    19341928
    19351929    // release File-Cache
     
    21662160unsigned int _set_fs_info()
    21672161{
    2168 
    2169 #if GIET_DEBUG_FAT
    2170 if ( _get_proctime() > GIET_DEBUG_FAT )
    2171 _printf("\n[DEBUG FAT] _set_fs_info(): enters at cycle %d\n", _get_proctime() );
    2172 #endif
    2173 
    21742162    // load FS_INFO sector into FAT buffer
    21752163    if ( _fat_ioc_access( 0,                                // no descheduling
     
    21822170        return 1;
    21832171    }
    2184 
    21852172    _fat.block_buffer_lba = _fat.fs_info_lba;
    21862173
    2187 #if GIET_DEBUG_FAT
    2188 if ( _get_proctime() > GIET_DEBUG_FAT )
    2189 _printf("\n[DEBUG FAT] _set_fs_info(): FS-INFO sector loaded\n");
    2190 #endif
    2191 
    21922174    // get general info from FAT descriptor
    2193     unsigned int  fat_blocks   = _fat.fat_sectors;
    21942175    unsigned int  data_blocks  = _fat.data_sectors;
    2195     unsigned int  lba          = _fat.fat_lba;
    2196     unsigned int* buf          = (unsigned int*)_fat.block_buffer;
    21972176
    21982177    // initialise <free_clusters_number> from FS-INFO sector
     
    22082187    _fat.free_clusters_number  = free_clusters;
    22092188
    2210     // scan FAT on device from FS-FREE_CLUSTER_HINT to initialise <first_free_cluster>
     2189    // initialise <free_cluster_hint> from FS_INFO sector
    22112190    unsigned int free_cluster_hint = _read_entry( FS_FREE_CLUSTER_HINT, _fat.block_buffer, 1);     
    22122191    if ( free_cluster_hint > (data_blocks>>3) )
     
    22182197    }
    22192198
    2220     unsigned int block_id    = free_cluster_hint>>7;
    2221     unsigned int first_entry = free_cluster_hint & 0x7F;
    2222     unsigned int  search     = 1;
    2223     unsigned int  first_free = 0;
    2224 
    2225     // loop on the FAT blocks from free_cluster_hint
    2226     // until free cluster found or end of FAT region
    2227     while ( search && (block_id < fat_blocks) )
    2228     {
    2229         // read one FAT block from device
    2230         if ( _fat_ioc_access( 0,                   // no_irq
    2231                               1,                   // to_mem,
    2232                               lba + block_id,      // lba
    2233                               (unsigned int)buf,   // FAT local buffer
    2234                               1 ) )                // one block
    2235         {
    2236             _printf("\n[FAT_ERROR] _set_fs_info() : cannot read FAT block %d\n", block_id);
     2199    _fat.free_cluster_hint  = free_cluster_hint;
     2200
     2201#if GIET_DEBUG_FAT
     2202if ( _get_proctime() > GIET_DEBUG_FAT )
     2203_printf("\n[DEBUG FAT] _set_fs_info() : free_clusters = %x / free_cluster_hint = %x\n",
     2204        free_clusters , free_cluster_hint );
     2205#endif
     2206
     2207    return 0;
     2208   
     2209}  // end _set_fs_info()
     2210
     2211
     2212
     2213
     2214/////////////////////////////////////
     2215static unsigned int _update_fs_info()
     2216{
     2217    // load buffer if miss
     2218    if ( _fat.fs_info_lba != _fat.block_buffer_lba )
     2219    {
     2220        if ( _fat_ioc_access( 1,                 // descheduling
     2221                              1,                 // read
     2222                              _fat.fs_info_lba,
     2223                              (unsigned int)_fat.block_buffer,
     2224                              1 ) )              // one block
     2225        {
     2226            _printf("\n[FAT_ERROR] _update_fs_info(): cannot read block\n");
    22372227            return 1;
    22382228        }
    2239 
    2240         _fat.block_buffer_lba = lba + block_id;
    2241 
    2242         // scan the entries in block from first_entry to 128
    2243         unsigned int entry;
    2244         for ( entry = first_entry ; entry < 128 ; entry++ )
    2245         {
    2246             if ( buf[entry] == FREE_CLUSTER )
    2247             {
    2248                 first_free = (block_id<<7) + entry;
    2249                 search = 0;
    2250                 break;
    2251             }
    2252         }  // end loop on entries
    2253 
    2254         block_id++;
    2255         first_entry = 0;
    2256     }  // end loop on blocks
    2257 
    2258     if ( search )               // no free cluster 
    2259     {
    2260         _printf("\n[FAT_ERROR] _set_fs_info() : No free cluster found in FAT\n");
     2229        _fat.block_buffer_lba = _fat.fs_info_lba;
     2230    }
     2231
     2232    // update buffer
     2233    unsigned int* ptr;
     2234
     2235    ptr  = (unsigned int*)(_fat.block_buffer + get_offset(FS_FREE_CLUSTERS) );
     2236    *ptr = _fat.free_clusters_number;
     2237
     2238    ptr  = (unsigned int*)(_fat.block_buffer + get_offset(FS_FREE_CLUSTER_HINT) );
     2239    *ptr = _fat.free_cluster_hint;
     2240   
     2241    // write bloc to FAT
     2242    if ( _fat_ioc_access( 1,                // descheduling
     2243                          0,                // write
     2244                          _fat.fs_info_lba,
     2245                          (unsigned int)_fat.block_buffer,
     2246                          1 ) )             // one block
     2247    {
     2248        _printf("\n[FAT_ERROR] _update_fs_info(): cannot write block\n");
    22612249        return 1;
    22622250    }
    2263     else          // update fat descriptor
    2264     {
    2265         _fat.first_free_cluster = first_free;
    2266 
    2267 #if GIET_DEBUG_FAT
    2268 if ( _get_proctime() > GIET_DEBUG_FAT )
    2269 _printf("\n[DEBUG FAT] _set_fs_info() completes : free_clusters = %x / first_free = %x\n",
    2270         free_clusters , first_free );
    2271 #endif
    2272 
    2273         return 0;
    2274     }
    2275 }  // end _set_fs_info()
     2251
     2252#if GIET_DEBUG_FAT
     2253if ( _get_proctime() > GIET_DEBUG_FAT )
     2254_printf("\n[DEBUG FAT] _update_fs_info() : free_clusters = %x / free_cluster_hint = %x\n",
     2255        _fat.free_clusters_number , _fat.free_cluster_hint );
     2256#endif
     2257
     2258    return 0;
     2259}  // end _update_fs_info()
     2260
    22762261
    22772262
     
    26582643
    26592644        // release clusters allocated to file/dir in DATA region
    2660         if ( _clusters_release( child ) )
     2645        if ( _all_clusters_release( child ) )
    26612646        {
    26622647            _spin_lock_release( &_fat.fat_lock );
     
    31173102            for ( cid = 0 ; cid < (new_clusters - old_clusters) ; cid++ )
    31183103            {
    3119                 if ( _cluster_allocate( inode , &index ) )
     3104                if ( _one_cluster_allocate( inode , &index ) )
    31203105                {
    31213106                    _spin_lock_release( &_fat.fat_lock );
     
    38093794        _get_last_name( pathname , name );
    38103795
    3811         // allocate one cluster from FAT for the new directory
    3812         unsigned int cluster;
    3813         if ( _allocate_one_cluster( &cluster ) )
    3814         {
    3815             _spin_lock_release( &_fat.fat_lock );
    3816             _atomic_and( &psched->context[ltid].slot[CTX_LOCKS_ID] , ~LOCKS_MASK_FAT );
    3817 
    3818             _printf("\n[FAT ERROR] _fat_mkdir(): no free cluster"
    3819                     " for directory <%s>\n" , pathname );
    3820             return GIET_FAT32_NO_FREE_SPACE;
    3821         }
    3822 
    38233796        // allocate a new inode and an empty Cache-File
    38243797        child = _allocate_one_inode( name,
    38253798                                     1,           // it's a directory
    3826                                      cluster, 
     3799                                     0xFFFFFFFF,  // cluster index not defined yet
    38273800                                     0,           // size = 0 for a directory
    38283801                                     0,           // count
     
    38333806        _add_inode_in_tree( child , parent );
    38343807 
     3808        // allocate cluster from FAT
     3809        unsigned int cluster;
     3810        if ( _one_cluster_allocate( inode , &cluster ) )
     3811        {
     3812            _spin_lock_release( &_fat.fat_lock );
     3813            _atomic_and( &psched->context[ltid].slot[CTX_LOCKS_ID] , ~LOCKS_MASK_FAT );
     3814
     3815            _printf("\n[FAT ERROR] _fat_mkdir(): no free cluster"
     3816                    " for directory <%s>\n" , pathname );
     3817            return GIET_FAT32_NO_FREE_SPACE;
     3818        }
     3819
     3820        // update cluster index in inode
     3821        child->cluster = cluster;
     3822
    38353823        // allocate and initialise one 4 Kbytes buffer and associated descriptor
    38363824        _allocate_one_buffer( child,
     
    42834271            unsigned int        cid;
    42844272            unsigned int        lba;
    4285             unsigned int        cluster_allocated;
     4273            unsigned int        one_cluster_allocated;
    42864274
    42874275            // File-Cache miss handling:
     
    43024290        (unsigned int)inode->cache->children[cluster_id] );
    43034291#endif
    4304                 // compute cluster_allocated condition, depending on file / dir type
    4305                 if ( is_dir )  cluster_allocated = ( cluster_id < is_dir );
    4306                 else           cluster_allocated = ( (cluster_id<<12) < size );
    4307 
    4308                 if ( cluster_allocated )  // cluster already allocated => allocate buffer
     4292                // compute one_cluster_allocated condition, depending on file / dir type
     4293                if ( is_dir )  one_cluster_allocated = ( cluster_id < is_dir );
     4294                else           one_cluster_allocated = ( (cluster_id<<12) < size );
     4295
     4296                if ( one_cluster_allocated )  // cluster already allocated => allocate buffer
    43094297                {
    43104298                    // scan the FAT to find the cluster index for cluster_id
     
    43634351                        {
    43644352                            // allocate one cluster on device
    4365                             if ( _cluster_allocate( inode , &current ) )
     4353                            if ( _one_cluster_allocate( inode , &current ) )
    43664354                            {
    43674355                                _printf("\n[FAT ERROR] in _get_file_cache_buffer() : "
  • soft/giet_vm/giet_fat32/fat32.h

    r773 r783  
    210210    unsigned int        data_sectors;            // number of sectors inf DATA region
    211211    unsigned int        fs_info_lba;             // lba of fs_info
    212     unsigned int        first_free_cluster;      // free cluster with smallest index
     212    unsigned int        free_cluster_hint;       // start point to search free cluster
    213213    unsigned int        free_clusters_number;    // total number of free clusters
    214214}   fat_desc_t;
Note: See TracChangeset for help on using the changeset viewer.