Changeset 626 for trunk/kernel/fs


Ignore:
Timestamp:
Apr 29, 2019, 7:25:09 PM (6 years ago)
Author:
alain
Message:

This version has been tested on the sort multithreaded application
for TSAR_IOB architectures ranging from 1 to 8 clusters.
It fixes three bigs bugs:
1) the dev_ioc device API has been modified: the dev_ioc_sync_read()
and dev_ioc_sync_write() function use now extended pointers on the
kernel buffer to access a mapper stored in any cluster.
2) the hal_uspace API has been modified: the hal_copy_to_uspace()
and hal_copy_from_uspace() functions use now a (cxy,ptr) couple
to identify the target buffer (equivalent to an extended pointer.
3) an implementation bug has been fixed in the assembly code contained
in the hal_copy_to_uspace() and hal_copy_from_uspace() functions.

Location:
trunk/kernel/fs
Files:
4 edited

Legend:

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

    r625 r626  
    3737#include <fatfs.h>
    3838
     39#define LITTLE_ENDIAN  1
    3940
    4041//////////////////////////////////////////////////////////////////////////////////////////
     
    7273
    7374//////////////////////////////////////////////////////////////////////////////////////////
    74 // This function return an integer record value (one, two, or four bytes)
    75 // from a memory buffer, taking into account endianness.
    76 //////////////////////////////////////////////////////////////////////////////////////////
    77 // @ offset        : first byte of record in buffer.
    78 // @ size          : record length in bytes (1/2/4).
    79 // @ buffer        : pointer on buffer base.
    80 // @ little endian : the most significant byte has the highest address when true.
     75// This function return an integer record value (one, two, or four bytes) from a local
     76// array of bytes, taking into account the global LITTLE_ENDIAN parameter:
     77// if LITTLE_ENDIAN is true, the most significant byte has the highest address.
     78//////////////////////////////////////////////////////////////////////////////////////////
     79// @ offset        : first byte in array.
     80// @ nbytes        : record length in bytes (1/2/4).
     81// @ buffer        : local pointer on byte array.
    8182// @ return the integer value in a 32 bits word.
    8283//////////////////////////////////////////////////////////////////////////////////////////
    8384static uint32_t fatfs_get_record( uint32_t    offset,
    84                                   uint32_t    size,
    85                                   uint8_t   * buffer,
    86                                   uint32_t    little_endian )
    87 {
    88     uint32_t n;
    89     uint32_t res  = 0;
    90 
    91     if ( little_endian )
    92     {
    93         for( n = size ; n > 0 ; n-- ) res = (res<<8) | buffer[offset+n-1];
    94     }
    95     else // big_endian
    96     {
    97         for( n = 0 ; n < size ; n++ ) res = (res<<8) | buffer[offset+n];
     85                                  uint32_t    nbytes,
     86                                  uint8_t   * buffer )
     87{
     88    uint32_t i;
     89    uint32_t res = 0;
     90
     91    if ( LITTLE_ENDIAN )
     92    {
     93        for( i = nbytes ; i > 0 ; i-- ) res = (res<<8) | buffer[offset+i-1];
     94    }
     95    else
     96    {
     97        for( i = 0 ; i < nbytes ; i++ ) res = (res<<8) | buffer[offset+i];
    9898    }
    9999    return res;
     
    102102
    103103//////////////////////////////////////////////////////////////////////////////////////////
    104 // This function writes one, two, or four bytes from a 32 bits integer to a memory buffer,
    105 // taking into account endianness.
    106 //////////////////////////////////////////////////////////////////////////////////////////
    107 // @ offset        : first byte of record in buffer.
    108 // @ size          : record length in bytes (1/2/4).
    109 // @ buffer        : pointer on buffer base.
    110 // @ little endian : the most significant byte has the highest address when true.
     104// This function return an integer record value (one, two, or four bytes) from a remote
     105// array of bytes, taking into account the global LITTLE_ENDIAN parameter:
     106// if LITTLE_ENDIAN is true, the most significant byte has the highest address.
     107//////////////////////////////////////////////////////////////////////////////////////////
     108// @ offset        : first byte in array.
     109// @ nbytes        : record length in bytes (1/2/4).
     110// @ buffer_xp     : extended pointer on byte array.
    111111// @ return the integer value in a 32 bits word.
    112112//////////////////////////////////////////////////////////////////////////////////////////
     113static uint32_t fatfs_get_remote_record( uint32_t   offset,
     114                                         uint32_t   nbytes,
     115                                         xptr_t     buffer_xp )
     116{
     117    uint32_t i;
     118    uint32_t res = 0;
     119
     120    if ( LITTLE_ENDIAN )
     121    {
     122        for( i = nbytes ; i > 0 ; i-- )
     123        {
     124            res = (res<<8) | hal_remote_lb( buffer_xp+offset+i-1 );
     125        }
     126    }
     127    else
     128    {
     129        for( i = 0 ; i < nbytes ; i++ )
     130        {
     131            res = (res<<8) | hal_remote_lb( buffer_xp+offset+i );
     132        }
     133    }
     134    return res;
     135
     136}  // end fatfs_get_remote_record()
     137
     138//////////////////////////////////////////////////////////////////////////////////////////
     139// This function writes one, two, or four bytes from a 32 bits integer to a local
     140// array of bytes, taking into account the global LITTLE_ENDIAN parameter:
     141// if LITTLE_ENDIAN is true, the most significant byte has the highest address.
     142//////////////////////////////////////////////////////////////////////////////////////////
     143// @ offset        : first byte in array.
     144// @ nbytes        : record length in bytes (1/2/4).
     145// @ buffer        : local pointer on byte array.
     146// @ value         : 32 bits integer value.
     147//////////////////////////////////////////////////////////////////////////////////////////
    113148static void fatfs_set_record( uint32_t    offset,
    114                               uint32_t    size,
     149                              uint32_t    nbytes,
    115150                              uint8_t   * buffer,
    116                               uint32_t    little_endian,
    117151                              uint32_t    value )
    118152{
    119     uint32_t n;
    120 
    121     if ( little_endian )
    122     {
    123         for( n = size ; n > 0 ; n-- ) buffer[offset+n-1] = (uint8_t)(value>>((n-1)<<3));
    124     }
    125     else // big_endian
    126     {
    127         for( n = 0 ; n < size ; n++ ) buffer[offset+n] = (uint8_t)(value>>((size-1-n)<<3));
     153    uint32_t i;
     154
     155    if ( LITTLE_ENDIAN )
     156    {
     157        for( i = nbytes ; i > 0 ; i-- ) buffer[offset+i-1] = (uint8_t)(value>>((i-1)<<3));
     158    }
     159    else
     160    {
     161        for( i = 0 ; i < nbytes ; i++ ) buffer[offset+i] = (uint8_t)(value>>((nbytes-1-i)<<3));
     162    }
     163
     164}  // end fatfs_set_record()
     165
     166//////////////////////////////////////////////////////////////////////////////////////////
     167// This function writes one, two, or four bytes from a 32 bits integer to a remote
     168// array of bytes, taking into account the global LITTLE_ENDIAN parameter:
     169// if LITTLE_ENDIAN is true, the most significant byte has the highest address.
     170//////////////////////////////////////////////////////////////////////////////////////////
     171// @ offset        : first byte in array.
     172// @ nbytes        : record length in bytes (1/2/4).
     173// @ buffer_xp     : extended pointer on byte array.
     174// @ value         : 32 bits integer value.
     175//////////////////////////////////////////////////////////////////////////////////////////
     176static void fatfs_set_remote_record( uint32_t    offset,
     177                                     uint32_t    nbytes,
     178                                     xptr_t      buffer_xp,
     179                                     uint32_t    value )
     180{
     181    uint32_t i;
     182
     183    if ( LITTLE_ENDIAN )
     184    {
     185        for( i = nbytes ; i > 0 ; i-- )
     186        {
     187            hal_remote_sb( (buffer_xp+offset+i-1) , (uint8_t)(value>>((i-1)<<3)) );
     188        }
     189    }
     190    else
     191    {
     192        for( i = 0 ; i < nbytes ; i++ )
     193        {
     194            hal_remote_sb( (buffer_xp+offset+i) , (uint8_t)(value>>((nbytes-1-i)<<3)) );
     195        }
    128196    }
    129197
     
    374442
    375443//////////////////////////////////////////////////////////////////////////////////////////
     444// This static function is called by both the fatfs_free_clusters_increment(),
     445// and the fatfs_free_cluster_decrement() functions defined below.
     446// It synchronously updates the  "free_clusters" and "free_cluster_hint" variables
     447// in FS_INFO sector on the IOC device, each times these variables are modified.
     448//////////////////////////////////////////////////////////////////////////////////////////
     449// @ fatfs_ctx_xp      : extended pointer on fatfs context in FAT cluster.
     450// @ free_clusters     : new free_clusters value.
     451// @ free_cluster_hint : new free_cluster_hint value.
     452// @ return 0 if success, return -1 if the FS_INFO sector cannot be updated.
     453//////////////////////////////////////////////////////////////////////////////////////////
     454static error_t fatfs_free_clusters_update_ioc( xptr_t    fatfs_ctx_xp,
     455                                               uint32_t  free_clusters,
     456                                               uint32_t  free_cluster_hint )
     457{
     458    cxy_t         fat_cxy;             // FAT cluster identifier
     459    fatfs_ctx_t * fatfs_ctx_ptr;       // local pointer on fatfs context in FAT cluster
     460    uint8_t     * fs_info_buffer_ptr;  // local pointer on FS_INFO buffer in FAT cluster
     461    xptr_t        fs_info_buffer_xp;   // extended pointer on FS_INFO buffer in FAT cluster
     462    uint32_t      fs_info_lba;         // FS_INFO sector lba on IOC device
     463
     464    // get cluster and local pointer on FAT cluster context
     465    fat_cxy       = GET_CXY( fatfs_ctx_xp );
     466    fatfs_ctx_ptr = GET_PTR( fatfs_ctx_xp );
     467
     468    // get pointers on FS_INFO buffer in FAT cluster
     469    fs_info_buffer_ptr = hal_remote_lpt( XPTR( fat_cxy , &fatfs_ctx_ptr->fs_info_buffer ) );
     470    fs_info_buffer_xp  = XPTR( fat_cxy , fs_info_buffer_ptr );
     471
     472    // get lba of FS_INFO sector on IOC device from fatfs context
     473    fs_info_lba = hal_remote_l32( XPTR( fat_cxy , &fatfs_ctx_ptr->fs_info_lba ) );
     474
     475    // update the FS_INFO buffer in FAT cluster
     476    fatfs_set_remote_record( FS_FREE_CLUSTERS     , fs_info_buffer_xp , free_clusters );
     477    fatfs_set_remote_record( FS_FREE_CLUSTER_HINT , fs_info_buffer_xp , free_cluster_hint );
     478   
     479    // update the FS_INFO sector on IOC device
     480    return dev_ioc_sync_write( fs_info_buffer_xp , fs_info_lba , 1 );
     481 
     482}  // fatfs_free_clusters_update_ioc()
     483
     484//////////////////////////////////////////////////////////////////////////////////////////
    376485// This static function decrements the  "free_clusters" variable, and updates the
    377 // "free_cluster_hint" variable in the FATFS context, identified by the <fat_ctx_cxy>
    378 // and <fat_ctx_ptr> arguments (cluster containing the FAT mapper).
     486// "free_cluster_hint" variable in the FATFS context in FAT cluster, identified
     487// by the <fat_ctx_xp> argument, when a new <cluster> has been allocated from FAT.
    379488// It scan all slots in the FAT mapper seen as an array of 32 bits words, looking for the
    380489// first free slot larger than the <cluster> argument, to update "free_cluster_hint".
     490// It calls the fatfs_free_clusters_update_ioc() function to synchronously update the
     491// FS_INFO sector on the IOC device. It can be called by a thead running in any cluster.
    381492//
    382493// WARNING : The free_lock protecting exclusive access to these variables
    383494//           must be taken by the calling function.
    384495//////////////////////////////////////////////////////////////////////////////////////////
    385 // @ fat_ctx_cxy  : FAT mapper cluster identifier.
    386 // @ fat_ctx_ptr  : local pointer on FATFS context.
    387 // @ cluster      : recently allocated cluster index in FAT.
    388 //////////////////////////////////////////////////////////////////////////////////////////
    389 static error_t fatfs_free_clusters_decrement( cxy_t         fat_ctx_cxy,
    390                                               fatfs_ctx_t * fat_ctx_ptr,
    391                                               uint32_t      cluster )
    392 {
     496// @ fatfs_ctx_xp  : extended pointer on FATFS context in FAT cluster.
     497// @ cluster       : recently allocated cluster index in FAT.
     498// @ return 0 if success, return -1 if the FS_INFO sector cannot be updated.
     499//////////////////////////////////////////////////////////////////////////////////////////
     500static error_t fatfs_free_clusters_decrement( xptr_t    fatfs_ctx_xp,
     501                                              uint32_t  cluster )
     502{
     503    error_t       error;
     504    cxy_t         fat_cxy;      // FAT cluster identifier
     505    fatfs_ctx_t * fat_ctx_ptr;  // local pointer on fatfs context in FAT cluster
    393506    xptr_t        mapper_xp;    // extended pointer on FAT mapper
    394507    xptr_t        hint_xp;      // extended pointer on "free_cluster_hint" shared variable
    395508    xptr_t        numb_xp;      // extended pointer on "free_clusters" shared variable
    396509    uint32_t      numb;         // "free_clusters" variable current value
     510    uint32_t      hint;         // "free_cluster_hint" variable current value
    397511    uint32_t      page_id;      // page index in FAT mapper
    398512    uint32_t      slot_id;      // slot index in one page of FAT (1024 slots per page)
     
    405519uint32_t   cycle = (uint32_t)hal_get_cycles();
    406520thread_t * this  = CURRENT_THREAD;
    407 if( DEBUG_FATFS_FREE_CLUSTERS < (uint32_t)hal_get_cycles() )
     521if( DEBUG_FATFS_FREE_CLUSTERS < cycle )
    408522printk("\n[%s] thread[%x,%x] enter for allocated cluster %x / cycle %d\n",
    409523__FUNCTION__, this->process->pid, this->trdid, cluster , cycle );
    410524#endif
    411525
    412     // build extended pointers on free_clusters, and free_cluster_hint
    413     hint_xp = XPTR( fat_ctx_cxy , &fat_ctx_ptr->free_cluster_hint );
    414     numb_xp = XPTR( fat_ctx_cxy , &fat_ctx_ptr->free_clusters );
    415 
    416     // update "free_clusters"
    417     numb = hal_remote_l32( numb_xp );
    418     hal_remote_s32( numb_xp , numb - 1 );
     526    // get FAT cluster an local pointer on fatfs context in FAT cluster
     527    fat_cxy      = GET_CXY( fatfs_ctx_xp );
     528    fat_ctx_ptr  = GET_PTR( fatfs_ctx_xp );
     529   
     530    // build extended pointers on free_clusters, and free_cluster_hint in fatfs context
     531    hint_xp = XPTR( fat_cxy , &fat_ctx_ptr->free_cluster_hint );
     532    numb_xp = XPTR( fat_cxy , &fat_ctx_ptr->free_clusters );
     533
     534    // update "free_clusters" value
     535    numb = hal_remote_l32( numb_xp ) - 1;
     536    hal_remote_s32( numb_xp , numb );
    419537
    420538    // get extended pointer on FAT mapper
    421     mapper_xp = hal_remote_l64( XPTR( fat_ctx_cxy , &fat_ctx_ptr->fat_mapper_xp ) );
     539    mapper_xp = hal_remote_l64( XPTR( fat_cxy , &fat_ctx_ptr->fat_mapper_xp ) );
    422540
    423541    // initialise variables to scan the FAT mapper
     
    425543    page_id  = (cluster + 1) >> 10;
    426544    slot_id  = (cluster + 1) & 0x3FF;
    427     page_max = hal_remote_l32( XPTR( fat_ctx_cxy, &fat_ctx_ptr->fat_sectors_count ) ) >> 3;
     545    page_max = hal_remote_l32( XPTR( fat_cxy, &fat_ctx_ptr->fat_sectors_count ) ) >> 3;
    428546
    429547    // scan FAT mapper / loop on pages
     
    451569            if ( hal_remote_l32( slot_xp ) == FREE_CLUSTER )
    452570            {
    453                 // update "free_cluster_hint"
    454                 hal_remote_s32( hint_xp , (page_id << 10) + slot_id - 1 );
     571                // update "free_cluster_hint" value
     572                hint = (page_id << 10) + slot_id - 1;
     573                hal_remote_s32( hint_xp , hint );
     574
     575                // update FS_INFO sector on IOC device
     576                error = fatfs_free_clusters_update_ioc( fatfs_ctx_xp , numb , hint );
     577
     578                if( error )
     579                {
     580                    printk("\n[ERROR] in %s : cannot update FS_INFO on IOC\n", __FUNCTION__ );
     581                    return -1;
     582                }
    455583
    456584#if DEBUG_FATFS_FREE_CLUSTERS
    457585cycle = (uint32_t)hal_get_cycles();
    458586if( DEBUG_FATFS_FREE_CLUSTERS < (uint32_t)hal_get_cycles() )
    459 printk("\n[%s] thread[%x,%x] exit / hint %x / free_clusters %x / cycle %d\n",
    460 __FUNCTION__, this->process->pid, this->trdid,
    461 hal_remote_l32(hint_xp), hal_remote_l32(numb_xp), cycle );
     587printk("\n[%s] thread[%x,%x] updated free cluster info  / hint %x / number %x\n",
     588__FUNCTION__, this->process->pid, this->trdid, 
     589hal_remote_l32(hint_xp), hal_remote_l32(numb_xp) );
    462590#endif
    463591                return 0;
     
    469597        }  // end loop on slots
    470598
    471         // update (page_id,slot_id) variables
     599        // update page_id & slot_id variables
    472600        page_id++;
    473601        slot_id = 0;
     
    483611//////////////////////////////////////////////////////////////////////////////////////////
    484612// This static function increments the "free_clusters" variable, and updates the
    485 // "free_cluster_hint" variables in the FATFS context, identified by the <fat_ctx_cxy>
    486 // and <fat_ctx_ptr> argument (cluster containing the FAT mapper).
     613// "free_cluster_hint" variables in the FATFS context in FAT cluster, identified
     614// by the <fat_ctx_xp> argument, when a cluster is released to FAT.
    487615// If the released cluster index is smaller than the current (hint) value,
    488616// it set "free_cluster_hint" <= cluster.
     617// It calls the fatfs_free_clusters_update_ioc() function to synchronously update the
     618// FS_INFO sector on the IOC device. It can be called by a thead running in any cluster.
    489619//
    490620// WARNING : The free_lock protecting exclusive access to these variables
    491621//           must be taken by the calling function.
    492622//////////////////////////////////////////////////////////////////////////////////////////
    493 // @ fat_ctx_cxy  : FAT mapper cluster identifier.
    494 // @ fat_ctx_ptr  : local pointer on FATFS context.
    495 // @ cluster     : recently released cluster index in FAT.
    496 //////////////////////////////////////////////////////////////////////////////////////////
    497 static void fatfs_free_clusters_increment( cxy_t         fat_ctx_cxy,
    498                                            fatfs_ctx_t * fat_ctx_ptr,
    499                                            uint32_t      cluster )
    500 {
     623// @ fatfs_ctx_xp  : extended pointer on FATFS context in FAT cluster.
     624// @ cluster       : recently released cluster index in FAT.
     625// @ return 0 if success, return -1 if the FS_INFO sector cannot be updated.
     626//////////////////////////////////////////////////////////////////////////////////////////
     627static error_t fatfs_free_clusters_increment( xptr_t   fatfs_ctx_xp,
     628                                              uint32_t cluster )
     629{
     630    error_t       error;
     631    cxy_t         fat_cxy;      // FAT cluster identifier
     632    fatfs_ctx_t * fat_ctx_ptr;  // local pointer on fatfs context in FAT cluster
    501633    xptr_t        hint_xp;      // extended pointer on "free_cluster_hint" shared variable
    502634    xptr_t        numb_xp;      // extended pointer on "free_clusters" shared variable
     
    504636    uint32_t      numb;         // "free_clusters" variable current value
    505637
     638#if DEBUG_FATFS_FREE_CLUSTERS
     639uint32_t   cycle = (uint32_t)hal_get_cycles();
     640thread_t * this  = CURRENT_THREAD;
     641if( DEBUG_FATFS_FREE_CLUSTERS < cycle )
     642printk("\n[%s] thread[%x,%x] enter for released cluster %x / cycle %d\n",
     643__FUNCTION__, this->process->pid, this->trdid, cluster , cycle );
     644#endif
     645
     646    // get FAT cluster an local pointer on fatfs context in FAT cluster
     647    fat_cxy      = GET_CXY( fatfs_ctx_xp );
     648    fat_ctx_ptr  = GET_PTR( fatfs_ctx_xp );
     649   
    506650    // build extended pointers on free_clusters, and free_cluster_hint
    507     hint_xp = XPTR( fat_ctx_cxy , &fat_ctx_ptr->free_cluster_hint );
    508     numb_xp = XPTR( fat_ctx_cxy , &fat_ctx_ptr->free_clusters );
     651    hint_xp = XPTR( fat_cxy , &fat_ctx_ptr->free_cluster_hint );
     652    numb_xp = XPTR( fat_cxy , &fat_ctx_ptr->free_clusters );
    509653
    510654    // get current value of free_cluster_hint and free_clusters
     
    512656    numb = hal_remote_l32( numb_xp );
    513657
    514     // update free_cluster_hint if required
    515     if ( (cluster - 1) < hint ) hal_remote_s32( hint_xp , (cluster - 1) );
     658    // update "numb" and "hint" variables as required
     659    numb++;
     660    if ( (cluster - 1) < hint ) hint = cluster - 1;
    516661
    517662    // update free_clusters
    518     hal_remote_s32( numb_xp , numb + 1 );
     663    hal_remote_s32( numb_xp , numb );
     664    hal_remote_s32( hint_xp , hint );
     665
     666    // update FS_INFO sector on IOC device
     667    error = fatfs_free_clusters_update_ioc( fatfs_ctx_xp , numb , hint );
     668
     669    if( error )
     670    {
     671        printk("\n[ERROR] in %s : cannot update FS_INFO on IOC\n", __FUNCTION__ );
     672        return -1;
     673    }
    519674
    520675#if DEBUG_FATFS_FREE_CLUSTERS
    521676thread_t * this = CURRENT_THREAD;
    522677if( DEBUG_FATFS_FREE_CLUSTERS < (uint32_t)hal_get_cycles() )
    523 printk("\n[%s] thread[%x,%x] updates free cluster info : hint %x / number %x\n",
     678printk("\n[%s] thread[%x,%x] updated free cluster info : hint %x / number %x\n",
    524679__FUNCTION__, this->process->pid, this->trdid,
    525680hal_remote_l32( hint_xp ), hal_remote_l32( numb_xp ) );
    526681#endif
     682
     683    return 0;
    527684
    528685}  // end fatfs_free_clusters_increment()
     
    576733                               FREE_CLUSTER ) ) return -1;
    577734
    578     // Update free_cluster_hint and free_clusters in FAT context
    579     fatfs_free_clusters_increment( mapper_cxy,
    580                                    fatfs_ctx,
    581                                    cluster );
    582 
    583     return 0;
     735    // Update free_cluster info in FATFS context and in FS_INFO sector
     736    return fatfs_free_clusters_increment( XPTR( mapper_cxy , fatfs_ctx ) , cluster );
    584737
    585738}  // end fatfs_recursive_release()
     
    590743//////////////////////////////////////////////////////////////////////////////////////////
    591744
    592 ///////////////////////////////////////////
    593 void fatfs_ctx_display( fatfs_ctx_t * ctx )
    594 {
    595     printk("\n*** FAT context ***\n"
     745///////////////////////////////////
     746void fatfs_display_ctx( cxy_t cxy )
     747{
     748    // get pointer on local FATFS context
     749    vfs_ctx_t   * vfs_ctx = &fs_context[FS_TYPE_FATFS];
     750        fatfs_ctx_t * ctx     = hal_remote_lpt( XPTR( cxy , &vfs_ctx->extend ) );
     751
     752    uint32_t fat_sectors       = hal_remote_l32( XPTR( cxy , &ctx->fat_sectors_count ) );
     753    uint32_t sector_size       = hal_remote_l32( XPTR( cxy , &ctx->bytes_per_sector ) );
     754    uint32_t sec_per_clus      = hal_remote_l32( XPTR( cxy , &ctx->sectors_per_cluster ) );
     755    uint32_t fat_lba           = hal_remote_l32( XPTR( cxy , &ctx->fat_begin_lba ) );
     756    uint32_t data_lba          = hal_remote_l32( XPTR( cxy , &ctx->cluster_begin_lba ) );
     757    uint32_t fsinfo_lba        = hal_remote_l32( XPTR( cxy , &ctx->fs_info_lba ) );
     758    uint32_t root_dir_clus     = hal_remote_l32( XPTR( cxy , &ctx->root_dir_cluster ) );
     759    uint32_t free_clusters     = hal_remote_l32( XPTR( cxy , &ctx->free_clusters ) );
     760    uint32_t free_cluster_hint = hal_remote_l32( XPTR( cxy , &ctx->free_cluster_hint ) );
     761    xptr_t   mapper_xp         = hal_remote_l64( XPTR( cxy , &ctx->fat_mapper_xp ) );
     762    void   * fs_info_buffer    = hal_remote_lpt( XPTR( cxy , &ctx->fs_info_buffer ) );
     763
     764    printk("\n*** FAT context in cluster %x\n"
    596765           "- fat_sectors       = %d\n"
    597766           "- sector size       = %d\n"
    598767           "- cluster size      = %d\n"
    599            "- fat_first_lba     = %d\n"
    600            "- data_first_lba    = %d\n"
    601            "- root_dir_cluster  = %d\n"
    602            "- free_clusters     = %d\n"
    603            "- free_cluster_hint = %d\n"
    604            "- fat_mapper_xp     = %l\n",
    605            ctx->fat_sectors_count,
    606            ctx->bytes_per_sector,
    607            ctx->sectors_per_cluster * ctx->bytes_per_sector,
    608            ctx->fat_begin_lba,
    609            ctx->cluster_begin_lba,
    610            ctx->root_dir_cluster,
    611            ctx->free_clusters,
    612            ctx->free_cluster_hint,
    613            ctx->fat_mapper_xp );
    614 
    615 }  // end ctx_display()
     768           "- fat_lba           = %x\n"
     769           "- data_lba          = %x\n"
     770           "- fsinfo_lba        = %x\n"
     771           "- root_dir_cluster  = %x\n"
     772           "- free_clusters     = %x\n"
     773           "- free_cluster_hint = %x\n"
     774           "- fat_mapper_ptr    = %x\n"
     775           "- fs_info_buffer    = %x\n",
     776           cxy,
     777           fat_sectors,
     778           sector_size,
     779           sector_size * sec_per_clus,
     780           fat_lba,
     781           data_lba,
     782           fsinfo_lba,
     783           root_dir_clus,
     784           free_clusters,
     785           free_cluster_hint,
     786           GET_PTR( mapper_xp ),
     787           fs_info_buffer );
     788
     789}  // end fatfs_ctx_display()
    616790
    617791//////////////////////////////////////////
     
    622796    uint32_t maxline;
    623797
    624     // copute numner of lines to display
     798    // compute number of lines to display
    625799    maxline = nentries >> 3;
    626800    if( nentries & 0x7 ) maxline++;
    627801
    628802    // get pointer on local FATFS context
    629     vfs_ctx_t   * vfs_ctx   = &fs_context[FS_TYPE_FATFS];
    630     fatfs_ctx_t * fatfs_ctx = (fatfs_ctx_t *)vfs_ctx->extend;
     803    vfs_ctx_t   * vfs_ctx       = &fs_context[FS_TYPE_FATFS];
     804    fatfs_ctx_t * loc_fatfs_ctx = (fatfs_ctx_t *)vfs_ctx->extend;
    631805
    632806    // get extended pointer on FAT mapper
    633     xptr_t fat_mapper_xp = fatfs_ctx->fat_mapper_xp;
    634 
    635     // get extended pointer and cluster of FAT mapper requested page
     807    xptr_t fat_mapper_xp  = loc_fatfs_ctx->fat_mapper_xp;
     808
     809    // get FAT cluster identifier
     810    cxy_t  fat_cxy = GET_CXY( fat_mapper_xp );
     811
     812    // get pointer on FATFS context in FAT cluster
     813    fatfs_ctx_t * fat_fatfs_ctx = hal_remote_lpt( XPTR( fat_cxy , &vfs_ctx->extend ) );
     814 
     815    // get current value of hint and free_clusters
     816    uint32_t hint = hal_remote_l32( XPTR( fat_cxy , &fat_fatfs_ctx->free_cluster_hint ) );
     817    uint32_t free = hal_remote_l32( XPTR( fat_cxy , &fat_fatfs_ctx->free_clusters ) );
     818 
     819    // get extended pointer on requested page in FAT mapper
    636820    xptr_t     page_xp  = mapper_remote_get_page( fat_mapper_xp , page_id );
    637821
    638822    // get extended pointer on requested page base
    639823    xptr_t     base_xp  = ppm_page2base( page_xp );
    640 
    641     printk("\n***** FAT content / page %d *****\n", page_id );
     824    void     * base     = GET_PTR( base_xp );
     825
     826    printk("\n***** FAT mapper / cxy %x / page_id %d / base %x / free_clusters %x / hint %x\n",
     827    fat_cxy, page_id, base, free, hint );
     828
    642829    for( line = 0 ; line < maxline ; line++ )
    643830    {
     
    766953    kmem_req_t    req;
    767954    uint8_t     * buffer;
     955    xptr_t        buffer_xp;
    768956
    769957#if DEBUG_FATFS_CTX_INIT
     
    778966assert( (fatfs_ctx != NULL) , "pointer on FATFS context is NULL" );
    779967
    780 // check only cluster 0 does FATFS init
     968// check only cluster 0 does FATFS initialization
    781969assert( (local_cxy == 0) , "only cluster 0 can initialize FATFS");
    782970
    783     // allocate a 512 bytes buffer to store the boot record
     971    // allocate a permanent 512 bytes buffer to store
     972    // - temporarily the BOOT sector
     973    // - permanently the FS_INFO sector
    784974        req.type    = KMEM_512_BYTES;
    785975    req.flags   = AF_KERNEL | AF_ZERO;
    786976        buffer      = (uint8_t *)kmem_alloc( &req );
     977    buffer_xp   = XPTR( local_cxy , buffer );
    787978
    788979    if( buffer == NULL )
     
    793984     
    794985    // load the BOOT record from device
    795     error = dev_ioc_sync_read( buffer , 0 , 1 );
     986    error = dev_ioc_sync_read( buffer_xp , 0 , 1 );
    796987
    797988    if ( error )
     
    807998
    808999    // get sector size from boot record
    809     uint32_t sector_size = fatfs_get_record( BPB_BYTSPERSEC , buffer , 1 );
     1000    uint32_t sector_size = fatfs_get_record( BPB_BYTSPERSEC , buffer );
    8101001    if ( sector_size != 512 )
    8111002    {
     
    8151006
    8161007    // get cluster size from boot record
    817     uint32_t nb_sectors = fatfs_get_record( BPB_SECPERCLUS , buffer , 1 );
     1008    uint32_t nb_sectors = fatfs_get_record( BPB_SECPERCLUS , buffer );
    8181009    if ( nb_sectors != 8 )
    8191010    {
     
    8231014
    8241015    // get number of FAT copies from boot record
    825     uint32_t nb_fats = fatfs_get_record( BPB_NUMFATS , buffer , 1 );
     1016    uint32_t nb_fats = fatfs_get_record( BPB_NUMFATS , buffer );
    8261017    if ( nb_fats != 1 )
    8271018    {
     
    8311022
    8321023    // get number of sectors in FAT from boot record
    833     uint32_t fat_sectors = fatfs_get_record( BPB_FAT32_FATSZ32 , buffer , 1 );
     1024    uint32_t fat_sectors = fatfs_get_record( BPB_FAT32_FATSZ32 , buffer );
    8341025    if ( (fat_sectors & 0xF) != 0 )
    8351026    {
     
    8391030
    8401031    // get root cluster from boot record
    841     uint32_t root_cluster = fatfs_get_record( BPB_FAT32_ROOTCLUS , buffer , 1 );
     1032    uint32_t root_cluster = fatfs_get_record( BPB_FAT32_ROOTCLUS , buffer );
    8421033    if ( root_cluster != 2 )
    8431034    {
     
    8471038
    8481039    // get FAT lba from boot record
    849     uint32_t fat_lba = fatfs_get_record( BPB_RSVDSECCNT , buffer , 1 );
     1040    uint32_t fat_lba = fatfs_get_record( BPB_RSVDSECCNT , buffer );
    8501041
    8511042    // get FS_INFO sector lba from boot record
    852     uint32_t fs_info_lba = fatfs_get_record( BPB_FAT32_FSINFO , buffer , 1 );
     1043    uint32_t fs_info_lba = fatfs_get_record( BPB_FAT32_FSINFO , buffer );
    8531044
    8541045    // load the FS_INFO record from device
    855     error = dev_ioc_sync_read( buffer , fs_info_lba , 1 );
     1046    error = dev_ioc_sync_read( buffer_xp , fs_info_lba , 1 );
    8561047
    8571048    if ( error )
     
    8611052    }
    8621053
    863     // get free clusters number from FS_INFO record
    864     uint32_t free_clusters = fatfs_get_record( FS_FREE_CLUSTERS , buffer , 1 );
     1054    // get free_clusters number from FS_INFO record
     1055    uint32_t free_clusters = fatfs_get_record( FS_FREE_CLUSTERS , buffer );
    8651056    if ( free_clusters >= fat_sectors << 7 )
    8661057    {
     
    8691060    }
    8701061
    871     // get cluster hint from FS_INFO record
    872     uint32_t free_cluster_hint = fatfs_get_record( FS_FREE_CLUSTER_HINT , buffer , 1 );
     1062    // get free_cluster_hint from FS_INFO record
     1063    uint32_t free_cluster_hint = fatfs_get_record( FS_FREE_CLUSTER_HINT , buffer );
     1064
    8731065    if ( free_cluster_hint >= fat_sectors << 7 )
    8741066    {
     
    8761068        hal_core_sleep();
    8771069    }
    878 
    879     // release the 512 bytes buffer
    880     req.type = KMEM_512_BYTES;
    881     req.ptr  = buffer;
    882     kmem_free( &req );
    8831070
    8841071    // allocate a mapper for the FAT itself
     
    8901077    }
    8911078
    892     // WARNING : the inode field MUST be NULL for the FAT mapper
     1079    // the inode field is NULL for the FAT mapper
    8931080    fat_mapper->inode = NULL;
    894 
    8951081
    8961082    // initialize the FATFS context
     
    9021088    fatfs_ctx->root_dir_cluster      = 2;
    9031089    fatfs_ctx->fat_mapper_xp         = XPTR( local_cxy , fat_mapper );
     1090    fatfs_ctx->fs_info_lba           = fs_info_lba;
    9041091    fatfs_ctx->free_clusters         = free_clusters;
    9051092    fatfs_ctx->free_cluster_hint     = free_cluster_hint;
     1093    fatfs_ctx->fs_info_buffer        = buffer;
    9061094
    9071095    remote_queuelock_init( XPTR( local_cxy , &fatfs_ctx->free_lock ) , LOCK_FATFS_FREE );
     
    10191207        while ( (offset < 4096) && (found == 0) )
    10201208        {
    1021             if ( fatfs_get_record( LDIR_ORD, (base + offset), 0 ) == NO_MORE_ENTRY )
     1209            if ( fatfs_get_record( LDIR_ORD, (base + offset) ) == NO_MORE_ENTRY )
    10221210            {
    10231211                found = 1;
     
    13351523
    13361524// check for LFN entry
    1337 assert( (fatfs_get_record( DIR_ATTR, base + offset, 0 ) == ATTR_LONG_NAME_MASK ),
     1525assert( (fatfs_get_record( DIR_ATTR, base + offset ) == ATTR_LONG_NAME_MASK ),
    13381526"this directory entry must be a LFN\n");
    13391527
     
    14391627        while( (offset < 4096) && (found == 0) )
    14401628        {
    1441             attr = fatfs_get_record( DIR_ATTR , base + offset , 0 );   
    1442             ord  = fatfs_get_record( LDIR_ORD , base + offset , 0 );   
     1629            attr = fatfs_get_record( DIR_ATTR , base + offset );   
     1630            ord  = fatfs_get_record( LDIR_ORD , base + offset );   
    14431631
    14441632            if (ord == NO_MORE_ENTRY)                 // no more entry => break
     
    15591747
    15601748// check arguments
    1561 assert( (parent_inode != NULL)         , "parent_inode is NULL\n" );
    1562 assert( (name         != NULL)         , "name is NULL\n" );
    1563 assert( (child_inode_xp != XPTR_NULL ) , "child_inode is XPTR_NULL\n" );
     1749assert( (parent_inode   != NULL)       , "parent_inode is NULL\n" );
     1750assert( (name           != NULL)       , "name is NULL\n" );
     1751assert( (child_inode_xp != XPTR_NULL ) , "child_inode is NULL\n" );
     1752
     1753    // get child inode cluster and local pointer
     1754    child_inode_cxy = GET_CXY( child_inode_xp );
     1755    child_inode_ptr = GET_PTR( child_inode_xp );
     1756
     1757    // build extended pointer on root of list of parent dentries
     1758    root_xp = XPTR( child_inode_cxy , &child_inode_ptr->parents );
     1759
     1760// check child inode has at least one parent
     1761assert( (xlist_is_empty( root_xp ) == false ), "child inode must have one parent\n");
    15641762
    15651763#if DEBUG_FATFS_GET_DENTRY
     
    15781776    error  = fatfs_scan_directory( mapper, name , &entry , &index );
    15791777
    1580     if( error )
    1581     {
    1582         vfs_inode_get_name( XPTR( local_cxy , parent_inode ) , dir_name );
    1583         printk("\n[ERROR] in %s : cannot find <%s> in parent mapper <%s>\n",
    1584         __FUNCTION__, name , dir_name );
    1585         return -1;
    1586     }
     1778    // return non fatal error if not found
     1779    if( error ) return -1;
    15871780
    15881781    // get relevant infos from FAT32 directory entry
    1589     cluster = (fatfs_get_record( DIR_FST_CLUS_HI , entry , 1 ) << 16) |
    1590               (fatfs_get_record( DIR_FST_CLUS_LO , entry , 1 )      ) ;
    1591     is_dir  = (fatfs_get_record( DIR_ATTR        , entry , 1 ) & ATTR_DIRECTORY);
    1592     size    =  fatfs_get_record( DIR_FILE_SIZE   , entry , 1 );
    1593 
    1594     // get child inode cluster and local pointer
    1595     child_inode_cxy = GET_CXY( child_inode_xp );
    1596     child_inode_ptr = GET_PTR( child_inode_xp );
    1597 
    1598     // build extended pointer on root of list of parent dentries
    1599     root_xp = XPTR( child_inode_cxy , &child_inode_ptr->parents );
    1600 
    1601 // check child inode has at least one parent
    1602 assert( (xlist_is_empty( root_xp ) == false ), "child inode must have one parent\n");
     1782    cluster = (fatfs_get_record( DIR_FST_CLUS_HI , entry ) << 16) |
     1783              (fatfs_get_record( DIR_FST_CLUS_LO , entry )      ) ;
     1784    is_dir  = (fatfs_get_record( DIR_ATTR        , entry ) & ATTR_DIRECTORY);
     1785    size    =  fatfs_get_record( DIR_FILE_SIZE   , entry );
    16031786
    16041787    // scan list of parent dentries to search the parent_inode
     
    16921875
    16931876    // set size in FAT32 directory entry
    1694     fatfs_set_record( DIR_FILE_SIZE , entry , 1 , size );
     1877    fatfs_set_record( DIR_FILE_SIZE , entry , size );
    16951878
    16961879    // get local pointer on modified page base
     
    17951978            bool_t valid = (dentry_id >= min_dentry) && (dirent_id <  max_dirent );
    17961979
    1797             attr = fatfs_get_record( DIR_ATTR , base + offset , 0 );   
    1798             ord  = fatfs_get_record( LDIR_ORD , base + offset , 0 );   
     1980            attr = fatfs_get_record( DIR_ATTR , base + offset );   
     1981            ord  = fatfs_get_record( LDIR_ORD , base + offset );   
    17991982
    18001983            if (ord == NO_MORE_ENTRY)                 // no more entry => break
     
    20332216error_t fatfs_sync_free_info( void )
    20342217{
     2218    error_t       error;
     2219    fatfs_ctx_t * fatfs_ctx_ptr;              // local pointer on fatfs context in cluster 0
     2220    uint32_t      ctx_free_clusters;          // number of free clusters from fatfs context
     2221    uint32_t      ctx_free_cluster_hint;      // free cluster hint from fatfs context
     2222    uint32_t      ioc_free_clusters;          // number of free clusters from fatfs context
     2223    uint32_t      ioc_free_cluster_hint;      // free cluster hint from fatfs context
     2224    uint32_t      fs_info_lba;                // lba of FS_INFO sector on IOC device
     2225    uint8_t     * fs_info_buffer;             // local pointer on FS_INFO buffer in cluster 0
     2226    xptr_t        fs_info_buffer_xp;          // extended pointer on FS_INFO buffer in cluster 0
     2227    uint8_t       tmp_buf[512];               // 512 bytes temporary buffer
     2228    xptr_t        tmp_buf_xp;                 // extended pointer on temporary buffer
    20352229
    20362230#if DEBUG_FATFS_SYNC_FSINFO
     
    20422236#endif
    20432237
    2044     uint8_t     * buffer;   // dynamically allocated aligned 512 bytes buffer
    2045     kmem_req_t    req;
    2046     error_t       error;
    2047 
    2048     // get FS_INFO lba, free_ from FATFS context
    2049     fatfs_ctx_t * fatfs_ctx  = fs_context[FS_TYPE_FATFS].extend;
    2050     uint32_t      lba        = fatfs_ctx->fs_info_lba;
    2051     uint32_t      hint       = fatfs_ctx->free_cluster_hint;
    2052     uint32_t      number     = fatfs_ctx->free_clusters;
    2053 
    2054     // allocate buffer to store the FS_INFO sector
    2055         req.type    = KMEM_512_BYTES;
    2056     req.flags   = AF_KERNEL | AF_ZERO;
    2057         buffer      = (uint8_t *)kmem_alloc( &req );
    2058     if( buffer == NULL )
    2059     {
    2060         printk("\n[PANIC] in %s : cannot allocate buffer\n", __FUNCTION__ );
    2061         return ENOMEM;
    2062     }
    2063      
    2064     // load the FS_INFO sector from device to buffer
    2065     error = dev_ioc_read( buffer , lba , 1 );
     2238    // get pointer on fatfs context in cluster 0
     2239    fatfs_ctx_ptr = hal_remote_lpt( XPTR( 0 , &fs_context[FS_TYPE_FATFS].extend ) );
     2240
     2241    // get "free_clusters" and "free_cluster_hint" from fatfs context in cluster 0
     2242    ctx_free_clusters     = hal_remote_l32( XPTR( 0 , &fatfs_ctx_ptr->free_clusters ) );
     2243    ctx_free_cluster_hint = hal_remote_l32( XPTR( 0 , &fatfs_ctx_ptr->free_cluster_hint ) );
     2244
     2245    // get fs_info_lba
     2246    fs_info_lba = hal_remote_l32( XPTR( 0 , &fatfs_ctx_ptr->fs_info_lba ) );
     2247
     2248    // build extended pointer on temporary buffer
     2249    tmp_buf_xp = XPTR( local_cxy , tmp_buf );
     2250
     2251    // copy FS_INFO sector from IOC to local buffer
     2252    error = dev_ioc_sync_read( tmp_buf_xp , fs_info_lba , 1 );
     2253
    20662254    if ( error )
    20672255    {
    2068         printk("\n[PANIC] in %s : cannot read FS_INFO record\n", __FUNCTION__ );
    2069         return EIO;
    2070     }
    2071 
    2072     // update buffer
    2073     fatfs_set_record( FS_FREE_CLUSTERS     , buffer , 1 , number );
    2074     fatfs_set_record( FS_FREE_CLUSTER_HINT , buffer , 1 , hint );
    2075 
    2076     // write modified FS_INFO sector from buffer to device
    2077     error = dev_ioc_write( buffer , lba , 1 );
    2078     if ( error )
    2079     {
    2080         printk("\n[PANIC] in %s : cannot write FS_INFO record\n", __FUNCTION__ );
    2081         return EIO;
    2082     }
    2083 
    2084     // release the 512 bytes buffer
    2085     req.type = KMEM_512_BYTES;
    2086     req.ptr  = buffer;
    2087     kmem_free( &req );
     2256        printk("\n[ERROR] in %s : cannot access FS_INFO on IOC device\n", __FUNCTION__ );
     2257        return -1;
     2258    }
     2259
     2260    // get current values of "free_clusters" and "free_cluster_hint" from FS_INFO on IOC
     2261    ioc_free_clusters     = fatfs_get_remote_record( FS_FREE_CLUSTERS     , tmp_buf_xp );
     2262    ioc_free_cluster_hint = fatfs_get_remote_record( FS_FREE_CLUSTER_HINT , tmp_buf_xp );
     2263
     2264    // check values
     2265    if( (ioc_free_clusters     != ctx_free_clusters) ||
     2266        (ioc_free_cluster_hint != ctx_free_cluster_hint) )
     2267    {
     2268        printk("\n[WARNING] in %s : unconsistent free clusters info\n"
     2269        " ioc_free %x / ctx_free %x / ioc_hint %x / ctx_hint %x\n",
     2270        __FUNCTION__, ioc_free_clusters, ctx_free_clusters,
     2271        ioc_free_cluster_hint, ctx_free_cluster_hint );
     2272
     2273        // get pointers on FS_INFO buffer in cluster 0
     2274        fs_info_buffer    = hal_remote_lpt( XPTR( 0 , &fatfs_ctx_ptr->fs_info_buffer ) );
     2275        fs_info_buffer_xp = XPTR( 0 , fs_info_buffer );
     2276
     2277        // update FS_INFO buffer in cluster 0
     2278        fatfs_set_remote_record(FS_FREE_CLUSTERS    ,fs_info_buffer_xp,ctx_free_clusters );
     2279        fatfs_set_remote_record(FS_FREE_CLUSTER_HINT,fs_info_buffer_xp,ctx_free_cluster_hint);
     2280
     2281        // update the FS_INFO sector on IOC device
     2282        error = dev_ioc_sync_write( fs_info_buffer_xp , fs_info_lba , 1 );
     2283
     2284        if ( error )
     2285        {
     2286            printk("\n[ERROR] in %s : cannot update FS_INFO on IOC device\n", __FUNCTION__ );
     2287            return -1;
     2288        }
     2289    }
    20882290
    20892291#if DEBUG_FATFS_SYNC_FSINFO
     
    20962298    return 0;
    20972299
    2098 }  // end fatfs_sync_fs_info()
     2300}  // end fatfs_sync_free_info()
    20992301
    21002302//////////////////////////////////////////////////////////
    21012303error_t fatfs_cluster_alloc( uint32_t * searched_cluster )
    21022304{
     2305    error_t       error;
    21032306    uint32_t      page_id;        // page index in FAT mapper
    21042307    uint32_t      slot_id;        // slot index in page (1024 slots per page)
     
    21092312    fatfs_ctx_t * fat_fatfs_ctx;  // local pointer on FATFS context in FAT cluster
    21102313    xptr_t        mapper_xp;      // extended pointer on FAT mapper
    2111     cxy_t         mapper_cxy;     // Fat mapper cluster identifier
     2314    cxy_t         fat_cxy;        // Fat mapper cluster identifier
    21122315    xptr_t        page_xp;        // extended pointer on current page descriptor in mapper
    21132316    xptr_t        slot_xp;        // extended pointer on FAT slot defined by hint
    21142317    xptr_t        lock_xp;        // extended pointer on lock protecting free clusters info
    21152318    xptr_t        hint_xp;        // extended pointer on free_cluster_hint in FAT cluster
    2116     xptr_t        numb_xp;        // extended pointer on free_clusters_number in FAT cluster
     2319    xptr_t        free_xp;        // extended pointer on free_clusters_number in FAT cluster
    21172320
    21182321#if DEBUG_FATFS_CLUSTER_ALLOC
     
    21302333    loc_fatfs_ctx = vfs_ctx->extend;
    21312334
    2132     // get extended pointer and cluster on FAT mapper
     2335    // get extended pointer on FAT mapper
    21332336    mapper_xp  = loc_fatfs_ctx->fat_mapper_xp;
    2134     mapper_cxy = GET_CXY( mapper_xp );
     2337
     2338    // get FAT cluster
     2339    fat_cxy = GET_CXY( mapper_xp );
    21352340   
    21362341    // get local pointer on FATFS context in FAT cluster
    2137     fat_fatfs_ctx = hal_remote_lpt( XPTR( mapper_cxy , &vfs_ctx->extend ) );
     2342    fat_fatfs_ctx = hal_remote_lpt( XPTR( fat_cxy , &vfs_ctx->extend ) );
    21382343
    21392344    // build relevant extended pointers on free clusters info in mapper cluster
    2140     lock_xp = XPTR( mapper_cxy , &fat_fatfs_ctx->free_lock );
    2141     hint_xp = XPTR( mapper_cxy , &fat_fatfs_ctx->free_cluster_hint );
    2142     numb_xp = XPTR( mapper_cxy , &fat_fatfs_ctx->free_clusters );
     2345    lock_xp = XPTR( fat_cxy , &fat_fatfs_ctx->free_lock );
     2346    hint_xp = XPTR( fat_cxy , &fat_fatfs_ctx->free_cluster_hint );
     2347    free_xp = XPTR( fat_cxy , &fat_fatfs_ctx->free_clusters );
    21432348
    21442349    // take the lock protecting free clusters
    21452350    remote_queuelock_acquire( lock_xp );
    21462351
    2147     // get hint and free_clusters values from FATFS context
     2352    // get hint and free_clusters values from FATFS context in FAT cluster
    21482353    cluster       = hal_remote_l32( hint_xp ) + 1;
    2149     free_clusters = hal_remote_l32( numb_xp );
     2354    free_clusters = hal_remote_l32( free_xp );
    21502355       
    21512356#if (DEBUG_FATFS_CLUSTER_ALLOC & 1)
     
    21682373    }
    21692374
    2170 
    2171 
    21722375    // get page index & slot index for selected cluster
    21732376    page_id  = cluster >> 10;
    21742377    slot_id  = cluster & 0x3FF;
    21752378
    2176     // get relevant page descriptor from mapper
     2379    // get relevant page descriptor from FAT mapper
    21772380    page_xp = mapper_remote_get_page( mapper_xp , page_id );
    21782381
     
    21942397    }
    21952398
    2196     // update free cluster info in FATFS context
    2197     fatfs_free_clusters_decrement( mapper_cxy , fat_fatfs_ctx , cluster );
     2399    // update free cluster info in FATFS context and in FS_INFO sector
     2400    error = fatfs_free_clusters_decrement( XPTR( fat_cxy , fat_fatfs_ctx ) , cluster );
     2401
     2402    if( error )
     2403    {
     2404        printk("\n[ERROR] in %s : cannot update free cluster info\n", __FUNCTION__ );
     2405        remote_queuelock_acquire( lock_xp );
     2406        return -1;
     2407    }
     2408
     2409    // update FAT mapper
     2410    hal_remote_s32( slot_xp , END_OF_CHAIN_CLUSTER_MAX );
     2411
     2412    // synchronously update FAT on device
     2413    error = fatfs_move_page( page_xp , IOC_SYNC_WRITE );
     2414
     2415    if( error )
     2416    {
     2417        printk("\n[ERROR] in %s : cannot update FAT on IOC device\n", __FUNCTION__ );
     2418        remote_queuelock_acquire( lock_xp );
     2419        return -1;
     2420    }
    21982421
    21992422    // release free clusters busylock
    22002423    remote_queuelock_release( lock_xp );
    2201 
    2202     // update FAT mapper
    2203     hal_remote_s32( slot_xp , END_OF_CHAIN_CLUSTER_MAX );
    2204 
    2205     // synchronously update FAT on device
    2206     fatfs_move_page( page_xp , IOC_SYNC_WRITE );
    22072424
    22082425#if DEBUG_FATFS_CLUSTER_ALLOC
    22092426cycle = (uint32_t)hal_get_cycles();
    22102427if( DEBUG_FATFS_CLUSTER_ALLOC < cycle )
    2211 printk("\n[%s] thread[%x,%x] exit / updated cluster %x in FAT / cycle %d\n",
     2428printk("\n[%s] thread[%x,%x] exit / allocated cluster %x in FAT / cycle %d\n",
    22122429__FUNCTION__, this->process->pid, this->trdid, cluster, cycle );
    22132430#endif
     
    22302447    xptr_t        first_xp;       // extended pointer on inode extension
    22312448    uint32_t      first_cluster;  // first cluster index for released inode
    2232     vfs_inode_t * inode_ptr;
    2233     cxy_t         inode_cxy;
     2449    vfs_inode_t * inode_ptr;      // local pointer on target inode
     2450    cxy_t         inode_cxy;      // target inode cluster identifier
    22342451
    22352452// check inode pointer
     
    23572574
    23582575    // get page base address
    2359     xptr_t    base_xp = ppm_page2base( page_xp );
    2360     uint8_t * buffer  = (uint8_t *)GET_PTR( base_xp );
     2576    xptr_t    buffer_xp = ppm_page2base( page_xp );
     2577    uint8_t * buffer_ptr = (uint8_t *)GET_PTR( buffer_xp );
    23612578 
    23622579    // get inode pointer from mapper
    23632580    inode_ptr  = hal_remote_lpt( XPTR( page_cxy , &mapper_ptr->inode ) );
    23642581
    2365     ////////////////////////////// it is the FAT mapper
     2582#if DEBUG_FATFS_MOVE_PAGE
     2583if( DEBUG_FATFS_MOVE_PAGE < cycle )
     2584printk("\n[%s] thread[%x,%x] enters : %s / cxy %x / mapper %x / inode %x / page %x\n",
     2585__FUNCTION__, this->process->pid, this->trdid,
     2586dev_ioc_cmd_str( cmd_type ), page_cxy, mapper_ptr, inode_ptr, buffer_ptr );
     2587#endif
     2588
     2589    //////////////////////////////  FAT mapper
    23662590    if( inode_ptr == NULL )
    23672591    {
     
    23702594 
    23712595        // access device
    2372         if     ( cmd_type == IOC_SYNC_READ  ) error = dev_ioc_sync_read ( buffer , lba , 8 );
    2373         else if( cmd_type == IOC_SYNC_WRITE ) error = dev_ioc_sync_write( buffer , lba , 8 );
    2374         else if( cmd_type == IOC_READ       ) error = dev_ioc_read      ( buffer , lba , 8 );
    2375         else if( cmd_type == IOC_WRITE      ) error = dev_ioc_write     ( buffer , lba , 8 );
    2376         else                                  error = -1;
    2377 
    2378         if( error ) return EIO;
     2596        if     (cmd_type == IOC_SYNC_READ ) error = dev_ioc_sync_read ( buffer_xp  , lba , 8 );
     2597        else if(cmd_type == IOC_SYNC_WRITE) error = dev_ioc_sync_write( buffer_xp  , lba , 8 );
     2598        else if(cmd_type == IOC_READ      ) error = dev_ioc_read      ( buffer_ptr , lba , 8 );
     2599        else if(cmd_type == IOC_WRITE     ) error = dev_ioc_write     ( buffer_ptr , lba , 8 );
     2600        else                                error = -1;
     2601
     2602        if( error )
     2603        {
     2604            printk("\n[ERROR] in %s : cannot access device\n", __FUNCTION__ );
     2605            return -1;
     2606        }
    23792607
    23802608#if DEBUG_FATFS_MOVE_PAGE
     
    23822610{
    23832611    if ( (cmd_type == IOC_READ) || (cmd_type == IOC_SYNC_READ) )
    2384          printk("\n[%s] thread[%x,%x] load page %d of FAT / cycle %d\n",
    2385          __FUNCTION__, this->process->pid, this->trdid, page_id, cycle );
     2612        printk("\n[%s] thread[%x,%x] load FAT mapper page %d from IOC / cycle %d\n",
     2613        __FUNCTION__, this->process->pid, this->trdid, page_id, cycle );
    23862614    else
    2387         printk("\n[%s] thread[%x,%x] sync page %d of FAT / cycle %d\n",
     2615        printk("\n[%s] thread[%x,%x] sync FAT mapper page %d to IOC / cycle %d\n",
    23882616        __FUNCTION__, this->process->pid, this->trdid, page_id, cycle );
    23892617}
     
    23912619
    23922620    }
    2393     ///////////////////////// it is an inode mapper
     2621    ///////////////////////// inode mapper
    23942622    else                       
    23952623    {
     
    24252653        }
    24262654
    2427         // get lba from searched_cluster
     2655        // get lba for searched_cluster
    24282656        uint32_t lba = fatfs_lba_from_cluster( fatfs_ctx , searched_cluster );
     2657
     2658        // access device
     2659        if     (cmd_type == IOC_SYNC_READ ) error = dev_ioc_sync_read ( buffer_xp  , lba , 8 );
     2660        else if(cmd_type == IOC_SYNC_WRITE) error = dev_ioc_sync_write( buffer_xp  , lba , 8 );
     2661        else if(cmd_type == IOC_READ      ) error = dev_ioc_read      ( buffer_ptr , lba , 8 );
     2662        else if(cmd_type == IOC_WRITE     ) error = dev_ioc_write     ( buffer_ptr , lba , 8 );
     2663        else                                error = -1;
     2664
     2665        if( error )
     2666        {
     2667            printk("\n[ERROR] in %s : cannot access device\n", __FUNCTION__ );
     2668            return -1;
     2669        }
    24292670
    24302671#if DEBUG_FATFS_MOVE_PAGE
     
    24402681#endif
    24412682
    2442         // access device
    2443         if     ( cmd_type == IOC_SYNC_READ  ) error = dev_ioc_sync_read ( buffer , lba , 8 );
    2444         else if( cmd_type == IOC_SYNC_WRITE ) error = dev_ioc_sync_write( buffer , lba , 8 );
    2445         else if( cmd_type == IOC_READ       ) error = dev_ioc_read      ( buffer , lba , 8 );
    2446         else if( cmd_type == IOC_WRITE      ) error = dev_ioc_write     ( buffer , lba , 8 );
    2447         else                                  error = -1;
    2448 
    2449         if( error )
    2450         {
    2451             printk("\n[ERROR] in %s : cannot access device\n", __FUNCTION__ );
    2452             return -1;
    2453         }
    24542683    }
    24552684
  • trunk/kernel/fs/fatfs.h

    r625 r626  
    173173/*****************************************************************************************
    174174 * This structure defines a FATFS specific context (extension to VFS context).
    175  * This extension is replicated in all clusters.
    176  *
    177  * WARNING : Almost all fields are constant values, but the <free_cluster_hint> and
    178  * <free_clusters> are shared variables. All kernel instances use the variables
    179  * in cluster 0, using the <free_lock> remote busy_lock for exclusive access.
     175 * This fatfs context is replicated in all clusters.
     176 *
     177 * WARNING : Almost all fields are constant values, but the <free_cluster_hint>,
     178 * <free_clusters> and <free_lock> are shared variables. Moreover, the <fs_info_buffer>,
     179 * only allocated in cluster 0, contains a copy of the FS_INFO sector. It is used by all
     180 * kernel instances to synchronously update the free clusters info on IOC device.
     181 * For these four variables, all kernel instances must use the values in cluster 0,
     182 * and take the <free_lock> stored in this cluster for exclusive access to FAT.
    180183 ****************************************************************************************/
    181184
    182185typedef struct fatfs_ctx_s
    183186{
     187    /* read-only constants replicated in all clusters                                   */
    184188    uint32_t            fat_sectors_count;     /*! number of sectors in FAT region      */
    185189    uint32_t            bytes_per_sector;      /*! number of bytes per sector           */
     
    190194    uint32_t            root_dir_cluster;      /*! cluster index for  root directory    */
    191195    xptr_t              fat_mapper_xp;         /*! extended pointer on FAT mapper       */
     196
     197    /* shared variables (only the copy in FAT cluster must be used)                     */
    192198    uint32_t            free_cluster_hint;     /*! cluster[hint+1] is the first free    */
    193199    uint32_t            free_clusters;         /*! free clusters number                 */
    194     remote_queuelock_t  free_lock;             /*! exclusive access to hint & number    */
     200    remote_queuelock_t  free_lock;             /*! exclusive access to FAT              */
     201    uint8_t           * fs_info_buffer;        /*! local pointer on FS_INFO buffer      */
    195202}
    196203fatfs_ctx_t;
     
    224231
    225232/*****************************************************************************************
    226  * This function display the content of the local FATFS context.
    227  *****************************************************************************************
    228  * @ ctx  : local pointer on the context.
    229  ****************************************************************************************/
    230 void fatfs_ctx_display( fatfs_ctx_t * ctx );
    231 
    232 /*****************************************************************************************
    233  * This function displays the content of a part of the File Allocation Table.
    234  * It loads the requested page fom device to mapper if required.
    235  *****************************************************************************************
    236  * @ page_id   : page index in FAT mapper (one page is 4 Kbytes).
    237  * @ nentries  : number of entries (one entry is 4 bytes).
     233 * This function display the content of the FATFS context copy in cluster identified
     234 * by the <cxy> argument.
     235 * This function can be called by a thread running in any cluster.
     236 *****************************************************************************************
     237 * @ cxy       :  target cluster identifier.
     238 ****************************************************************************************/
     239void fatfs_display_ctx( cxy_t cxy );
     240
     241/*****************************************************************************************
     242 * This function access the FAT mapper to display one page of the File Allocation Table.
     243 * It loads the requested page fom IOC device to FAT mapper if required.
     244 * This function can be called by a thread running in any cluster.
     245 *****************************************************************************************
     246 * @ page_id     : page index in FAT mapper (one page is 4 Kbytes).
     247 * @ nb_entries  : number of entries (one entry is 4 bytes).
    238248 ****************************************************************************************/
    239249void fatfs_display_fat( uint32_t  page_id,
    240                         uint32_t  nentries );
     250                        uint32_t  nb_entries );
    241251
    242252
     
    254264
    255265/*****************************************************************************************
    256  * This function access the boot device, and initialises the local FATFS context
    257  * from informations contained in the boot record.
     266 * This function access the boot device, and initialises the local FATFS context,
     267 * from informations contained in the boot record. This initialisation includes the
     268 * creation of the FAT mapper in cluster 0.
    258269 *****************************************************************************************
    259270 * @ vfs_ctx   : local pointer on VFS context for FATFS.
     
    271282 * This function implements the generic vfs_fs_add_dentry() function for the FATFS.
    272283 *****************************************************************************************
    273  * This function updates a directory identified by the <inode> argument
     284 * This function updates a directory mapper identified by the <inode> argument
    274285 * to add a new directory entry identified by the <dentry> argument.
    275  * All modified pages in directory mapper are synchronously updated on IOC device.
    276  * It must be called by a thread running in the cluster containing the inode.
     286 * All modified pages in the directory mapper are synchronously updated on IOC device.
     287 * It must be called by a thread running in the cluster containing the directory inode.
    277288 *
    278289 * Implementation note : this function works in two steps:
     
    313324 * This function implements the generic vfs_fs_new_dentry() function for the FATFS.
    314325 *****************************************************************************************
    315  * It initializes a new inode/dentry couple in Inode Tree, attached to the directory
    316  * identified by the <parent_inode> argument. The directory entry is identified
    317  * by the <name> argument. The child inode descriptor, identified by the <child_inode_xp>
    318  * argument, and the associated dentry descriptor must have been previously allocated.
    319  * It scan the parent mapper to find the <name> argument.
    320  * It set the "type", "size", and "extend" fields in the child inode descriptor.
    321  * It set the " extend" field in the dentry descriptor.
     326 * It scan a parent directory mapper, identified by the <parent_inode> argument to find
     327 * a directory entry identified by the <name> argument.  In case of success, it
     328 * initializes the inode/dentry couple, identified by the  <child_inode_xp> argument
     329 * in the Inode Tree. The child inode descriptor, and the associated dentry descriptor
     330 * must have been previously allocated by the caller.
     331 * - It set the "type", "size", and "extend" fields in the child inode descriptor.
     332 * - It set the " extend" field in the dentry descriptor.
    322333 * It must be called by a thread running in the cluster containing the parent inode.
    323334 *****************************************************************************************
     
    325336 * @ name            : child name.
    326337 * @ child_inode_xp  : extended pointer on remote child inode (file or directory).
    327  * @ return 0 if success / return ENOENT if child not found.
     338 * @ return 0 if success / return -1 if child not found.
    328339 ****************************************************************************************/
    329340error_t fatfs_new_dentry( struct vfs_inode_s * parent_inode,
     
    392403 *****************************************************************************************
    393404 * @ inode   : local pointer on inode.
    394  * @ return 0 if success / return EIO if failure during device access.
     405 * @ return 0 if success / return -1 if failure during IOC device access.
    395406 ****************************************************************************************/
    396407error_t fatfs_sync_inode( struct vfs_inode_s * inode );
     
    399410 * This function implements the generic vfs_fs_sync_fat() function for the FATFS.
    400411 *****************************************************************************************
    401  * It updates the FATFS on the IOC device for the FAT itself.
     412 * It updates the FAT on the IOC device for the FAT itself.
    402413 * It scan all clusters registered in the FAT mapper, and copies from mapper to device
    403414 * each page marked as dirty.
     
    408419 *  variables defining the smallest/largest dirty page index in FAT mapper...
    409420 *****************************************************************************************
    410  * @ return 0 if success / return EIO if failure during device access.
     421 * @ return 0 if success / return -1 if failure during IOC device access.
    411422 ****************************************************************************************/
    412423error_t fatfs_sync_fat( void );
     
    415426 * This function implements the generic vfs_fs_sync_fsinfo() function for the FATFS.
    416427 *****************************************************************************************
    417  * It updates the FS_INFO sector on the IOC device.
    418  * It copies the <free_cluster_hint> and <free_clusters> variables from
    419  * the FATFS context in cluster 0 to the FS_INFO sector on device.
    420  *****************************************************************************************
    421  * @ return 0 if success / return EIO if failure during device access.
     428 * It checks the current values of the "free_clusters" and "free_cluster_hint" variables
     429 * in the FS_INFO sector on IOC, versus the values stored in the fatfs context.
     430 * As these values are synchronously updated on IOC device at each modification,
     431 * it does nothing if the values are equal. It updates the FS_INFO sector on IOC device,
     432 * and displays a warning message on TXT0 if they are not equal.
     433 * This function can be called by any thread running in any cluster.
     434 *****************************************************************************************
     435 * @ return 0 if success / return -1 if failure during IOC device access.
    422436 ****************************************************************************************/
    423437error_t fatfs_sync_free_info( void );
     
    430444 * It can be called by a thread running in any cluster, as it uses remote access
    431445 * primitives when the FAT mapper is remote. It takes the queuelock stored in the FATFS
    432  * context (located in the same cluster as the FAT mapper itself), to get exclusive
    433  * access to the FAT. It uses the <free_cluster_hint> and <free_clusters> variables
    434  * stored in this FATFS context.
     446 * context located in the same cluster as the FAT mapper itself, to get exclusive
     447 * access to the FAT. It uses and updates the <free_cluster_hint> and <free_clusters>
     448 * variables stored in this FATFS context.
    435449 * - it updates the <free_cluster_hint> and <free_clusters> variables in FATFS context.
    436450 * - it updates the FAT mapper (handling miss from IOC device if required).
     
    445459/*****************************************************************************************
    446460 * This function implements the generic vfs_fs_release_inode() function for the FATFS.
    447  *****************************************************************************************
     461  *****************************************************************************************
    448462 * It releases all clusters allocated to a file/directory identified by the <inode_xp>
    449463 * argument. All released clusters are marked FREE_CLUSTER in the FAT mapper.
     
    466480 * The pointer on the mapper and the page index in file are found in the page descriptor.
    467481 * It is used for both a regular file/directory mapper, and the FAT mapper.
    468  * For the FAT mapper, it access the FATFS to get the location on IOC device.
    469  * For a regular file, it access the FAT mapper to get the cluster index on IOC device.
     482 * - For the FAT mapper, it updates the FAT region on IOC device.
     483 * - For a regular file, it access the FAT mapper to get the cluster index on IOC device.
    470484 * It can be called by any thread running in any cluster.
    471485 *
  • trunk/kernel/fs/vfs.c

    r625 r626  
    423423}  // end vfs_inode_load_all_pages()
    424424
     425/////////////////////////////////////////
     426void vfs_inode_display( xptr_t inode_xp )
     427{
     428    assert( (inode_xp != XPTR_NULL), "inode pointer is NULL");
     429
     430    char  name[CONFIG_VFS_MAX_NAME_LENGTH];
     431
     432    vfs_inode_get_name( inode_xp , name );
     433
     434    cxy_t         inode_cxy = GET_CXY( inode_xp );
     435    vfs_inode_t * inode_ptr = GET_PTR( inode_xp );
     436
     437    vfs_inode_type_t type    = hal_remote_l32( XPTR( inode_cxy , &inode_ptr->type ) );
     438    uint32_t         attr    = hal_remote_l32( XPTR( inode_cxy , &inode_ptr->attr ) );
     439    uint32_t         size    = hal_remote_l32( XPTR( inode_cxy , &inode_ptr->size ) );
     440    uint32_t         parents = hal_remote_l32( XPTR( inode_cxy , &inode_ptr->links ) );
     441    mapper_t       * mapper  = hal_remote_lpt( XPTR( inode_cxy , &inode_ptr->mapper ) );
     442    void           * extend  = hal_remote_lpt( XPTR( inode_cxy , &inode_ptr->extend ) );
     443
     444    printk("\n**** inode <%s>\n"
     445           " - type    = %s\n"
     446           " - attr    = %x\n"
     447           " - size    = %d\n"
     448           " - parents = %d\n"
     449           " - cxy     = %x\n"
     450           " - inode   = %x\n"
     451           " - mapper  = %x\n"
     452           " - extend  = %x\n",
     453           name,
     454           vfs_inode_type_str( type ),
     455           attr,
     456           size,
     457           parents,
     458           inode_cxy,
     459           inode_ptr,
     460           mapper,
     461           extend );
     462
     463}  // end vfs_inode_display()
     464
     465
    425466////////////////////////////////////////////////////////////////////////////////////////////
    426467//          VFS dentry descriptor related functions
     
    737778cycle = (uint32_t)hal_get_cycles();
    738779if( DEBUG_VFS_OPEN < cycle )
    739 printk("\n[%s] thread[%x,%x] exit for <%s> / fdid %d / cluster %x / cycle %d\n",
     780printk("\n[%s] thread[%x,%x] exit for <%s> / fdid %d / cxy %x / cycle %d\n",
    740781__FUNCTION__, process->pid, this->trdid, path, file_id, GET_CXY( file_xp ), cycle );
    741782#endif
     
    773814// check inode type
    774815assert( (inode_type == INODE_TYPE_FILE), "bad inode type" );
     816
     817#if DEBUG_VFS_USER_MOVE
     818char          name[CONFIG_VFS_MAX_NAME_LENGTH];
     819uint32_t      cycle      = (uint32_t)hal_get_cycles();
     820thread_t    * this       = CURRENT_THREAD;
     821vfs_inode_t * inode      = hal_remote_lpt( XPTR( file_cxy , &file_ptr->inode ) );
     822vfs_inode_get_name( XPTR( file_cxy , inode ) , name );
     823if( cycle > DEBUG_VFS_USER_MOVE )
     824{
     825    if( to_buffer )
     826    printk("\n[%s] thread[%x,%x] enter / %d bytes / mapper(%s) -> buffer(%x) / cycle %d\n",
     827    __FUNCTION__ , this->process->pid, this->trdid, size, name, buffer, cycle );
     828    else           
     829    printk("\n[%s] thread[%x,%x] enter / %d bytes / buffer(%x) -> mapper(%s) / cycle %d\n",
     830    __FUNCTION__ , this->process->pid, this->trdid, size, buffer, name, cycle );
     831}
     832#endif
    775833
    776834    // get mapper pointer and file offset from file descriptor
     
    794852
    795853#if DEBUG_VFS_USER_MOVE
    796 char          name[CONFIG_VFS_MAX_NAME_LENGTH];
    797 uint32_t      cycle      = (uint32_t)hal_get_cycles();
    798 thread_t    * this       = CURRENT_THREAD;
    799 vfs_inode_t * inode      = hal_remote_lpt( XPTR( file_cxy , &file_ptr->inode ) );
    800 vfs_inode_get_name( XPTR( file_cxy , inode ) , name );
     854cycle = (uint32_t)hal_get_cycles();
    801855if( cycle > DEBUG_VFS_USER_MOVE )
    802856{
    803857    if( to_buffer )
    804     printk("\n[%s] thread[%x,%x] moves %d bytes from <%s> mapper to buffer (%x) / cycle %d\n",
    805     __FUNCTION__ , this->process->pid, this->trdid, size, name, buffer );
     858    printk("\n[%s] thread[%x,%x] exit / %d bytes / mapper(%s) -> buffer(%x) / cycle %d\n",
     859    __FUNCTION__ , this->process->pid, this->trdid, size, name, buffer, cycle );
    806860    else           
    807     printk("\n[%s] thread[%x,%x] moves %d bytes from buffer (%x) to <%s> mapper / cycle %d\n",
    808     __FUNCTION__ , this->process->pid, this->trdid, size, buffer, name );
     861    printk("\n[%s] thread[%x,%x] exit / %d bytes / buffer(%x) -> mapper(%s) / cycle %d\n",
     862    __FUNCTION__ , this->process->pid, this->trdid, size, buffer, name, cycle );
    809863}
    810864#endif
     
    17941848            xptr_t inode_children_xp = XPTR( inode_cxy , &inode_ptr->children.items );
    17951849
    1796 printk("\n@@@ in %s : children_xp = (%x,%x)\n",
    1797 __FUNCTION__, inode_cxy, &inode_ptr->children.items );
    1798 
    17991850            // get target inode number of children
    18001851            inode_children = hal_remote_l32( inode_children_xp );
     
    21662217
    21672218    // display inode
    2168     nolock_printk("%s<%s> : %s / extd %d / %d bytes / dirty %d / cxy %x / inode %x / mapper %x\n",
     2219    nolock_printk("%s<%s> : %s / extd %x / %d bytes / dirty %d / cxy %x / inode %x / mapper %x\n",
    21692220    indent_str[indent], name, vfs_inode_type_str( inode_type ), (uint32_t)inode_extd,
    21702221    inode_size, inode_dirty, inode_cxy, inode_ptr, mapper_ptr );
     
    23012352// This static function is used by the vfs_lookup() function.
    23022353// It takes an extended pointer on a remote parent directory inode, a directory
    2303 // entry name, and returns an extended pointer on the child inode.
     2354// entry name, and and scan the XHTAB associated to the parent inode to find the
     2355// searched dentry. It does NOT modify the inode tree in case of miss.
    23042356// It can be used by any thread running in any cluster.
    23052357//////////////////////////////////////////////////////////////////////////////////////////
     
    24242476    bool_t             create;       // searched inode must be created if not found
    24252477    bool_t             excl;         // searched inode must not exist
    2426     bool_t             par;          // searched inode is the parent
     2478    bool_t             parent;       // searched inode is the parent
    24272479    thread_t         * this;         // pointer on calling thread descriptor
    24282480    process_t        * process;      // pointer on calling process descriptor
     
    24492501    create = (lookup_mode & VFS_LOOKUP_CREATE) == VFS_LOOKUP_CREATE;
    24502502    excl   = (lookup_mode & VFS_LOOKUP_EXCL)   == VFS_LOOKUP_EXCL;
    2451     par    = (lookup_mode & VFS_LOOKUP_PARENT) == VFS_LOOKUP_PARENT;
     2503    parent = (lookup_mode & VFS_LOOKUP_PARENT) == VFS_LOOKUP_PARENT;
    24522504
    24532505    // initialise loop variables
     
    24992551        child_cxy  = GET_CXY( child_xp );
    25002552
    2501         // analyse found & last, depending on lookup_mode
    25022553        if( found == false )                              // not found in Inode Tree
    25032554        {
    25042555            // when a inode is not found in the Inode Tree:
    2505             // - if (last and par) the Inode Tree is not modified
     2556            // - if (last and parent) the Inode Tree is not modified
    25062557            // - else we speculatively introduce a new (dentry/inode) in inode tree,
    25072558            //        and scan the parent directory mapper to initialise it.
     
    25142565            //         - if the child is a directory, the child mapper is loaded from device
    25152566
    2516             if( last && par )   //  does nothing
     2567            if( last && parent )   //  does nothing
    25172568            {
    25182569
     
    25772628                }
    25782629
    2579                 if ( error )   // child not found in parent mapper
     2630                // when the missing dentry is not in the parent mapper,
     2631                // it is a new dentry that must be registered in parent directory mapper
     2632                if ( error )
    25802633                {
    25812634                    if ( last && create )  // add a brand new dentry in parent directory
     
    25942647#if (DEBUG_VFS_LOOKUP & 1)
    25952648if( DEBUG_VFS_LOOKUP < cycle )
    2596 printk("\n[%s] thread[%x,%x] child <%s> not found in parent mapper => create it\n",
     2649printk("\n[%s] thread[%x,%x] child <%s> not found in parent mapper => created it\n",
    25972650__FUNCTION__, process->pid, this->trdid, name );
    2598 #endif
     2651vfs_inode_display( child_xp );
     2652#endif
     2653
     2654
    25992655                    }
    26002656                    else                   // not last or not create => error
     
    26872743        if ( last )           // last inode in path  => return relevant info
    26882744        {
    2689             if ( par )  // return parent inode and child name
     2745            if ( parent )  // return parent inode and child name
    26902746            {
    26912747
     
    27572813    vfs_inode_t  * child_ptr  = GET_PTR( child_xp );
    27582814
    2759     // 1. allocate one free cluster to child inode
    2760     // depending on the child inode FS type
     2815    // 1. allocate one free cluster in file system to child inode,
     2816    // and update the File Allocation Table in both the TAF mapper and IOC device.
     2817    // It depends on the child inode FS type.
    27612818    vfs_ctx_t * ctx = hal_remote_lpt( XPTR( child_cxy , &child_ptr->ctx ) );
    27622819
     
    27722829#if( DEBUG_VFS_NEW_DENTRY_INIT & 1)
    27732830if( DEBUG_VFS_NEW_DENTRY_INIT < cycle )
    2774 printk("\n[%s] thread[%x,%x] allocated FAT cluster %x to <%s>\n",
     2831printk("\n[%s] thread[%x,%x] allocated FS cluster %x to <%s>\n",
    27752832__FUNCTION__ , this->process->pid, this->trdid, cluster, child_name );
    27762833#endif
    27772834
    2778     // 2. update the child inode descriptor
     2835    // 2. update the child inode descriptor size and extend
    27792836    child_type = hal_remote_l32( XPTR( child_cxy , &child_ptr->type ) );
    27802837    child_size = (child_type == INODE_TYPE_DIR) ? 4096 : 0;
     
    33013358#endif
    33023359
    3303     // register new_dentry in parent_inode xhtab of children
     3360    // 4. register new_dentry in parent_inode xhtab of children
    33043361    children_xhtab_xp = XPTR( parent_cxy , &parent_inode_ptr->children );
    33053362    children_entry_xp = XPTR( parent_cxy , &new_dentry_ptr->children );
     
    33133370#endif
    33143371
    3315     // update "parent" and "child_xp" fields in new_dentry
     3372    // 5. update "parent" and "child_xp" fields in new_dentry
    33163373    hal_remote_s64( XPTR( parent_cxy , &new_dentry_ptr->child_xp ) , new_inode_xp );
    33173374    hal_remote_spt( XPTR( parent_cxy , &new_dentry_ptr->parent ) , parent_inode_ptr );
  • trunk/kernel/fs/vfs.h

    r625 r626  
    376376 * argument to a local buffer identified by the <name> argument.
    377377 * The local buffer size must be at least CONFIG_VFS_MAX_NAME_LENGTH.
    378  *****************************************************************************************
     378 ******************************************************************************************
    379379 * @ inode_xp  : extended pointer on the remote inode.
    380380 * @ name      : local buffer pointer.
     
    396396error_t vfs_inode_load_all_pages( vfs_inode_t * inode );
    397397
    398 
     398/******************************************************************************************
     399 * This debug function display the curren state of an inode descriptor identified by
     400 * the <inode_xp> argument.
     401 *****************************************************************************************/
     402void vfs_inode_display( xptr_t inode_xp );
    399403
    400404/******************************************************************************************
     
    547551 * It can be executed by any thread running in any cluster (can be different from both
    548552 * the child cluster and the parent cluster).
    549  *
    550  * [Implementation]
     553 * The new child inode and the parent inode can have different FS types.
     554 * [Implementation note]
    551555 * As there are cross-references between inode and dentry, this function implements
    552  * a three steps scenario :
     556 * a five steps scenario :
    553557 * 1) The dentry descriptor is created in the cluster containing the existing <parent_xp>
    554558 *    inode, and partially initialized, using the RPC_VFS_CREATE DENTRY if required.
    555559 * 2) The inode and its associated mapper are created in cluster identified by <child_cxy>,
    556560 *    and partially initialised, using the RPC_VFS_CREATE_INODE if required.
    557  *    The new inode and the parent inode can have different FS types.
    558  * 3) The pointers between the parent inode, the new dentry, and the child inode
    559  *    are updated, using remote accesses.
    560  ******************************************************************************************
     561 * 3) The pointers on dentry in parent inode are updated, using remote access.
     562 * 4) The pointers on dentry in child inode are updated, using remotes access.
     563 * 5) The pointers on parent and child inode in dentry are updated, using remotes access.
     564 *****************************************************************************************
    561565 * @ child_inode_cxy  : [in]  target cluster for child inode.
    562566 * @ fs_type          : [in]  child inode FS type.
     
    591595
    592596/******************************************************************************************
    593  * This function is called by the vfs_lookup() function when a new dentry/inode must
    594  * be created from scratch and introduced in both the Inode Tree and the IOC device.
    595  * The dentry and inode descriptors have been created by the caller.
    596  * - It allocates one cluster from the relevant FS, and updates the File Allocation
    597  *   Table (both the FAT mapper, and the IOC device).
    598  * - It set the "size", and "extend" fields in child inode descriptor.
    599  * - It updates the parent directory to introduce the new child in the parent directory
    600  *   inode descriptor (radix tree), in theparent inode mapper, and on IOC device.
    601  * - It set the "extend" field in dentry descriptor.
     597 * This function is called by the vfs_lookup() function when a new (dentry/inode) must
     598 * be created from scratch and introduced in both the parent mapper and the IOC device.
     599 * The dentry and inode descriptors must have been previously created by the caller.
     600 * 1. It allocates one cluster from the relevant FS, updates the FAT mapper,
     601 *    and synchronously update the IOC device).
     602 * 2. It set the "size", and "extend" fields in child inode descriptor.
     603 * 3. It updates the parent directory mapper to introduce the new child,
     604 *    and synchronously update the IOC device.
     605 * 4. It set the "extend" field in dentry descriptor.
    602606 * It can be called by a thread running in any cluster.
    603607 ******************************************************************************************
Note: See TracChangeset for help on using the changeset viewer.