Ignore:
Timestamp:
Jan 19, 2016, 11:34:45 AM (9 years ago)
Author:
alain
Message:

Replace the _get_buffer_from_cache() function by

  • _get_file_cache_buffer() : external
  • _get_fat_cache_buffer() : internal
File:
1 edited

Legend:

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

    r750 r761  
    5353// Fat-Descriptor
    5454__attribute__((section(".kdata")))
    55 fat_desc_t _fat __attribute__((aligned(64)));
     55fat_desc_t     _fat __attribute__((aligned(64)));
    5656
    5757// buffer used by boot code as a simple cache when scanning FAT
     
    180180
    181181//////////////////////////////////////////////////////////////////////////////////
    182 // The following function introduces the inode identified by the "child" argument,
    183 // as a new child of the "parent" inode in the Inode-Tree.
     182// The following function introduces the inode identified by the <child> argument,
     183// as a new child of the <parent> inode in the Inode-Tree.
    184184// All checking are supposed to be done by the caller.
    185185// Nor the File-Cache, neither the block device are modified.
     
    190190
    191191//////////////////////////////////////////////////////////////////////////////////
    192 // The following function removes one inode identified by the "inode" argument
     192// The following function removes one inode identified by the <inode> argument
    193193// from the Inode-Tree. All checking are supposed to be done by the caller.
    194194// Nor the File-Cache, neither the block device are modified.
     
    200200// This recursive function scan one File-Cache (or Fat-Cache) from root to leaves,
    201201// to writes all dirty clusters to block device, and reset the dirty bits.
    202 // The cache is identified by the "root" an "levels" arguments.
    203 // The "string" argument is only used for debug : inode name or Fat.
     202// The cache is identified by the <root> an <levels> arguments.
     203// The <string> argument is only used for debug : inode name or Fat.
    204204// It returns 0 on success.
    205205// It returns 1 on error.
     
    223223// The following function read a data field (from one to four bytes)
    224224// from an unsigned char[] buffer, taking endianness into account.
    225 // The analysed field is defined by the "offset" and "size" arguments.
     225// The analysed field is defined by the <offset> and <size> arguments.
    226226//////////////////////////////////////////////////////////////////////////////
    227227
     
    249249
    250250//////////////////////////////////////////////////////////////////////////////////
    251 // The following function search in the directory identified by the "parent"
    252 // inode pointer a child (file or directory) identified by its "name".
    253 // It returns in the "inode" argument the searched child inode pointer.
     251// The following function search in the directory identified by the <parent>
     252// inode pointer a child (file or directory) identified by its <name>.
     253// It returns in the <inode> argument the searched child inode pointer.
    254254// If the searched name is not found in the Inode-Tree, the function accesses
    255 // the "file_cache" associated to the parent directory.
     255// the File-cache associated to the parent directory.
    256256// If the child exists on block device, the Inode-Tree is updated, and
    257257// a success code is returned.
     
    356356//////////////////////////////////////////////////////////////////////////////////
    357357// The following function releases all clusters allocated to a file or directory,
    358 // from the cluster index defined by the "cluster" argument, until the end
     358// from the cluster index defined by the <cluster> argument, until the end
    359359// of the FAT linked list.
    360360// It calls _get_fat_entry() and _set_fat_entry() functions to scan the FAT,
     
    368368
    369369//////////////////////////////////////////////////////////////////////////////////
    370 // This function allocate "nb_clusters_more" new clusters to a file (or directory)
    371 // identified by the "inode" pointer. It allocates also the associated buffers
    372 // and buffer descriptors in the Cache-File.
     370// This function allocate one cluster in FAT to a file (or directory) identified
     371// by the <inode> pointer. The allocated cluster index is returned in the
     372// <cluster> argument.
     373// It allocates also the associated buffers and buffer descriptors in Cache-File.
    373374// It calls _get_fat_entry() and _set_fat_entry() functions to update the
    374375// clusters chaining in the Cache-Fat. The FAT region on block device is updated.
     
    377378//////////////////////////////////////////////////////////////////////////////////
    378379
    379 static unsigned int _clusters_allocate( fat_inode_t* inode,
    380                                         unsigned int nb_clusters_current,
    381                                         unsigned int nb_clusters_more );
     380static unsigned int _cluster_allocate( fat_inode_t*   inode,
     381                                       unsigned int*  cluster );
    382382
    383383//////////////////////////////////////////////////////////////////////////////////
     
    393393
    394394//////////////////////////////////////////////////////////////////////////////////
    395 // The following function allocates and initializes a new Fat-Cache node.
     395// The following function allocates and initializes a new cache node.
    396396// Its first child can be specified (used when adding a cache level).
    397 // The Fat-Cache is initialized as empty: all children set to NULL.
     397// The 63 other children are set to NULL.
    398398// It returns a pointer to a new Fat-Cache node.
    399399//////////////////////////////////////////////////////////////////////////////////
     
    404404// The following function allocates and initializes a new inode,
    405405// using the values defined by the arguments.
    406 // If the "cache_allocate" argument is true ans empty cache is allocated.
     406// If the "cache_allocate" argument is true, an empty cache is allocated.
    407407// It returns a pointer on the new inode.
    408408//////////////////////////////////////////////////////////////////////////////////
     
    417417
    418418//////////////////////////////////////////////////////////////////////////////////
    419 // The following function allocates one 4 Kbytes buffer and associated cluster
    420 // descriptor for the file (or directory) identified by the "inode" argument,
    421 // and updates the Cache_File slot identified by the "cluster_id" argument.
     419// The following function allocates a 4 Kbytes buffer and the associated cluster
     420// descriptor for the file (or directory) identified by the <inode> argument,
     421// and updates the Cache_File slot identified by the <cluster_id> argument.
    422422// The File-Cache slot must be empty.
    423 // It updates the cluster descriptor, using the "cluster" argument, that is
     423// It updates the buffer descriptor, using the <cluster> argument, that is
    424424// the cluster index in FAT.  The cluster descriptor dirty field is set.
    425425// It traverse the 64-tree Cache-file from top to bottom to find the last level.
     
    431431
    432432//////////////////////////////////////////////////////////////////////////////////
    433 // The following function allocates one free cluster from the FAT "heap" of free
    434 // clusters, and returns the cluster index in the "cluster" argument.
     433// The following function allocates one free cluster from the FAT
     434// and returns the cluster index in the <cluster> argument.
    435435// It updates the FAT slot, and the two FAT global variables: first_free_cluster,
    436436// and free_clusters_number.
     
    443443/////////////////////////////////////////////////////////////////////////////
    444444// This function remove from the file system a file or a directory
    445 // identified by the "inode" argument.
     445// identified by the <inode> argument.
    446446// The remove condition must be checked by the caller.
    447447// The relevant lock(s) must have been taken by te caller.
     
    483483
    484484//////////////////////////////////////////////////////////////////////////////////
    485 // The following functions return the length or the size of a FAT field,
     485// The following functions return the the size (bytes) of a FAT field,
    486486// identified by an (offset,length) mnemonic defined in the fat32.h file.
    487487//////////////////////////////////////////////////////////////////////////////////
     
    491491static inline int get_offset( int offset , int length ) { return offset; }
    492492
     493//////////////////////////////////////////////////////////////////////////////////
     494// The following function returns in the <desc> argument a pointer on a buffer
     495// descriptor contained in the Fat_Cache.
     496// The <cluster_id> argument is the buffer index in the FAT_Cache.
     497// In case of miss, a 4 Kbytesbuffer and a buffer descriptor are allocated
     498// from the local heap, and the missing cluster is loaded in the Fat_Cache.
     499// It returns 0 on success.
     500// It returns 1 on error.
     501//////////////////////////////////////////////////////////////////////////////////
     502
     503static unsigned int _get_fat_cache_buffer( unsigned int        cluster_id,
     504                                           fat_cache_desc_t**  desc );
    493505
    494506
     
    855867
    856868
    857 ////////////////////////////////////////////////////////////
     869//////////////////////////////////////////////////////////////////////////////////
    858870static fat_cache_node_t* _allocate_one_cache_node( fat_cache_node_t* first_child )
    859871{
     
    10061018    unsigned int       entry_id   = cluster & 0x3FF;
    10071019
    1008     // get pointer on the relevant cluster descriptor in FAT cache
     1020    // get pointer on the relevant buffer descriptor in FAT cache
    10091021    fat_cache_desc_t*  pdesc;
    10101022    unsigned int*      buffer;
    1011     if ( _fat_buffer_from_cache( NULL,               // Fat-Cache
    1012                                  cluster_id,
    1013                                  &pdesc ) ) return 1;
     1023    if ( _get_fat_cache_buffer( cluster_id,
     1024                                &pdesc ) ) return 1;
    10141025
    10151026    // get value from FAT slot
     
    10311042    unsigned int entry_id   = cluster & 0x3FF;
    10321043
    1033     // get pointer on the relevant cluster descriptor in FAT cache
     1044    // get pointer on the relevant buffer descriptor in FAT cache
    10341045    fat_cache_desc_t*  pdesc;
    10351046    unsigned int*      buffer;
    1036     if ( _fat_buffer_from_cache( NULL,               // Fat-Cache
    1037                                  cluster_id,
    1038                                  &pdesc ) )  return 1;           
     1047    if ( _get_fat_cache_buffer( cluster_id,
     1048                                &pdesc ) )  return 1;           
    10391049
    10401050    // set value into FAT slot
     
    10531063                                  unsigned int  cluster )
    10541064{
     1065
     1066#if (GIET_DEBUG_FAT & 1)
     1067if ( _get_proctime() > GIET_DEBUG_FAT )
     1068_printf("\n[DEBUG FAT] _allocate_one_buffer(): in cache <%s> for cluster_id %d\n",
     1069        inode->name, cluster_id );
     1070#endif
     1071
    10551072    // add cache levels if needed
    10561073    while ( _get_levels_from_size( (cluster_id + 1) * 4096 ) > inode->levels )
    10571074    {
     1075
    10581076#if (GIET_DEBUG_FAT & 1)
    10591077if ( _get_proctime() > GIET_DEBUG_FAT )
     
    10771095        {
    10781096            fat_cache_desc_t* pdesc = (fat_cache_desc_t*)node->children[index];
     1097
    10791098            if ( pdesc != NULL )      // slot not empty!!!
    10801099            {
    1081                 _printf("\n[FAT ERROR] allocate_one buffer(): slot not empty "
    1082                         "in File-Cache <%s> / cluster_id = %d\n", inode->name , cluster_id );
     1100                _printf("\n[FAT ERROR] in _allocate_one buffer() : slot not empty "
     1101                        "in File-Cache <%s>\n cluster_id = %d / cache = %x / pdesc[0] = %x\n",
     1102                        inode->name , cluster_id ,
     1103                        (unsigned int)node , (unsigned int)pdesc );
    10831104                _exit();
    10841105            }
     
    11551176#if (GIET_DEBUG_FAT & 1)
    11561177if ( _get_proctime() > GIET_DEBUG_FAT )
    1157 _printf("\n[DEBUG FAT] _allocate_one_cluster(): cluster = %x / first_free = %x\n",
     1178_printf("\n[DEBUG FAT] _allocate_one_cluster(): allocated cluster = %x / first_free = %x\n",
    11581179        free , current );
    11591180#endif
     
    11761197    unsigned int ret = 0;
    11771198
    1178     if ( levels == 1 )  // last level => children are cluster descriptors
     1199    if ( levels == 1 )  // last level => children are buffer descriptors
    11791200    {
    11801201        for( index = 0 ; index < 64 ; index++ )
     
    12731294
    12741295
    1275 /////////////////////////////////////////////////////////////
    1276 static unsigned int _clusters_allocate( fat_inode_t* inode,
    1277                                         unsigned int nb_current_clusters,
    1278                                         unsigned int nb_required_clusters )
    1279 {
    1280     // Check if FAT contains enough free clusters
    1281     if ( nb_required_clusters > _fat.free_clusters_number )
    1282     {
    1283         _printf("\n[FAT ERROR] _clusters_allocate(): required_clusters = %d"
    1284                 " / free_clusters = %d\n", nb_required_clusters , _fat.free_clusters_number );
     1296////////////////////////////////////////////////////////////
     1297static unsigned int _cluster_allocate( fat_inode_t*   inode,
     1298                                       unsigned int*  cluster )
     1299{
     1300    // Check free cluster available
     1301    if ( _fat.free_clusters_number == 0 )
     1302    {
     1303        _printf("\n[FAT ERROR] in _cluster_allocate(): no more free clusters\n");
    12851304        return 1;
    12861305    }
    12871306
    1288 #if (GIET_DEBUG_FAT & 1)
    1289 if ( _get_proctime() > GIET_DEBUG_FAT )
    1290 _printf("\n[DEBUG FAT] _clusters_allocate(): enters for <%s> / nb_current_clusters = %d "
    1291         "/ nb_required_clusters = %d\n",
    1292         inode->name , nb_current_clusters , nb_required_clusters );
    1293 #endif
    1294  
    1295     // compute last allocated cluster index when (nb_current_clusters > 0)
     1307    // compute number of already allocated clusters
     1308    // and last allocated cluster index
     1309    unsigned int nb_current_clusters = 0;
    12961310    unsigned int current = inode->cluster;
    1297     unsigned int next;
    1298     unsigned int last;
    1299     if ( nb_current_clusters )   // clusters allocated => search last
    1300     {   
    1301         while ( current < END_OF_CHAIN_CLUSTER_MIN )
    1302         {
    1303             // get next cluster
    1304             if ( _get_fat_entry( current , &next ) )  return 1;
    1305             last    = current;
    1306             current = next;
    1307         }
     1311    unsigned int last    = current;
     1312    unsigned int next    = 0;
     1313    unsigned int new     = 0;
     1314
     1315    while ( current < END_OF_CHAIN_CLUSTER_MIN )
     1316    {
     1317        // get next cluster
     1318        if ( _get_fat_entry( current , &next ) )  return 1;
     1319       
     1320        // increment number of allocated clusters
     1321        nb_current_clusters++;
     1322
     1323        // update loop variables
     1324        last    = current;
     1325        current = next;
    13081326    } 
    13091327
    1310     // Loop on the new clusters to be allocated
    1311     // if (nb_current_clusters == 0) the first new cluster index must
    1312     //                               be written in inode->cluster field
    1313     // if (nb_current_clusters >  0) the first new cluster index must
    1314     //                               be written in FAT[last]
    1315     unsigned int      cluster_id;
    1316     unsigned int      new;
    1317     for ( cluster_id = nb_current_clusters ;
    1318           cluster_id < (nb_current_clusters + nb_required_clusters) ;
    1319           cluster_id ++ )
    1320     {
    1321         // allocate one cluster on block device
    1322         if ( _allocate_one_cluster( &new ) ) return 1;
    1323 
    1324         // allocate one 4K buffer to File-Cache
    1325         _allocate_one_buffer( inode,
    1326                               cluster_id,
    1327                               new );
    1328 
    1329         if ( cluster_id == 0 )  // update inode
    1330         {
    1331             inode->cluster = new;
    1332         }
    1333         else                    // update FAT
    1334         {
    1335             if ( _set_fat_entry( last , new ) ) return 1;
    1336         }
    1337 
    1338 #if (GIET_DEBUG_FAT & 1)
    1339 if ( _get_proctime() > GIET_DEBUG_FAT )
    1340 _printf("\n[DEBUG FAT] _clusters_allocate(): done for cluster_id = %d / cluster = %x\n",
    1341         cluster_id , new );
    1342 #endif
    1343 
    1344         // update loop variables
    1345         last = new;
    1346 
    1347     } // end for loop
    1348 
    1349     // update FAT : last slot should contain END_OF_CHAIN_CLUSTER_MAX
    1350     if ( _set_fat_entry( last , END_OF_CHAIN_CLUSTER_MAX ) )  return 1;
     1328    // allocate one free cluster from FAT
     1329    if ( _allocate_one_cluster( &new ) ) return 1;
     1330
     1331    // allocate one 4K buffer to File-Cache
     1332    _allocate_one_buffer( inode,
     1333                          nb_current_clusters,
     1334                          new );
     1335
     1336    if ( nb_current_clusters == 0 )  // first cluster : inode and directory entry
     1337    {
     1338        // update inode
     1339        inode->cluster = new;
     1340
     1341        // update directory entry
     1342        _update_dir_entry( inode );
     1343    }
     1344    else                             // update previous last cluster in FAT
     1345    {
     1346        if ( _set_fat_entry( last , new ) ) return 1;
     1347    }
    13511348
    13521349    // update the FAT on block device
     
    13541351                                    _fat.fat_cache_root,
    13551352                                    "FAT" ) )              return 1;
     1353#if (GIET_DEBUG_FAT & 1)
     1354if ( _get_proctime() > GIET_DEBUG_FAT )
     1355_printf("\n[DEBUG FAT] _cluster_allocate(): for <%s> / current_clusters = %d"
     1356        " / last_cluster = %x / new_cluster = %x\n",
     1357        inode->name , nb_current_clusters , last , new );
     1358#endif
     1359
     1360    // returns allocated cluster index
     1361    *cluster = new;
     1362
    13561363    return 0;
    1357 }  // end _clusters_allocate()
     1364}  // end _cluster_allocate()
    13581365
    13591366
     
    15181525    {
    15191526        // get one 4 Kytes buffer from File_Cache 
    1520         if ( _fat_buffer_from_cache( inode,
     1527        if ( _get_file_cache_buffer( inode,
    15211528                                     cluster_id,
     1529                                     0,         
    15221530                                     &pdesc ) )   return 1;
    15231531        buffer = pdesc->buffer;
     
    16001608    {
    16011609        // get one 4 Kytes buffer from File_Cache 
    1602         if ( _fat_buffer_from_cache( parent,
     1610        if ( _get_file_cache_buffer( parent,
    16031611                                     cluster_id,
     1612                                     0,
    16041613                                     &pdesc ) )   return 1;
    16051614
     
    16581667        if ( offset >= 4096 )  // new buffer required
    16591668        {
    1660             if ( _fat_buffer_from_cache( parent,
     1669            if ( _get_file_cache_buffer( parent,
    16611670                                         cluster_id + 1,
     1671                                         0,
    16621672                                         &pdesc ) )      return 1;
    16631673            buffer       = pdesc->buffer;
     
    18321842    fat_cache_desc_t*  pdesc;
    18331843
    1834     if ( _fat_buffer_from_cache( inode->parent,
     1844    if ( _get_file_cache_buffer( inode->parent,
    18351845                                 cluster_id,
     1846                                 0,
    18361847                                 &pdesc ) ) return 1;
    18371848    buffer       = pdesc->buffer;
     
    18491860                break;
    18501861
    1851             if ( _fat_buffer_from_cache( inode->parent,
     1862            if ( _get_file_cache_buffer( inode->parent,
    18521863                                         cluster_id - 1,
     1864                                         0,
    18531865                                         &pdesc ) )   return 1;
    18541866            buffer       = pdesc->buffer;
     
    18851897    unsigned int       offset     = (inode->dentry & 0x7F)<<5;
    18861898
    1887     if ( _fat_buffer_from_cache( inode->parent,
     1899    if ( _get_file_cache_buffer( inode->parent,
    18881900                                 cluster_id,
     1901                                 0,
    18891902                                 &pdesc ) )    return 1;
    18901903    buffer       = pdesc->buffer;
     
    19381951    }
    19391952
    1940     // not found in Inode-Tree => access the parent directory
    1941     // file_cache.  Two embedded loops:
     1953    // not found in Inode-Tree => access the parent directory file_cache.
     1954    // Two embedded loops:
    19421955    // - scan the clusters allocated to this directory
    19431956    // - scan the directory entries in each 4 Kbytes buffer
     
    19701983        // get one 4 Kytes buffer from parent File_Cache 
    19711984        fat_cache_desc_t*  pdesc;
    1972         if ( _fat_buffer_from_cache( parent,
     1985        if ( _get_file_cache_buffer( parent,
    19731986                                     cluster_id,
     1987                                     0,
    19741988                                     &pdesc ) )    return 2;
    19751989        buffer = pdesc->buffer;
     
    19781992        while( (offset < 4096) && (found == 0) )
    19791993        {
    1980 
    1981 #if (GIET_DEBUG_FAT & 1)
    1982 if ( _get_proctime() > GIET_DEBUG_FAT )
    1983 _printf("\n[DEBUG FAT] _get_child_from_parent(): scan buffer %d for <%s>\n",
    1984         cluster_id , name );
    1985 #endif
    19861994            attr = _read_entry( DIR_ATTR , buffer + offset , 0 );   
    19871995            ord  = _read_entry( LDIR_ORD , buffer + offset , 0 );
     
    20272035                }
    20282036                   
    2029                 // test if extracted name == searched name
     2037                // get dir-entry arguments if extracted name == searched name
    20302038                if ( _strcmp( name , cname ) == 0 )
    20312039                {
     
    20362044                    size    = _read_entry( DIR_FILE_SIZE , buffer + offset , 1 );
    20372045                    found   = 1;
     2046
     2047                    // adjust size for a directory :
     2048                    // size must be non-zero and rounded to a multiple of 4 Kbytes
     2049                    if ( is_dir )
     2050                    {
     2051                        if      ( size == 0 )    size = 4096;
     2052                        else if ( size & 0xFFF ) size = ((size>>12) + 1)<<12; 
     2053                    }
    20382054                }
    20392055                offset = offset + 32;
     
    24492465
    24502466
     2467//////////////////////////////////////////////////////////////////////////
     2468static unsigned int _get_fat_cache_buffer( unsigned int        cluster_id,
     2469                                           fat_cache_desc_t**  desc )
     2470{
     2471    // get cache pointer and number of levels
     2472    fat_cache_node_t*   node   = _fat.fat_cache_root;   
     2473    unsigned int        level  = _fat.fat_cache_levels; 
     2474
     2475    if ( _get_levels_from_size( (cluster_id + 1) * 4096 ) > level )
     2476    {
     2477        _printf("\n[FAT ERROR] in _get_fat_cache_buffer() : "
     2478                "cluster_id %d too large", cluster_id );
     2479        return 1;
     2480    }
     2481
     2482    // search the 64-tree cache from top to bottom
     2483    while ( level )
     2484    {
     2485        // compute child index at each level
     2486        unsigned int index = (cluster_id >> (6*(level-1))) & 0x3F;
     2487
     2488        if ( level == 1 )        // last level => children are buffer descriptors
     2489        {
     2490            fat_cache_desc_t*   pdesc = (fat_cache_desc_t*)node->children[index];
     2491
     2492            if ( pdesc == NULL )      // miss
     2493            {
     2494
     2495#if (GIET_DEBUG_FAT & 1)
     2496if ( _get_proctime() > GIET_DEBUG_FAT )
     2497_printf("\n[DEBUG FAT] _get_fat_cache_buffer(): miss for cluster_id %d\n", cluster_id );
     2498#endif
     2499                // compute missing cluster lba
     2500                unsigned int lba = _fat.fat_lba + (cluster_id << 3);
     2501
     2502                // allocate a 4 Kbytes buffer and a buffer descriptor
     2503                void* buf      = _malloc( 4096 );
     2504                pdesc          = _malloc( sizeof(fat_cache_desc_t) );
     2505                pdesc->lba     = lba;
     2506                pdesc->buffer  = buf;
     2507                pdesc->dirty   = 0;
     2508                node->children[index] = pdesc;
     2509
     2510                // load cluster from device
     2511                if ( _fat_ioc_access( 1,         // descheduling
     2512                                      1,         // to memory
     2513                                      lba,
     2514                                      (unsigned int)buf,
     2515                                      8 ) )
     2516                {
     2517                    _free( buf );
     2518                    _free( pdesc );
     2519                    _printf("\n[FAT ERROR] in _get_fat_cache_buffer() : "
     2520                            ": cannot access block device for lba = %x\n", lba );
     2521                    return 1;
     2522                }
     2523
     2524            }
     2525
     2526#if (GIET_DEBUG_FAT & 1)
     2527if ( _get_proctime() > GIET_DEBUG_FAT )
     2528_printf("\n[DEBUG FAT] _get_fat_cache_buffer() : found buffer = %x\n",
     2529        (unsigned int)pdesc->buffer );
     2530#endif
     2531            // return pdesc pointer
     2532            *desc = pdesc;
     2533
     2534            // prepare next iteration
     2535            level--;
     2536        }
     2537        else                      // not last level => children are 64-tree nodes
     2538        {
     2539            fat_cache_node_t* child = (fat_cache_node_t*)node->children[index];
     2540            if ( child == NULL )  // miss
     2541            {
     2542                // allocate a cache node if miss
     2543                child = _allocate_one_cache_node( NULL );
     2544                node->children[index] = child;   
     2545            }
     2546
     2547            // prepare next iteration
     2548            node = child;
     2549            level--;
     2550        }
     2551    } // end while
     2552
     2553    return 0;
     2554}  // end _get_fat_cache_buffer()
     2555
     2556
    24512557
    24522558/////////////////////////////////////////////////////////////////////////////
     
    24592565/////////////////////////////////////////////////////////////////////////////
    24602566// This function initializes the FAT structures.
    2461 // - The Fat-Descriptor is always initialized.
     2567// - The Fat-Descriptor is initialized in both boot and kernel modes.
    24622568// - The dynamically allocated structures (the Inode-Tre, the Fat_Cache,
    24632569//   and the File-Cache for the root directory) are only allocated
     
    25822688
    25832689        // create Inode-Tree root
    2584         _fat.inode_tree_root = _allocate_one_inode("/", // dir name
    2585                                                    1,   // directory
    2586                                                    2,   // cluster id
    2587                                                    0,   // no size
    2588                                                    0,   // no children
    2589                                                    0,   // no dentry
    2590                                                    1);  // allocate cache
     2690        _fat.inode_tree_root = _allocate_one_inode("/",   // dir name
     2691                                                   1,     // is directory
     2692                                                   2,     // cluster index
     2693                                                   4096,  // at least one buffer
     2694                                                   0,     // no children
     2695                                                   0,     // no dentry
     2696                                                   1);    // allocate cache
    25912697
    25922698        // initialize lock
     
    26142720///////////////////////////////////////////////////////////////////////////////
    26152721// This function implements the giet_fat_open() system call.
    2616 // The semantic is similar to the UNIX open() function, but only the O_CREATE
    2617 // and O_RDONLY flags are supported. The UNIX access rights are not supported.
    2618 // If the file does not exist in the specified directory, it is created.
     2722// The semantic is similar to the UNIX open() function, with some limitations:
     2723// - only the O_CREATE, O_RDONLY, and O_TRUNC flags are supported.
     2724// - the UNIX access rights are not supported.
     2725// If the file does not exist in the specified directory, it is created when
     2726// the O_CREATE flag is set.
    26192727// If the specified directory does not exist, an error is returned.
    26202728// It allocates a file descriptor to the calling task, for the file identified
    2621 // by "pathname". If several tasks try to open the same file, each task
    2622 // obtains a private file descriptor.
     2729// by the <pathname> argument. If several tasks try to open the same file,
     2730// each task obtains a private file descriptor.
    26232731// A node name (file or directory) cannot be larger than 31 characters.
    26242732///////////////////////////////////////////////////////////////////////////////
     
    26722780    code = _get_inode_from_path( pathname , &inode );
    26732781
    2674     if ( code == 2 ) 
     2782    if ( code == 2 )                          // parent inode not found
    26752783    {
    26762784        _spin_lock_release( &_fat.fat_lock );
     
    26812789        return GIET_FAT32_FILE_NOT_FOUND;
    26822790    }
    2683     else if ( code == 3 ) 
     2791    else if ( code == 3 )                     // illegal path name
    26842792    {
    26852793        _spin_lock_release( &_fat.fat_lock );
     
    26902798        return GIET_FAT32_NAME_TOO_LONG;
    26912799    }
    2692     else if ( (code == 1) && (create == 0) )   
     2800    else if ( (code == 1) && (create == 0) )   // inode not found
    26932801    {
    26942802        _spin_lock_release( &_fat.fat_lock );
     
    26992807        return GIET_FAT32_FILE_NOT_FOUND;
    27002808    }
    2701     else if ( (code == 1) && (create != 0) )   // file name not found => create
     2809    else if ( (code == 1) && (create != 0) )   // inode not found => create
    27022810    {
    27032811        // set parent inode pointer
     
    27202828                                     0,                         // size : new file is empty
    27212829                                     0,                         // count incremented later
    2722                                      0,                         // dentry set by add_dir_entry
     2830                                     0,                         // set by add_dir_entry
    27232831                                     1 );                       // cache_allocate
    27242832
     
    27762884        // no need to truncate a new file
    27772885        truncate = 0;
    2778     }
    2779     else // code == 0
     2886
     2887#if GIET_DEBUG_FAT
     2888if ( _get_proctime() > GIET_DEBUG_FAT )
     2889{
     2890    _printf("\n[DEBUG FAT] _fat_open() : new inode created for <%s>\n"
     2891            " size = %x / cluster = %x / cache = %x",
     2892            child->name , child->size , child->cluster , child->cache );
     2893    if ( child->cache != NULL )
     2894    {
     2895         _printf(" / pdesc[0] = %x\n", (unsigned int)(child->cache->children[0]) );
     2896    }
     2897    else
     2898    {
     2899         _printf("\n");
     2900    }
     2901}
     2902#endif
     2903
     2904    }
     2905    else                                    // inode found
    27802906    {
    27812907        // set searched file inode pointer
     
    28462972    }
    28472973
     2974#if GIET_DEBUG_FAT
     2975if ( _get_proctime() > GIET_DEBUG_FAT )
     2976_printf("\n[DEBUG FAT] _fat_open(): P[%d,%d,%d] got fd = %d for <%s> / "
     2977        "size = %x / read_only = %d\n",
     2978        x , y , p , fd_id , pathname , read_only );
     2979#endif
     2980
    28482981    // releases the lock
    28492982    _spin_lock_release( &_fat.fat_lock );
    28502983    _atomic_and( &psched->context[ltid].slot[CTX_LOCKS_ID] , ~LOCKS_MASK_FAT );
    28512984
    2852 
    2853 #if GIET_DEBUG_FAT
    2854 if ( _get_proctime() > GIET_DEBUG_FAT )
    2855 _printf("\n[DEBUG FAT] _fat_open(): P[%d,%d,%d] got fd = %d for <%s> / "
    2856         "read_only = %d\n",
    2857         x , y , p , fd_id , pathname , read_only );
    2858 #endif
    28592985    return fd_id;
    28602986} // end _fat_open()
     
    29103036    fat_inode_t*  inode = _fat.fd[fd_id].inode;
    29113037
     3038#if GIET_DEBUG_FAT
     3039if ( _get_proctime() > GIET_DEBUG_FAT )
     3040_printf("\n[FAT DEBUG] _fat_close() for file <%s> : refcount = %d"
     3041        " / size = %x / cluster = %x\n",
     3042        inode->name , inode->count , inode->size , inode->cluster );
     3043#endif
     3044
    29123045    // decrement reference count
    29133046    inode->count = inode->count - 1;
    29143047   
    2915 #if GIET_DEBUG_FAT
    2916 if ( _get_proctime() > GIET_DEBUG_FAT )
    2917 _printf("\n[FAT DEBUG] _fat_close() for file <%s> : refcount = %d\n",
    2918         inode->name , inode->count );
    2919 #endif
    2920 
    29213048    // update block device and release File-Cache if no more references
    29223049    if ( inode->count == 0 )
     
    29373064#if GIET_DEBUG_FAT
    29383065if ( _get_proctime() > GIET_DEBUG_FAT )
    2939 _printf("\n[FAT DEBUG] _fat_close() update device for file <%s>\n", inode->name );
    2940 #endif
    2941 
    2942         // update directory dirty clusters for parent directory
     3066_printf("\n[FAT DEBUG] _fat_close() updated device for file <%s>\n", inode->name );
     3067#endif
     3068
     3069        // update dirty clusters for parent directory
    29433070        if ( inode->parent &&
    29443071             _update_device_from_cache( inode->parent->levels,
     
    29563083#if GIET_DEBUG_FAT
    29573084if ( _get_proctime() > GIET_DEBUG_FAT )
    2958 _printf("\n[FAT DEBUG] _fat_close() update device for parent directory <%s>\n",
     3085_printf("\n[FAT DEBUG] _fat_close() updated device for parent directory <%s>\n",
    29593086        inode->parent->name );
    29603087#endif
     
    31383265        unsigned char*     cbuf;
    31393266        fat_cache_desc_t*  pdesc;
    3140         if ( _fat_buffer_from_cache( inode,
     3267        if ( _get_file_cache_buffer( inode,
    31413268                                     cluster_id,
     3269                                     0,
    31423270                                     &pdesc ) )
    31433271        {
     
    33143442    if ( new_size > old_size )
    33153443    {
     3444        // compute current and required numbers of clusters
     3445        unsigned old_clusters = old_size >> 12;
     3446        if ( old_size & 0xFFF ) old_clusters++;
     3447
     3448        unsigned new_clusters = new_size >> 12;
     3449        if ( new_size & 0xFFF ) new_clusters++;
     3450
     3451        // allocate new clusters from FAT if required
     3452        if ( new_clusters > old_clusters )
     3453        {
     3454
     3455#if GIET_DEBUG_FAT
     3456if ( _get_proctime() > GIET_DEBUG_FAT )
     3457_printf("\n[DEBUG FAT] _fat_write(): P[%d,%d,%d] allocates new clusters for file <%s>"
     3458        " / current = %d / required = %d\n",
     3459        x , y , p , inode->name , old_clusters , new_clusters );
     3460#endif
     3461            // allocate missing clusters
     3462            unsigned int cid;
     3463            unsigned int index;  // unused
     3464            for ( cid = 0 ; cid < (new_clusters - old_clusters) ; cid++ )
     3465            {
     3466                if ( _cluster_allocate( inode , &index ) )
     3467                {
     3468                    _spin_lock_release( &_fat.fat_lock );
     3469                    _atomic_and( &psched->context[ltid].slot[CTX_LOCKS_ID] ,
     3470                                 ~LOCKS_MASK_FAT );
     3471
     3472                    _printf("\n[FAT ERROR] in _fat_write(): no free cluster"
     3473                            " for file <%s>\n", _fat.fd[fd_id].inode->name );
     3474                    return GIET_FAT32_NO_FREE_SPACE;
     3475                }
     3476            }
     3477        }
     3478         
    33163479        // update size in inode
    33173480        inode->size = new_size;
    33183481 
    3319         // compute current and required numbers of clusters
    3320         unsigned old_clusters = old_size >> 12;
    3321         if ( old_size & 0xFFF ) old_clusters++;
    3322 
    3323         unsigned new_clusters = new_size >> 12;
    3324         if ( new_size & 0xFFF ) new_clusters++;
    3325 
    3326         // allocate new clusters from FAT if required
    3327         if ( new_clusters > old_clusters )
    3328         {
    3329 
    3330 #if GIET_DEBUG_FAT
    3331 if ( _get_proctime() > GIET_DEBUG_FAT )
    3332 _printf("\n[DEBUG FAT] _fat_write(): P[%d,%d,%d] allocates new clusters for file <%s>"
    3333         " / current = %d / required = %d\n",
    3334         x , y , p , inode->name , old_clusters , new_clusters );
    3335 #endif
    3336             // allocate missing clusters
    3337             if ( _clusters_allocate( inode,
    3338                                      old_clusters,
    3339                                      new_clusters - old_clusters ) )
    3340             {
    3341                 _spin_lock_release( &_fat.fat_lock );
    3342                 _atomic_and( &psched->context[ltid].slot[CTX_LOCKS_ID] , ~LOCKS_MASK_FAT );
    3343 
    3344                 _printf("\n[FAT ERROR] _fat_write(): no free clusters"
    3345                         " for file <%s>\n", _fat.fd[fd_id].inode->name );
    3346                 return GIET_FAT32_NO_FREE_SPACE;
    3347             }
    3348         }
    3349          
    33503482        // update parent directory entry (size and cluster index)
    33513483        if ( _update_dir_entry( inode ) )
     
    33933525        unsigned char*     cbuf;
    33943526        fat_cache_desc_t*  pdesc;
    3395         if ( _fat_buffer_from_cache( inode,   
     3527        if ( _get_file_cache_buffer( inode,   
    33963528                                     cluster_id, 
     3529                                     0,
    33973530                                     &pdesc ) )   
    33983531        {
     
    39154048                               0 );            // no cache_allocate
    39164049 
    3917     // give the "old" File-Cache to the "new inode
     4050    // attach the "old" File-Cache to the "new" inode
    39184051    new->levels = old->levels;
    39194052    new->cache  = old->cache;
     
    41074240                                     1,           // it's a directory
    41084241                                     cluster, 
    4109                                      0,           // size not defined
     4242                                     4096,        // one buffer for a directory
    41104243                                     0,           // count
    41114244                                     0,           // dentry set by _add_dir_entry()
     
    44794612
    44804613
    4481 //////////////////////////////////////////////////////////////////////////////////
    4482 // The following function returns in the "desc" argument a pointer on a buffer
    4483 // descriptor contained in a File_Cache, or in the Fat_Cache.
    4484 // The searched buffer is idenfified by the "inode" and "cluster_id" arguments.
    4485 // If the "inode" pointer is not NULL, the searched cache is a File-Cache.
    4486 // If the "inode" pointer is NULL, the searched cache is the Fat-Cache,
    4487 // The "cluster_id" argument is the buffer index in the file (or in the FAT).
    4488 // In case of miss, it allocate a 4 Kbytes buffer and a cluster descriptor
    4489 // from the local kernel heap, and calls the _fat_ioc_access() function to load
    4490 // the missing cluster from the block device.
     4614
     4615//////////////////////////////////////////////////////////////////////////////////
     4616// The following function returns in the <desc> argument a pointer on a buffer
     4617// descriptor contained in a File_Cache.
     4618// The searched buffer is idenfified by the <inode> and <cluster_id> arguments.
     4619// The <cluster_id> argument is the buffer index in the file.
     4620// The <writable> argument define the behaviour in case of miss in File-Cache:
     4621// - if [all clusters (from 0 to cluster_id) are already allocated in FAT]
     4622//   we scan the FAT to find the cluster index on device, and we load the
     4623//   missing cluster in the File-Cache, marked as dirty if writable is set.
     4624// - else if [writable is not set]  we return an error.
     4625// - else [writable set, but all clusters (from 0 to cluster_id) not allocated]
     4626//   we allocate in FAT all required clusters, we update the size in the inode
     4627//   and dentry, and we allocate a buffer descriptor for the missing cluster,
     4628//   marked as dirty.
     4629// This function can be called by the FAT functions, and by _sys_fat_mmap().
     4630// It does not take the FAT lock, that must be taken by the caller.
    44914631//////////////////////////////////////////////////////////////////////////////////
    44924632// It returns 0 on success.
    44934633// It returns 1 on error.
    44944634//////////////////////////////////////////////////////////////////////////////////
    4495 int _fat_buffer_from_cache( fat_inode_t*        inode,
    4496                             unsigned int        cluster,
     4635int _get_file_cache_buffer( fat_inode_t*        inode,
     4636                            unsigned int        cluster_id,
     4637                            unsigned int        writable,
    44974638                            fat_cache_desc_t**  desc )
    44984639{
    4499     // get cache pointer and levels
    4500     fat_cache_node_t*   node;         // pointer on a 64-tree node
    4501     unsigned int        level;        // cache level
    4502 
    4503     if ( inode == NULL )   // searched cache is the Fat-Cache
    4504     {
    4505         node   = _fat.fat_cache_root;
    4506         level  = _fat.fat_cache_levels;
    45074640
    45084641#if (GIET_DEBUG_FAT & 1)
    45094642if ( _get_proctime() > GIET_DEBUG_FAT )
    4510 _printf("\n[DEBUG FAT] _fat_buffer_from_cache(): enters in FAT-Cache"
    4511         " for cluster = %d\n", cluster );
    4512 #endif
    4513     }
    4514     else                   // searched cache is a File-Cache
    4515     {
    4516         // add cache levels if needed
    4517         while ( _get_levels_from_size( (cluster + 1) * 4096 ) > inode->levels )
    4518         {
     4643_printf("\n[DEBUG FAT] _get_file_cache_buffer(): enters in File-Cache <%s>"
     4644        " for cluster_id = %d\n size = %x / cache = %x / desc[%d] = %x\n",
     4645        inode->name , cluster_id ,
     4646        inode->size , (unsigned int)inode->cache , cluster_id ,
     4647        (unsigned int)inode->cache->children[cluster_id] );
     4648#endif
     4649
     4650    // checking FAT initialized
     4651    if( _fat.initialized != FAT_INITIALIZED )
     4652    {
     4653        _printf("\n[FAT ERROR] in _get_file_cache_buffer() : FAT not initialized\n");
     4654        return GIET_FAT32_NOT_INITIALIZED;
     4655    }
     4656
     4657    // checking arguments
     4658    if ( inode == NULL )   // illegal inode argument
     4659    {
     4660        _printf("\n[FAT ERROR] in _get_file_cache_buffer() : illegal inode argument\n");
     4661        return GIET_FAT32_INVALID_ARG;
     4662    }
     4663
     4664    // add cache levels if needed
     4665    while ( _get_levels_from_size( (cluster_id + 1) * 4096 ) > inode->levels )
     4666    {
     4667
    45194668#if (GIET_DEBUG_FAT & 1)
    45204669if ( _get_proctime() > GIET_DEBUG_FAT )
    4521 _printf("\n[DEBUG FAT] _fat_buffer_from_cache(): adding a File-Cache level\n" );
    4522 #endif
    4523 
    4524             inode->cache = _allocate_one_cache_node( inode->cache );
    4525             inode->levels++;
    4526         }
    4527 
    4528         node   = inode->cache;
    4529         level  = inode->levels;
    4530 
    4531 #if (GIET_DEBUG_FAT & 1)
    4532 if ( _get_proctime() > GIET_DEBUG_FAT )
    4533 _printf("\n[DEBUG FAT] _fat_buffer_from_cache(): enters in File-Cache <%s>"
    4534         " for cluster = %d\n", inode->name , cluster );
    4535 #endif
    4536     }
     4670_printf("\n[DEBUG FAT] _get_file_cache_buffer() : add a File-Cache level\n" );
     4671#endif
     4672
     4673        inode->cache = _allocate_one_cache_node( inode->cache );
     4674        inode->levels++;
     4675    }
     4676
     4677    // get File-Cache
     4678    fat_cache_node_t*   node  = inode->cache; 
     4679    unsigned int        level = inode->levels;
     4680
    45374681
    45384682    // search the 64-tree cache from top to bottom
     
    45404684    {
    45414685        // compute child index at each level
    4542         unsigned int index = (cluster >> (6*(level-1))) & 0x3F;
    4543 
    4544         if ( level == 1 )        // last level => children are cluster descriptors
    4545         {
    4546             fat_cache_desc_t* pdesc = (fat_cache_desc_t*)node->children[index];
    4547 
    4548             if ( pdesc == NULL )      // miss
     4686        unsigned int index = (cluster_id >> (6*(level-1))) & 0x3F;
     4687
     4688        if ( level == 1 )        // last level => children are buffer descriptors
     4689        {
     4690            fat_cache_desc_t*   pdesc = (fat_cache_desc_t*)node->children[index];
     4691            unsigned int        current = inode->cluster;
     4692            unsigned int        next    = 0;
     4693            unsigned int        prev    = 0;
     4694            unsigned int        cid;
     4695            unsigned int        lba;
     4696
     4697            if ( pdesc == NULL )      // miss in File-Cache
    45494698            {
    4550                 // get missing cluster index lba
    4551                 unsigned int lba;
    4552                 unsigned int next;
    4553                 unsigned int current = inode->cluster;
    4554                 unsigned int count   = cluster;
    4555 
    4556                 if ( inode == NULL )      // searched cache is the Fat-Cache
     4699
     4700#if (GIET_DEBUG_FAT & 1)
     4701if ( _get_proctime() > GIET_DEBUG_FAT )
     4702_printf("\n[DEBUG FAT] _get_file_cache_buffer() : miss in cache <%s> for cluster_id = %d\n"
     4703        " cluster = %x / size = %x / cache = %x / desc[%d] = %x\n",
     4704        inode->name , cluster_id , inode-> cluster , inode->size ,
     4705        (unsigned int)inode->cache , cluster_id ,
     4706        (unsigned int)inode->cache->children[cluster_id] );
     4707#endif
     4708                if ( inode->size > (cluster_id<<12) )  // all clusters allocated in FAT
    45574709                {
    4558 
    4559 #if (GIET_DEBUG_FAT & 1)
    4560 if ( _get_proctime() > GIET_DEBUG_FAT )
    4561 _printf("\n[DEBUG FAT] _fat_buffer_from_cache(): miss in FAT-Cache for cluster %d\n",
    4562         cluster );
    4563 #endif
    4564                     lba = _fat.fat_lba + (cluster << 3);
    4565                 }
    4566                 else                      // searched cache is a File-Cache
    4567                 {
    4568 
    4569 #if (GIET_DEBUG_FAT & 1)
    4570 if ( _get_proctime() > GIET_DEBUG_FAT )
    4571 _printf("\n[DEBUG FAT] _fat_buffer_from_cache(): miss in File-Cache <%s> "
    4572         "for cluster %d\n", inode->name, cluster );
    4573 #endif
    4574                     while ( count )
    4575                     {
     4710                    // scan the FAT to find the cluster index for cluster_id
     4711                    for ( cid = 0 ; cid < cluster_id ; cid++ )
     4712                    {
     4713                        // get next cluster index from FAT
    45764714                        if ( _get_fat_entry( current , &next ) ) return 1;
    45774715                        current = next;
    4578                         count--;
    45794716                    }
     4717
     4718                    // compute lba
    45804719                    lba = _cluster_to_lba( current );
     4720
     4721                    // allocate a 4 Kbytes buffer and a buffer descriptor
     4722                    // the selected heap depends on the calling thread
     4723                    void* buf      = _malloc( 4096 );
     4724                    pdesc          = _malloc( sizeof(fat_cache_desc_t) );
     4725
     4726                    // set buffer descriptor
     4727                    pdesc->lba     = lba;
     4728                    pdesc->buffer  = buf;
     4729                    pdesc->dirty   = writable;
     4730                    node->children[index] = pdesc;
     4731
     4732                    // load cluster from device
     4733                    if ( _fat_ioc_access( 1,         // descheduling
     4734                                          1,         // to memory
     4735                                          lba,
     4736                                          (unsigned int)buf,
     4737                                      8 ) )
     4738                    {
     4739                         
     4740                        _free( buf );
     4741                        _free( pdesc );
     4742                        _printf("\n[FAT ERROR] in _get_file_cache_buffer() : "
     4743                                "cannot access block device for lba = %x\n", lba );
     4744                        return GIET_FAT32_IO_ERROR;
     4745                    }
    45814746                }
    4582 
    4583                 // allocate a 4 Kbytes buffer in cluster running the calling thread
    4584                 void* buf = _malloc( 4096 );
    4585 
    4586                 // load one cluster (8 blocks) from block device
    4587                 if ( _fat_ioc_access( 1,         // descheduling
    4588                                       1,         // to memory
    4589                                       lba,
    4590                                       (unsigned int)buf,
    4591                                       8 ) )
     4747                else if ( writable == 0 )
    45924748                {
    4593                     _free( buf );
    4594                     _printf("\n[FAT ERROR] _fat_buffer_from_cache()"
    4595                             ": cannot access block device for lba = %x\n", lba );
    4596                     return 1;
     4749                    _printf("\n[FAT ERROR] in _get_file_cache_buffer() : "
     4750                            " file size too small for <%s>\n"
     4751                            " size = %x / cluster_id = %d / procid = %x\n",
     4752                            inode->name , inode->size , cluster_id , _get_procid() );
     4753                    return GIET_FAT32_IO_ERROR;
    45974754                }
    4598 
    4599                 // allocate buffer descriptor
    4600                 pdesc          = _malloc( sizeof(fat_cache_desc_t) );
    4601                 pdesc->lba     = lba;
    4602                 pdesc->buffer  = buf;
    4603                 pdesc->dirty   = 0;
    4604                 node->children[index] = pdesc;
    4605 
    4606 #if (GIET_DEBUG_FAT & 1)
    4607 if ( _get_proctime() > GIET_DEBUG_FAT )
    4608 _printf("\n[DEBUG FAT] _fat_buffer_from_cache(): buffer loaded from device"
    4609         " at vaddr = %x\n", (unsigned int)buf );
    4610 #endif
     4755                else   // writable and all clusters NOT allocated in FAT
     4756                {
     4757                    // scan the FAT to allocate all required clusters
     4758                    for ( cid = 0 ; cid <= cluster_id ; cid++ )
     4759                    {
     4760                        if ( current >= END_OF_CHAIN_CLUSTER_MIN ) // non allocated
     4761                        {
     4762                            // allocate one cluster on device
     4763                            if ( _cluster_allocate( inode , &current ) )
     4764                            {
     4765                                _printf("\n[FAT ERROR] in _get_file_cache_buffer() : "
     4766                                        "cannot allocate new cluster for file <%s>\n",
     4767                                        inode->name );
     4768                                return GIET_FAT32_IO_ERROR;
     4769                            }
     4770                        }
     4771 
     4772                        // get next cluster index from FAT
     4773                        if ( _get_fat_entry( current , &next ) )
     4774                        {
     4775                            _printf("\n[FAT ERROR] in _get_file_cache_buffer() : "
     4776                                    "cannot get next cluster for file <%s>\n",
     4777                                    inode->name );
     4778                            return GIET_FAT32_IO_ERROR;
     4779                        }
     4780                        prev    = current;
     4781                        current = next;
     4782                    }
     4783
     4784                    // update size in inode and directory entry
     4785                    inode->size = (cluster_id + 1)<<12;
     4786                    _update_dir_entry( inode );
     4787
     4788                    // compute lba
     4789                    lba = _cluster_to_lba( current );
     4790
     4791                    // allocate a 4 Kbytes buffer and a buffer descriptor
     4792                    // the selected heap depends on the calling thread
     4793                    void* buf      = _malloc( 4096 );
     4794                    pdesc          = _malloc( sizeof(fat_cache_desc_t) );
     4795
     4796                    // set buffer descriptor
     4797                    pdesc->lba     = lba;
     4798                    pdesc->buffer  = buf;
     4799                    pdesc->dirty   = writable;
     4800                    node->children[index] = pdesc;
     4801                }
    46114802            }
    46124803
     
    46144805            *desc = pdesc;
    46154806
     4807#if (GIET_DEBUG_FAT & 1)
     4808if ( _get_proctime() > GIET_DEBUG_FAT )
     4809_printf("\n[DEBUG FAT] _fat_buffer_from_cache(): found buffer = %x "
     4810        " in file <%s> for cluster_id %d\n",
     4811        (unsigned int)pdesc->buffer , inode->name , cluster_id );
     4812#endif
    46164813            // prepare next iteration
    46174814            level--;
     
    46334830    } // end while
    46344831
    4635     return 0;
    4636 }  // end _fat_buffer_from_cache()
    4637 
    4638 
    4639 
     4832    return GIET_FAT32_OK;
     4833
     4834}  // end _get_file_cache_buffer()
    46404835
    46414836// Local Variables:
Note: See TracChangeset for help on using the changeset viewer.