Changeset 626 for trunk/kernel


Ignore:
Timestamp:
Apr 29, 2019, 7:25:09 PM (5 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
Files:
37 edited

Legend:

Unmodified
Added
Removed
  • trunk/kernel/Makefile

    r612 r626  
    185185              build/syscalls/sys_is_fg.o
    186186
    187 SYS_OBJS_5  = build/syscalls/sys_exit.o
     187SYS_OBJS_5  = build/syscalls/sys_exit.o            \
     188              build/syscalls/sys_sync.o            \
     189              build/syscalls/sys_fsync.o
    188190
    189191VFS_OBJS    = build/fs/vfs.o              \
     
    194196# List of directories to be searched for included files
    195197# when compiling for kernel.elf generation
    196 KERNEL_INCLUDE = -I.                  \
    197                  -Ikern             \
    198                  -Idevices          \
    199                  -Isyscalls         \
    200                  -I$(SHARED_INCLUDE)  \
     198KERNEL_INCLUDE = -I.                   \
     199                 -Ikern                \
     200                 -Idevices             \
     201                 -Isyscalls            \
     202                 -I$(SHARED_INCLUDE)   \
    201203                 -I$(HAL_ARCH)/drivers \
    202204                 -Isyscalls            \
  • trunk/kernel/devices/dev_ioc.c

    r619 r626  
    22 * dev_ioc.c - IOC (Block Device Controler) generic device API implementation.
    33 *
    4  * Author  Alain Greiner    (2016,2017,2018)
     4 * Author  Alain Greiner    (2016,2017,2018,2019)
    55 *
    66 * Copyright (c) UPMC Sorbonne Universites
     
    3636
    3737extern chdev_directory_t  chdev_dir;     // allocated in kernel_init.c
     38
     39////////////////////////////////////////
     40char * dev_ioc_cmd_str( cmd_type_t cmd )
     41{
     42    if     ( cmd == IOC_READ       )  return "READ";
     43    else if( cmd == IOC_WRITE      )  return "WRITE";
     44    else if( cmd == IOC_SYNC_READ  )  return "SYNC_READ";
     45    else if( cmd == IOC_SYNC_WRITE )  return "SYNC_WRITE";
     46    else                              return "undefined";
     47}
    3848
    3949//////////////////////////////////
     
    192202////////////////////////////////////i/////////////////////////////////////////////
    193203error_t dev_ioc_sync_access( uint32_t   cmd_type,
    194                              uint8_t  * buffer,
     204                             xptr_t     buffer_xp,
    195205                             uint32_t   lba,
    196206                             uint32_t   count )
     
    202212    if( chdev_dir.iob )
    203213    {
    204         if (cmd_type == IOC_SYNC_READ) dev_mmc_inval( XPTR(local_cxy,buffer) , count<<9 );
    205         else                           dev_mmc_sync ( XPTR(local_cxy,buffer) , count<<9 );
     214        if (cmd_type == IOC_SYNC_READ) dev_mmc_inval( buffer_xp , count<<9 );
     215        else                           dev_mmc_sync ( buffer_xp , count<<9 );
    206216    }
    207217
     
    215225    this->ioc_cmd.dev_xp    = ioc_xp;
    216226    this->ioc_cmd.type      = cmd_type;
    217     this->ioc_cmd.buf_xp    = XPTR( local_cxy , buffer );
     227    this->ioc_cmd.buf_xp    = buffer_xp;
    218228    this->ioc_cmd.lba       = lba;
    219229    this->ioc_cmd.count     = count;
     
    241251    return this->ioc_cmd.error;
    242252
    243 }  // end ioc_sync_access()
    244 
    245 /////////////////////////////////////////////
    246 error_t dev_ioc_sync_read( uint8_t  * buffer,
     253}  // end dev_ioc_sync_access()
     254
     255////////////////////////////////////////////////
     256error_t dev_ioc_sync_read( xptr_t     buffer_xp,
    247257                           uint32_t   lba,
    248258                           uint32_t   count )
     
    253263uint32_t   cycle = (uint32_t)hal_get_cycles();
    254264if( DEBUG_DEV_IOC_RX < cycle )
    255 printk("\n[%s] thread[%x,%x] : lba  %x / buffer %x / cycle %d\n",
    256 __FUNCTION__ , this->process->pid, this->trdid, lba, buffer, cycle );
    257 #endif
    258 
    259     return dev_ioc_sync_access( IOC_SYNC_READ , buffer , lba , count );
     265printk("\n[%s] thread[%x,%x] : lba  %x / buffer(%x,%x) / count %d / cycle %d\n",
     266__FUNCTION__ , this->process->pid, this->trdid,
     267lba, GET_CXY(buffer_xp), GET_PTR(buffer_xp), count, cycle );
     268#endif
     269
     270    return dev_ioc_sync_access( IOC_SYNC_READ , buffer_xp , lba , count );
    260271}
    261272
    262 //////////////////////////////////////////////
    263 error_t dev_ioc_sync_write( uint8_t  * buffer,
     273/////////////////////////////////////////////////
     274error_t dev_ioc_sync_write( xptr_t     buffer_xp,
    264275                            uint32_t   lba,
    265276                            uint32_t   count )
    266277{
    267278
    268 #if DEBUG_DEV_IOC_RX
    269 thread_t * this  = CURRENT_THREAD;
    270 uint32_t   cycle = (uint32_t)hal_get_cycles();
    271 if( DEBUG_DEV_IOC_RX < cycle )
    272 printk("\n[%s] thread[%x,%x] enters / lba  %x / buffer %x / cycle %d\n",
    273 __FUNCTION__ , this->process->pid, this->trdid, lba, buffer, cycle );
    274 #endif
    275 
    276     return dev_ioc_sync_access( IOC_SYNC_WRITE , buffer , lba , count );
     279#if DEBUG_DEV_IOC_TX
     280thread_t * this  = CURRENT_THREAD;
     281uint32_t   cycle = (uint32_t)hal_get_cycles();
     282if( DEBUG_DEV_IOC_TX < cycle )
     283printk("\n[%s] thread[%x,%x] : lba  %x / buffer(%x,%x) / count %d / cycle %d\n",
     284__FUNCTION__ , this->process->pid, this->trdid,
     285lba, GET_CXY(buffer_xp), GET_PTR(buffer_xp), count, cycle );
     286#endif
     287
     288    return dev_ioc_sync_access( IOC_SYNC_WRITE , buffer_xp , lba , count );
    277289}
    278290
  • trunk/kernel/devices/dev_ioc.h

    r614 r626  
    22 * dev_ioc.h - IOC (Block Device Controler) generic device API definition.
    33 *
    4  * Author  Alain Greiner    (2016,2017,2018)
     4 * Author  Alain Greiner    (2016,2017,2018,2019)
    55 *
    66 * Copyright (c) UPMC Sorbonne Universites
     
    4444 * - SYNC_WRITE : move blocks from memory to device, with a busy waiting policy.
    4545
    46  * A READ or WRITE operation requires dynamic ressource allocation. The calling thread
     46 * The READ or WRITE operations require dynamic ressource allocation. The calling thread
    4747 * is descheduled, and the work is done by the server thread associated to IOC device.
    4848 * The general scenario is detailed below.
     
    6666 *
    6767 * The SYNC_READ and SYNC_WRITE operations are used by the kernel in the initialisation
    68  * phase. These operations do not not use the IOC device waiting queue, the server thread,
    69  * and the IOC IRQ, but implement a busy-waiting policy for the calling thread.
     68 * phase, to update the FAT (both the FAT mapper and the FAT on IOC device), or to update
     69 * a directory on IOC device when a new file is created.
     70 * - These synchronous operations do not not use the IOC device waiting queue,
     71 *   the server thread, and the IOC IRQ, but implement a busy-waiting policy
     72 *   for the calling thread.
     73 * - As the work
    7074 *****************************************************************************************/
    7175
     
    119123}
    120124ioc_command_t;
     125
     126/******************************************************************************************
     127 * This function returns a printable string for a IOC command type.
     128 ******************************************************************************************
     129 * @ cmd  : command type.
     130 * @ return pointer on string.
     131 *****************************************************************************************/
     132char * dev_ioc_cmd_str( cmd_type_t cmd );
    121133
    122134/******************************************************************************************
     
    138150 * registered in the device pending request queue, and the calling thread is descheduled,
    139151 * waiting on transfer completion. It will be resumed by the IRQ signaling completion.
    140  * It must be called in the client cluster.
     152 * It must be called by a local thread.
    141153 ******************************************************************************************
    142154 * @ buffer    : local pointer on target buffer in memory (must be block aligned).
    143155 * @ lba       : first block index on device.
    144156 * @ count     : number of blocks to transfer.
    145  * @ returns 0 if success / returns EINVAL if error.
     157 * @ returns 0 if success / returns -1 if error.
    146158 *****************************************************************************************/
    147159error_t dev_ioc_read( uint8_t      * buffer,
     
    154166 * registered in the device pending request queue, and the calling thread is descheduled,
    155167 * waiting on transfer completion. It will be resumed by the IRQ signaling completion.
    156  * It must be called in the client cluster.
     168 * It must be called by a local thread.
    157169 ******************************************************************************************
    158170 * @ buffer    : local pointer on source buffer in memory (must be block aligned).
    159171 * @ lba       : first block index on device.
    160172 * @ count     : number of blocks to transfer.
    161  * @ returns 0 if success / returns EINVAL if error.
     173 * @ returns 0 if success / returns -1 if error.
    162174 *****************************************************************************************/
    163175error_t dev_ioc_write( uint8_t      * buffer,
     
    167179/******************************************************************************************
    168180 * This blocking function moves one or several contiguous blocks of data
    169  * from the block device to a local memory buffer.
     181 * from the block device to a - possibly remote - memory buffer.
    170182 * It does  not uses the IOC device waiting queue and server thread, and does not use
    171183 * the IOC IRQ, but call directly the relevant IOC driver, implementing a busy-waiting
    172184 * policy for the calling thread.
    173  * It must be called in the client cluster.
    174  ******************************************************************************************
    175  * @ buffer    : local pointer on target buffer in memory (must be block aligned).
    176  * @ lba       : first block index on device.
    177  * @ count     : number of blocks to transfer.
    178  * @ returns 0 if success / returns EINVAL if error.
    179  *****************************************************************************************/
    180 error_t dev_ioc_sync_read( uint8_t      * buffer,
     185 * It can be called by a thread running in any cluster.
     186 ******************************************************************************************
     187 * @ buffer_xp : extended pointer on target buffer in memory (must be block aligned).
     188 * @ lba       : first block index on device.
     189 * @ count     : number of blocks to transfer.
     190 * @ returns 0 if success / returns -1 if error.
     191 *****************************************************************************************/
     192error_t dev_ioc_sync_read( xptr_t         buffer_xp,
    181193                           uint32_t       lba,
    182194                           uint32_t       count );
     
    184196/******************************************************************************************
    185197 * This blocking function moves one or several contiguous blocks of data
    186  * from a local memory buffer to the block device.
     198 * from a - possibly remote - memory buffer to the block device.
    187199 * It does  not uses the IOC device waiting queue and server thread, and does not use
    188200 * the IOC IRQ, but call directly the relevant IOC driver, implementing a busy-waiting
    189201 * policy for the calling thread.
    190  * It must be called in the client cluster.
    191  ******************************************************************************************
    192  * @ buffer    : local pointer on source buffer in memory (must be block aligned).
    193  * @ lba       : first block index on device.
    194  * @ count     : number of blocks to transfer.
    195  * @ returns 0 if success / returns EINVAL if error.
    196  *****************************************************************************************/
    197 error_t dev_ioc_sync_write( uint8_t      * buffer,
     202 * It can be called by a thread running in any cluster.
     203 ******************************************************************************************
     204 * @ buffer_xp : extended pointer on source buffer in memory (must be block aligned).
     205 * @ lba       : first block index on device.
     206 * @ count     : number of blocks to transfer.
     207 * @ returns 0 if success / returns -1 if error.
     208 *****************************************************************************************/
     209error_t dev_ioc_sync_write( xptr_t         buffer_xp,
    198210                            uint32_t       lba,
    199211                            uint32_t       count );
  • trunk/kernel/devices/dev_mmc.c

    r605 r626  
    108108
    109109    // get buffer cluster and local pointer
    110     cxy_t  buf_cxy = GET_CXY( buf_xp );
    111     void * buf_ptr = GET_PTR( buf_xp );
     110    cxy_t     buf_cxy = GET_CXY( buf_xp );
     111    uint8_t * buf_ptr = GET_PTR( buf_xp );
    112112   
    113     assert( (((intptr_t)buf_ptr & (CONFIG_CACHE_LINE_SIZE -1)) == 0) ,
    114              "buffer not aligned on cache line" );
     113    // force buffer align
     114    uint32_t  delta = (uint32_t)buf_ptr & (CONFIG_CACHE_LINE_SIZE - 1);
     115    uint8_t * base  = buf_ptr - delta;
     116    uint32_t  size  = buf_size + delta;
    115117
    116118    // store command arguments in thread descriptor
    117119    this->mmc_cmd.dev_xp    = chdev_dir.mmc[buf_cxy];
    118120    this->mmc_cmd.type      = MMC_CC_INVAL;
    119     this->mmc_cmd.buf_ptr   = buf_ptr;
    120     this->mmc_cmd.buf_size  = buf_size;
     121    this->mmc_cmd.buf_ptr   = base;
     122    this->mmc_cmd.buf_size  = size;
    121123
    122124    // call MMC driver
     
    152154    void * buf_ptr = GET_PTR( buf_xp );
    153155   
    154     assert( (((intptr_t)buf_ptr & (CONFIG_CACHE_LINE_SIZE -1)) == 0) ,
    155              "buffer not aligned on cache line" );
     156    // force buffer align
     157    uint32_t  delta = (uint32_t)buf_ptr & (CONFIG_CACHE_LINE_SIZE - 1);
     158    uint8_t * base  = buf_ptr - delta;
     159    uint32_t  size  = buf_size + delta;
    156160
    157161    // store command arguments in thread descriptor
    158162    this->mmc_cmd.dev_xp    = chdev_dir.mmc[buf_cxy];
    159163    this->mmc_cmd.type      = MMC_CC_SYNC;
    160     this->mmc_cmd.buf_ptr   = buf_ptr;
    161     this->mmc_cmd.buf_size  = buf_size;
     164    this->mmc_cmd.buf_ptr   = base;
     165    this->mmc_cmd.buf_size  = size;
    162166
    163167    // call MMC driver
  • trunk/kernel/devices/dev_txt.c

    r619 r626  
    22 * dev_txt.c - TXT (Text Terminal) generic device API implementation.
    33 *
    4  * Author  Alain Greiner    (2016,2017,2018)
     4 * Author  Alain Greiner    (2016,2017,2018,2019)
    55 *
    66 * Copyright (c) UPMC Sorbonne Universites
  • trunk/kernel/devices/dev_txt.h

    r565 r626  
    22 * dev_txt.h - TXT (Text Terminal) generic device API definition.
    33 *
    4  * Author  Alain Greiner    (2016)
     4 * Author  Alain Greiner    (2016,2017,2018,2019))
    55 *
    66 * Copyright (c) UPMC Sorbonne Universites
     
    106106    const char * buffer;    /*! local pointer on characters array                        */
    107107    uint32_t     count;     /*! number of characters in buffer                           */
    108     uint32_t    channel;   /*! channel, aka which tty to write to                        */
     108    uint32_t     channel;   /*! channel, aka which tty to write to                       */
    109109}
    110110txt_sync_args_t;
    111111
    112112/******************************************************************************************
    113  * This function returns a printable string for the comman type.
     113 * This function returns a printable string for the command type.
    114114 ******************************************************************************************
    115115 * @ type     : command type (TXT_READ / TXT_WRITE / TXT_SYNC_WRITE)
     
    166166 * interfering with another possible TXT access to another terminal.
    167167 * As it is used for debug, the command arguments <buffer> and <count> are registerd
    168  * in a specific "dbg_cmd" field of the calling thread.
     168 * in a specific "txt_syc_args_t" structure passed to the driver "aux" function.
    169169 ****************************************************************************************
    170170 * @ buffer    : local pointer on source buffer containing the string.
  • 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 ******************************************************************************************
  • trunk/kernel/kern/do_syscall.c

    r610 r626  
    22 * do_syscall.c - architecture independant entry-point for system calls.
    33 *
    4  * Author    Alain Greiner (2016,2017,2018)
     4 * Author    Alain Greiner (2016,2017,2018, 2019)
    55 *
    66 * Copyright (c) UPMC Sorbonne Universites
     
    106106
    107107    sys_exit,               // 50
     108    sys_sync,               // 51
     109    sys_fsync,              // 52
    108110};
    109111
     
    169171
    170172    case SYS_EXIT:                         return "EXIT";             // 50
     173    case SYS_SYNC:                         return "SYNC";             // 51
     174    case SYS_FSYNC:                        return "FSYNc";            // 52
    171175
    172176    default:                               return "undefined";
  • trunk/kernel/kern/kernel_init.c

    r624 r626  
    898898}
    899899
     900
     901
     902
     903
     904/////////////////////////////////
     905// kleenex debug function
     906/////////////////////////////////
     907void display_fat( uint32_t step )
     908{
     909    fatfs_ctx_t * fatfs_ctx = fs_context[FS_TYPE_FATFS].extend;
     910    if( fatfs_ctx != NULL )
     911    {
     912        printk("\n[%s] step %d at cycle %d\n", __FUNCTION__, step, (uint32_t)hal_get_cycles() );
     913        xptr_t     mapper_xp = fatfs_ctx->fat_mapper_xp;
     914        mapper_display_page( mapper_xp , 0 , 128 );
     915    }
     916    else
     917    {
     918        printk("\n[%s] step %d : fatfs context not initialized\n", __FUNCTION__, step );
     919    }
     920}
     921
     922
     923
     924
     925
    900926///////////////////////////////////////////////////////////////////////////////////////////
    901927// This function is the entry point for the kernel initialisation.
     
    11431169        if( CONFIG_VFS_ROOT_IS_FATFS )
    11441170        {
    1145             // 1. allocate memory for FATFS context extension in cluster 0
     1171            // 1. allocate memory for FATFS context in cluster 0
    11461172            fatfs_ctx_t * fatfs_ctx = fatfs_ctx_alloc();
    11471173
     
    11551181            // 2. access boot device to initialize FATFS context
    11561182            fatfs_ctx_init( fatfs_ctx );
    1157  
     1183
    11581184            // 3. get various informations from FATFS context
    11591185            uint32_t root_dir_cluster = fatfs_ctx->root_dir_cluster;
  • trunk/kernel/kern/process.c

    r625 r626  
    14471447#if( DEBUG_PROCESS_MAKE_FORK & 1 )
    14481448cycle = (uint32_t)hal_get_cycles();
    1449 if( DEBUG_PROCESS_MAKE_EXEC < cycle )
     1449if( DEBUG_PROCESS_MAKE_FORK < cycle )
    14501450printk("\n[%s] thread[%x,%x] / child takes TXT ownership / cycle %d\n",
    14511451__FUNCTION__ , pid, trdid, cycle );
     
    15561556#if DEBUG_PROCESS_MAKE_EXEC
    15571557uint32_t cycle = (uint32_t)hal_get_cycles();
    1558 if( DEBUG_PROCESS_MAKE_EXEC < cycle )
     1558if( local_cxy == 0x11 )
    15591559printk("\n[%s] thread[%x,%x] enters for %s / cycle %d\n",
    15601560__FUNCTION__, pid, thread->trdid, path, cycle );
     
    15791579#if (DEBUG_PROCESS_MAKE_EXEC & 1)
    15801580cycle = (uint32_t)hal_get_cycles();
    1581 if( DEBUG_PROCESS_MAKE_EXEC < cycle )
     1581if( local_cxy == 0x11 )
    15821582printk("\n[%s] thread[%x,%x] opened file <%s> / cycle %d\n",
    15831583__FUNCTION__, pid, thread->trdid, path, cycle );
     
    15891589#if (DEBUG_PROCESS_MAKE_EXEC & 1)
    15901590cycle = (uint32_t)hal_get_cycles();
    1591 if( DEBUG_PROCESS_MAKE_EXEC < cycle )
     1591if( local_cxy == 0x11 )
    15921592printk("\n[%s] thread[%x,%x] deleted existing threads / cycle %d\n",
    15931593__FUNCTION__, pid, thread->trdid, cycle );
     
    15991599#if( DEBUG_PROCESS_MAKE_EXEC & 1 )
    16001600cycle = (uint32_t)hal_get_cycles();
    1601 if( DEBUG_PROCESS_MAKE_EXEC < cycle )
     1601if( local_cxy == 0x11 )
    16021602printk("\n[%s] thread[%x,%x] completed VMM reset / cycle %d\n",
    16031603__FUNCTION__, pid, thread->trdid, cycle );
     
    16161616#if( DEBUG_PROCESS_MAKE_EXEC & 1 )
    16171617cycle = (uint32_t)hal_get_cycles();
    1618 if( DEBUG_PROCESS_MAKE_EXEC < cycle )
     1618if( local_cxy == 0x11 )
    16191619printk("\n[%s] thread[%x,%x] registered args/envs vsegs / cycle %d\n",
    16201620__FUNCTION__, pid, thread->trdid, cycle );
     
    16341634#if( DEBUG_PROCESS_MAKE_EXEC & 1 )
    16351635cycle = (uint32_t)hal_get_cycles();
    1636 if( DEBUG_PROCESS_MAKE_EXEC < cycle )
     1636if( local_cxy == 0x11 )
    16371637printk("\n[%s] thread[%x,%x] registered code/data vsegs / cycle %d\n",
    16381638__FUNCTION__, pid, thread->trdid, cycle );
  • trunk/kernel/libk/grdxt.c

    r610 r626  
    11/*
    2  * grdxt.c - Three-levels Generic Radix-tree implementation
     2 * grdxt.c - Three-levels Generic Radix-tree implementation.
    33 *
    4  * authors  Alain Greiner (2016)
     4 * authors  Alain Greiner (2016,2017,2018,2019))
    55 *
    66 * Copyright (c)  UPMC Sorbonne Universites
  • trunk/kernel/libk/grdxt.h

    r623 r626  
    11/*
    2  * grdxt.h - Three-levels Generic Radix-tree interface
     2 * grdxt.h - Three-levels Generic Radix-tree definition.
    33 *
    4  * Authors  Alain Greiner (2016)
     4 * Authors  Alain Greiner (2016,2017,2018,2019)
    55 *
    66 * Copyright  UPMC Sorbonne Universites
  • trunk/kernel/libk/remote_rwlock.c

    r625 r626  
    251251        thread_t *  thread_ptr = GET_PTR( thread_xp );
    252252
    253 printk("\n@@@ in %s : release first waiting writer[%x,%x]\n",
    254 __FUNCTION__, thread_cxy, thread_ptr );
    255 
    256253        // remove this waiting thread from waiting list
    257254        xlist_unlink( XPTR( thread_cxy , &thread_ptr->wait_xlist ) );
  • trunk/kernel/mm/mapper.c

    r625 r626  
    280280    printk("\n[%s] thread[%x,%x] enter for page %d in <%s> / cycle %d",
    281281    __FUNCTION__, this->process->pid, this->trdid, page_id, name, cycle );
    282    if( DEBUG_MAPPER_HANDLE_MISS & 1 ) grdxt_display( XPTR(local_cxy,&mapper->rt), name );
     282    if( DEBUG_MAPPER_HANDLE_MISS & 1 ) grdxt_display( XPTR(local_cxy,&mapper->rt), name );
    283283}
    284284if( (DEBUG_MAPPER_HANDLE_MISS < cycle) && (inode == NULL) )
     
    286286    printk("\n[%s] thread[%x,%x] enter for page %d in FAT / cycle %d",
    287287    __FUNCTION__, this->process->pid, this->trdid, page_id, cycle );
    288    if( DEBUG_MAPPER_HANDLE_MISS & 1 ) grdxt_display( XPTR(local_cxy,&mapper->rt), "FAT" );
     288    if( DEBUG_MAPPER_HANDLE_MISS & 1 ) grdxt_display( XPTR(local_cxy,&mapper->rt), "FAT" );
    289289}
    290290#endif
     
    324324    }
    325325
    326     // launch I/O operation to load page from device to mapper
     326    // launch I/O operation to load page from IOC device to mapper
    327327    error = vfs_fs_move_page( XPTR( local_cxy , page ) , IOC_SYNC_READ );
    328328
     
    401401
    402402#if DEBUG_MAPPER_MOVE_USER
    403 uint32_t   cycle = (uint32_t)hal_get_cycles();
    404 thread_t * this  = CURRENT_THREAD;
     403uint32_t      cycle      = (uint32_t)hal_get_cycles();
     404thread_t    * this       = CURRENT_THREAD;
     405cxy_t         mapper_cxy = GET_CXY( mapper_xp );
     406mapper_t    * mapper_ptr = GET_PTR( mapper_xp );
     407vfs_inode_t * inode_ptr  = hal_remote_lpt( XPTR( mapper_cxy , &mapper_ptr->inode ) );
     408xptr_t        inode_xp   = XPTR( mapper_cxy , inode_ptr );
     409char          name[CONFIG_VFS_MAX_NAME_LENGTH];
     410vfs_inode_get_name( inode_xp , name );
    405411if( DEBUG_MAPPER_MOVE_USER < cycle )
    406 printk("\n[%s] thread[%x,%x] : to_buf %d / buffer %x / size %d / offset %d / cycle %d\n",
    407 __FUNCTION__, this->process->pid, this->trdid,
    408 to_buffer, buffer, size, file_offset, cycle );
     412{
     413    if( to_buffer )
     414    printk("\n[%s] thread[%x,%x] : mapper(%s) -> buffer(%x) / bytes %d / cycle %d\n",
     415    __FUNCTION__, this->process->pid, this->trdid, name, buffer, size, cycle );
     416    else
     417    printk("\n[%s] thread[%x,%x] : buffer(%x) -> mapper(%s) / bytes %d / cycle %d\n",
     418    __FUNCTION__, this->process->pid, this->trdid, buffer, name, size, cycle );
     419}
    409420#endif
    410421
     
    419430#if (DEBUG_MAPPER_MOVE_USER & 1)
    420431if( DEBUG_MAPPER_MOVE_USER < cycle )
    421 printk("\n[%s] thread[%x,%x] : first_page %d / last_page %d\n",
    422 __FUNCTION__, this->process->pid, this->trdid, first, last );
     432printk("\n[%s] thread[%x,%x] : mapper(%x,%x) / first_page %d / last_page %d\n",
     433__FUNCTION__, this->process->pid, this->trdid, mapper_cxy, mapper_ptr, first, last );
    423434#endif
    424435
     
    440451#if (DEBUG_MAPPER_MOVE_USER & 1)
    441452if( DEBUG_MAPPER_MOVE_USER < cycle )
    442 printk("\n[%s] thread[%x,%x] : page_id = %d / page_offset = %d / page_count = %d\n",
     453printk("\n[%s] thread[%x,%x] : page_id %d / page_offset %d / bytes %d\n",
    443454__FUNCTION__, this->process->pid, this->trdid, page_id , page_offset , page_count );
    444455#endif
     
    449460        if ( page_xp == XPTR_NULL ) return -1;
    450461
     462        // compute cluster and pointers on page in mapper
     463        xptr_t     map_xp  = ppm_page2base( page_xp );
     464        uint8_t  * map_ptr = GET_PTR( map_xp );
     465        cxy_t      map_cxy = GET_CXY( map_xp );
     466
    451467#if (DEBUG_MAPPER_MOVE_USER & 1)
    452468if( DEBUG_MAPPER_MOVE_USER < cycle )
    453 printk("\n[%s] thread[%x,%x] : get page (%x,%x) from mapper\n",
    454 __FUNCTION__, this->process->pid, this->trdid, GET_CXY(page_xp), GET_PTR(page_xp) );
    455 #endif
    456 
    457         // compute pointer in mapper
    458         xptr_t    base_xp = ppm_page2base( page_xp );
    459         uint8_t * map_ptr = (uint8_t *)GET_PTR( base_xp ) + page_offset;
    460 
    461         // compute pointer in buffer
     469printk("\n[%s] thread[%x,%x] : get buffer(%x,%x) in mapper\n",
     470__FUNCTION__, this->process->pid, this->trdid, map_cxy, map_ptr );
     471#endif
     472        // compute pointer in user buffer
    462473        uint8_t * buf_ptr = (uint8_t *)buffer + done;
    463474
     
    465476        if( to_buffer )
    466477        {
    467             hal_copy_to_uspace( buf_ptr , map_ptr , page_count );
     478            hal_copy_to_uspace( map_cxy , map_ptr , buf_ptr , page_count );
     479
     480#if DEBUG_MAPPER_MOVE_USER & 1
     481if( DEBUG_MAPPER_MOVE_USER < cycle )
     482printk("\n[%s] thread[%x,%x] moved %d bytes / mapper %s (%x,%x) -> user buffer(%x,%x)\n",
     483__FUNCTION__, this->process->pid, this->trdid, page_count,
     484name, map_cxy, map_ptr, local_cxy, buf_ptr );
     485#endif
     486
    468487        }
    469488        else
    470489        {
    471490            ppm_page_do_dirty( page_xp );
    472             hal_copy_from_uspace( map_ptr , buf_ptr , page_count );
     491            hal_copy_from_uspace( map_cxy , map_ptr , buf_ptr , page_count );
     492
     493#if DEBUG_MAPPER_MOVE_USER & 1
     494if( DEBUG_MAPPER_MOVE_USER < cycle )
     495printk("\n[%s] thread[%x,%x] moved %d bytes / user buffer(%x,%x) -> mapper %s (%x,%x)\n",
     496__FUNCTION__, this->process->pid, this->trdid, page_count,
     497local_cxy, buf_ptr, name, map_cxy, map_ptr );
     498mapper_display_page(  mapper_xp , page_id, 128 );
     499#endif
     500
    473501        }
    474502
     
    477505
    478506#if DEBUG_MAPPER_MOVE_USER
    479 cycle = (uint32_t)hal_get_cycles();
     507cycle      = (uint32_t)hal_get_cycles();
    480508if( DEBUG_MAPPER_MOVE_USER < cycle )
    481 printk("\n[%s] thread[%x,%x] exit / cycle %d\n",
    482 __FUNCTION__, this->process->pid, this->trdid, cycle );
     509{
     510    if( to_buffer )
     511    printk("\n[%s] thread[%x,%x] completed mapper(%s) -> buffer(%x) / cycle %d\n",
     512    __FUNCTION__, this->process->pid, this->trdid, name, buffer, cycle );
     513    else
     514    printk("\n[%s] thread[%x,%x] completed buffer(%x) -> mapper(%s) / cycle %d\n",
     515    __FUNCTION__, this->process->pid, this->trdid, buffer, name, cycle );
     516}
    483517#endif
    484518
     
    717751#if DEBUG_MAPPER_SYNC
    718752if( cycle > DEBUG_MAPPER_SYNC )
    719 printk("\n[%s] thread[%x,%x] synchonise page %d of <%s> to device\n",
     753printk("\n[%s] thread[%x,%x] synchonise page %d of <%s> to IOC device\n",
    720754__FUNCTION__, this->process->pid, this->trdid, page->index, name );
    721755#endif
     
    804838    // display 8 words per line
    805839    tabi = (uint32_t *)buffer;
    806     printk("\n***** <%s> first %d bytes of page %d *****\n", name, nbytes, page_id );
     840    printk("\n***** mapper <%s> / %d bytes in page %d (%x,%x)\n",
     841    name, nbytes, page_id, GET_CXY(base_xp), GET_PTR(base_xp) );
    807842    for( line = 0 ; line < (nbytes >> 5) ; line++ )
    808843    {
  • trunk/kernel/mm/mapper.h

    r625 r626  
    6262 *   and the  allocated memory is only released when the mapper/inode is destroyed.
    6363 *
    64  * TODO : the mapper being only used to implement the VFS cache(s), the mapper.c
    65  *        and mapper.h file should be trandfered to the fs directory.
     64 * TODO (1) the mapper being only used to implement the VFS cache(s), the mapper.c
     65 *          and mapper.h file should be trandfered to the fs directory.
     66 * TODO (2) the "type" field is probably unused...
    6667 ******************************************************************************************/
    6768
     
    230231
    231232/*******************************************************************************************
    232  * This scans all pages present in the mapper identified by the <mapper> argument,
     233 * This function scan all pages present in the mapper identified by the <mapper> argument,
    233234 * and synchronize all pages maked as dirty" on disk.
    234235 * These pages are unmarked and removed from the local PPM dirty_list.
  • trunk/kernel/syscalls/shared_include/shared_almos.h

    r623 r626  
    5454    DISPLAY_MAPPER            = 9,
    5555    DISPLAY_BARRIER           = 10,
     56    DISPLAY_FAT               = 11,
    5657}
    5758display_type_t;
  • trunk/kernel/syscalls/shared_include/syscalls_numbers.h

    r610 r626  
    22 * syscalls_numbers.c - Contains enum of the syscalls.
    33 *
    4  * Author    Alain Greiner (2018)
     4 * Author    Alain Greiner (2016,2017,2018,2019)
    55 *
    66 * Copyright (c) UPMC Sorbonne Universites
     
    8686
    8787    SYS_EXIT           = 50,
     88    SYS_SYNC           = 51,
     89    SYS_FSYNC          = 52,
    8890
    89     SYSCALLS_NR        = 51,
     91    SYSCALLS_NR        = 53,
    9092
    9193} syscalls_t;
  • trunk/kernel/syscalls/sys_barrier.c

    r625 r626  
    104104 
    105105                // copy barrier attributes into kernel space
    106                 hal_copy_from_uspace( &k_attr , (void*)attr , sizeof(pthread_barrierattr_t) );
     106                hal_copy_from_uspace( local_cxy,
     107                                      &k_attr,
     108                                      (void*)attr,
     109                                      sizeof(pthread_barrierattr_t) );
    107110
    108111                if ( count != k_attr.x_size * k_attr.y_size *k_attr.nthreads ) 
  • trunk/kernel/syscalls/sys_display.c

    r625 r626  
    5656    else if( type == DISPLAY_MAPPER            ) return "MAPPER";
    5757    else if( type == DISPLAY_BARRIER           ) return "BARRIER";
     58    else if( type == DISPLAY_FAT               ) return "FAT";
    5859    else                                         return "undefined";
    5960}
     
    436437            break;
    437438        }
     439        /////////////////
     440        case DISPLAY_FAT:
     441        {
     442            uint32_t  entries = (uint32_t)arg1;
     443
     444            if( entries > 4096 )
     445                {
     446
     447#if DEBUG_SYSCALLS_ERROR
     448printk("\n[ERROR] in %s for FAT : nb_entries larger than 4096\n",
     449__FUNCTION__ );
     450#endif
     451                        this->errno = EINVAL;
     452                        return -1;
     453                }
     454
     455            if( entries == 0 )  // display fat context in cluster cxy
     456            {
     457                uint32_t  cxy = (uint32_t)arg0;
     458
     459                if( cluster_is_undefined( cxy ) )
     460                {
     461
     462#if DEBUG_SYSCALLS_ERROR
     463printk("\n[ERROR] in %s for FAT : illegal cxy argument %x\n",
     464__FUNCTION__ , cxy );
     465#endif
     466                     this->errno = EINVAL;
     467                     return -1;
     468                }
     469
     470                fatfs_display_ctx( cxy );
     471            }
     472            else                  // display nb_entries in page
     473            {                       
     474                uint32_t page = (uint32_t)arg0;
     475
     476                fatfs_display_fat( page , entries );
     477            }
     478
     479            break;
     480        }
    438481        ////////
    439482        default:
  • trunk/kernel/syscalls/sys_exec.c

    r625 r626  
    9696
    9797    // copy the array of pointers to kernel buffer
    98     hal_copy_from_uspace( k_pointers,
     98    hal_copy_from_uspace( local_cxy,
     99                          k_pointers,
    99100                          u_pointers,
    100101                          CONFIG_PPM_PAGE_SIZE );
     
    115116
    116117        // copy the user string to kernel buffer
    117         hal_copy_from_uspace( k_buf_ptr,
     118        hal_copy_from_uspace( local_cxy,
     119                              k_buf_ptr,
    118120                              k_pointers[index],
    119121                              length );
  • trunk/kernel/syscalls/sys_fsync.c

    r1 r626  
    11/*
    2  * sys_fsync: sync file
     2 * sys_fsync.c - copy all modified pages of a given file mapper to IOC device.
    33 *
    4  * Copyright (c) 2015 UPMC Sorbonne Universites
     4 * Author    Alain Greiner  (2016,1017)
    55 *
    6  * This file is part of ALMOS-kernel.
     6 * Copyright (c)  UPMC Sorbonne Universites
    77 *
    8  * ALMOS-kernel is free software; you can redistribute it and/or modify it
     8 * This file is part of ALMOS-MKH.
     9 *
     10 * ALMOS-MKH is free software; you can redistribute it and/or modify it
    911 * under the terms of the GNU General Public License as published by
    1012 * the Free Software Foundation; version 2.0 of the License.
    1113 *
    12  * ALMOS-kernel is distributed in the hope that it will be useful, but
     14 * ALMOS-MKH is distributed in the hope that it will be useful, but
    1315 * WITHOUT ANY WARRANTY; without even the implied warranty of
    1416 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     
    1618 *
    1719 * You should have received a copy of the GNU General Public License
    18  * along with ALMOS-kernel; if not, write to the Free Software Foundation,
     20 * along with ALMOS-MKH; if not, write to the Free Software Foundation,
    1921 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
    2022 */
    2123
     24#include <hal_kernel_types.h>
     25#include <vfs.h>
     26#include <process.h>
     27#include <thread.h>
     28#include <printk.h>
    2229
    23 #include <types.h>
     30#include <syscalls.h>
    2431
    25 int sys_fsync (uint_t fd)
     32/////////////////////////////////
     33int sys_fsync( uint32_t file_id )
    2634{
    27         //TODO
    28         return 0;
     35    printk("\n[ERROR] in %d : not implemented yet\n", __FUNCTION__, file_id );
     36    return ENOSYS;
    2937}
  • trunk/kernel/syscalls/sys_get_config.c

    r625 r626  
    111111
    112112    // copy to user space
    113         hal_copy_to_uspace( x_size  , &k_x_size  , sizeof(uint32_t) );
    114         hal_copy_to_uspace( y_size  , &k_y_size  , sizeof(uint32_t) );
    115         hal_copy_to_uspace( ncores  , &k_ncores  , sizeof(uint32_t) );
     113        hal_copy_to_uspace( local_cxy, &k_x_size, x_size, sizeof(uint32_t) );
     114        hal_copy_to_uspace( local_cxy, &k_y_size, y_size, sizeof(uint32_t) );
     115        hal_copy_to_uspace( local_cxy, &k_ncores, ncores, sizeof(uint32_t) );
    116116
    117117    hal_fence();
  • trunk/kernel/syscalls/sys_get_core.c

    r625 r626  
    8282
    8383    // copy to user space
    84         hal_copy_to_uspace( cxy , &k_cxy , sizeof(uint32_t) );
    85         hal_copy_to_uspace( lid , &k_lid , sizeof(uint32_t) );
     84        hal_copy_to_uspace( local_cxy, &k_cxy, cxy, sizeof(uint32_t) );
     85        hal_copy_to_uspace( local_cxy, &k_lid, lid, sizeof(uint32_t) );
    8686
    8787        return 0;
  • trunk/kernel/syscalls/sys_get_cycle.c

    r625 r626  
    6464
    6565    // copy to user space
    66         hal_copy_to_uspace( cycle , &k_cycle , sizeof(uint64_t) );
     66        hal_copy_to_uspace( local_cxy, &k_cycle, cycle, sizeof(uint64_t) );
    6767
    6868        return 0;
  • trunk/kernel/syscalls/sys_is_fg.c

    r625 r626  
    9191
    9292    // copy to user space
    93     hal_copy_to_uspace( is_fg , &is_txt_owner , sizeof(uint32_t) );
     93    hal_copy_to_uspace( local_cxy, &is_txt_owner, is_fg, sizeof(uint32_t) );
    9494
    9595    hal_fence();
  • trunk/kernel/syscalls/sys_mmap.c

    r625 r626  
    7777
    7878    // copy attributes from user space to kernel space
    79     hal_copy_from_uspace( &k_attr , attr , sizeof(mmap_attr_t) );
     79    hal_copy_from_uspace( local_cxy,
     80                          &k_attr,
     81                          attr,
     82                          sizeof(mmap_attr_t) );
    8083
    8184    // get addr, fdid, offset, and length attributes
     
    305308
    306309    // copy vseg base address to user space
    307     hal_copy_to_uspace( &attr->addr , &vseg->min , sizeof(intptr_t) );
    308 
     310    hal_copy_to_uspace( local_cxy,
     311                        &vseg->min,
     312                        &attr->addr,
     313                        sizeof(intptr_t) );
    309314    hal_fence();
    310315
  • trunk/kernel/syscalls/sys_opendir.c

    r625 r626  
    175175
    176176    // set ident value in user buffer
    177     hal_copy_to_uspace( dirp , &ident , sizeof(intptr_t) );
     177    hal_copy_to_uspace( local_cxy,
     178                        &ident,
     179                        dirp,
     180                        sizeof(intptr_t) );
    178181
    179182    hal_fence();
  • trunk/kernel/syscalls/sys_readdir.c

    r625 r626  
    22 * sys_readdir.c - Copy one entry from an open VFS directory to an user buffer.
    33 *
    4  * Author    Alain Greiner (2016,2017,2018)
     4 * Author    Alain Greiner (2016,2017,2018,2019)
    55 *
    66 * Copyright (c) UPMC Sorbonne Universites
     
    113113
    114114    // copy dirent pointer to user buffer
    115     hal_copy_to_uspace( buffer, &direntp , sizeof(void *) );
     115    hal_copy_to_uspace( local_cxy,
     116                        &direntp,
     117                        buffer,
     118                        sizeof(void *) );
    116119
    117120    // update current index in user_dir structure
  • trunk/kernel/syscalls/sys_sem.c

    r624 r626  
    139139 
    140140            // return value to user
    141             hal_copy_to_uspace( current_value , &current , sizeof(uint32_t) );
     141            hal_copy_to_uspace( local_cxy,
     142                                &current,
     143                                current_value,
     144                                sizeof(uint32_t) );
    142145        }
    143146        break;
  • trunk/kernel/syscalls/sys_stat.c

    r624 r626  
    122122   
    123123    // copy k_stat to u_stat
    124     hal_copy_to_uspace( u_stat , &k_stat , sizeof(struct stat) );
     124    hal_copy_to_uspace( local_cxy,
     125                        &k_stat,
     126                        u_stat,
     127                        sizeof(struct stat) );
    125128
    126129    hal_fence();
  • trunk/kernel/syscalls/sys_thread_create.c

    r624 r626  
    106106            }
    107107       
    108             hal_copy_from_uspace( &kern_attr , user_attr , sizeof(pthread_attr_t) );
     108            hal_copy_from_uspace( local_cxy,
     109                              &kern_attr,
     110                              user_attr,
     111                              sizeof(pthread_attr_t) );
    109112    }
    110113
     
    212215        // returns trdid to user space
    213216        trdid = hal_remote_l32( XPTR( child_cxy , &child_ptr->trdid ) );
    214         hal_copy_to_uspace( trdid_ptr , &trdid , sizeof(pthread_t) );
     217        hal_copy_to_uspace( local_cxy,
     218                        &trdid,
     219                        trdid_ptr,
     220                        sizeof(pthread_t) );
    215221
    216222    // activate new thread
  • trunk/kernel/syscalls/sys_timeofday.c

    r624 r626  
    8383
    8484    // copy values to user space
    85         hal_copy_to_uspace( tv , &k_tv , sizeof(struct timeval) );
     85        hal_copy_to_uspace( local_cxy,
     86                        &k_tv,
     87                        tv,
     88                        sizeof(struct timeval) );
    8689
    8790    hal_fence();
  • trunk/kernel/syscalls/sys_wait.c

    r625 r626  
    154154#endif
    155155                 // return child termination state  to parent process
    156                  hal_copy_to_uspace( status , &child_state , sizeof(int) );
     156                 hal_copy_to_uspace( local_cxy,
     157                                     &child_state,
     158                                     status,
     159                                     sizeof(int) );
    157160                 return child_pid;
    158161            }
  • trunk/kernel/syscalls/syscalls.h

    r623 r626  
    22 * syscalls.h - Kernel side services for syscall handling.
    33 *
    4  * Author     Alain Greiner (2016,2017,2018)
     4 * Author     Alain Greiner (2016,2017,2018,2019)
    55 *
    66 * Copyright (c) UPMC Sorbonne Universites
     
    584584 * [43] This debug function displays on the kernel terminal TXT0 an user defined string,
    585585 * or the current state of a kernel structure, identified by the <type> argument.
    586  * The <arg0>, <arg1>, and <arg2> arguments depends on the structure type:
    587  * - DISPLAY_STRING          : an user defined string
    588  * - DISPLAY_VMM             : VSL and GPT for a process identified by <pid>.
    589  * - DISPLAY_SCHED           : all threads allocated to a scheduler <cxy> & <lid>.
    590  * - DISPLAY_CLUSTER_PROCESS : all processes registered in a cluster identified by <cxy>. 
    591  * - DISPLAY_TXT_PROCESS     : all processes registered in a cluster identified by <cxy>. 
    592  * - DISPLAY_VFS             : all files registered in the VFS cache.
    593  * - DISPLAY_CHDEV           : all registered channel devices.
    594  * - DISPLAY_DQDT            : all DQDT nodes curren values.
    595  * - DISPLAY_BUSYLOCKS       : all busylocks taken by one thread.
    596  * - DISPLAY_MAPPER          : one page of a given mapper.
     586 * The <arg0>, <arg1>, and <arg2> arguments depends on the structure type.
    597587 ******************************************************************************************
    598588 * type      : [in] type of display
     
    671661
    672662/******************************************************************************************
    673  * [50] This function implements the exit system call terminating a POSIX process.
     663 * [50] This function implements the "exit" system call terminating a POSIX process.
    674664 * It can be called by any thread running in any cluster.
    675665 * It uses both remote accesses to access the owner process descriptor, and the
    676  * RPC_PROCESS_SIGACTION to delete remote process and thread descriptors.
     666 * RPC_PROCESS_SIGACTION to delete remote process copies and thread descriptors.
    677667 * In the present implementation, this function implements actually the _exit():
    678668 * - it does not flush open output streams.
    679669 * - it does not close open streams.
    680670 ******************************************************************************************
    681  * @ status   : terminaison status.
     671 * @ status   : terminaison status returned to parent process.
     672 * @ return 0 if success / return -1 if failure.
    682673 *****************************************************************************************/
    683674int sys_exit( uint32_t status );
    684675
     676/******************************************************************************************
     677 * [51] This function implements the "sync" system call.
     678 * It forces all modified pages in all kernel mappers to be copied to the IOC device.
     679 * It can be called by any thread running in any cluster.
     680 * TODO not implemented yet.
     681 ******************************************************************************************
     682 * @ return 0 if success / return -1 if failure.
     683 *****************************************************************************************/
     684int sys_sync( void );
     685
     686/******************************************************************************************
     687 * [52] This function implements the "fsync" system call.
     688 * It forces all modified pages of the file mapper identified by the <fd> argument
     689 * to be copied to the IOC device.
     690 * It can be called by any thread running in any cluster.
     691 * TODO not implemented yet.
     692 ******************************************************************************************
     693 * @ file_id   : file descriptor index in fd_array.
     694 * @ return 0 if success / return -1 if failure.
     695 *****************************************************************************************/
     696int sys_fsync( uint32_t file_id );
     697
    685698#endif  // _SYSCALLS_H_
Note: See TracChangeset for help on using the changeset viewer.