Index: trunk/kernel/fs/fatfs.c
===================================================================
--- trunk/kernel/fs/fatfs.c	(revision 647)
+++ trunk/kernel/fs/fatfs.c	(revision 656)
@@ -850,4 +850,156 @@
 
 }  // end fatfs_recursive_release()
+
+
+//////////////////////////////////////////////////////////////////////////////////////////
+// This static function access the FAT (File Allocation Table), stored in the FAT mapper,
+// and returns in <searched_cluster_id> the FATFS cluster_id for a given page of a given 
+// inode, identified by the <searched_page_id> argument, that is the page index in file
+// (i.e. the page index in file mapper). The entry point in the FAT is defined by the
+// <first_cluster_id> argument, that is the cluster_id of an already allocated cluster.
+// It can be the cluster_id of the first page of the file (always registered in the
+// fatfs_inode extension), or any page of the file whose <first_page_id> argument
+// is smaller than the searched <first_page_id> argument. 
+// This function can be called by a thread running in any cluster, as it uses remote
+// access primitives when the FAT mapper is remote.
+// The FAT mapper being a WRITE-THROUGH cache, this function updates the FAT mapper 
+// from informations stored on IOC device in case of miss when scanning the FAT mapper.
+// The searched inode mapper being a WRITE-BACK cache, this function allocates a new
+// cluster_id when the searched page exist in the inode mapper, and there is no FATFS 
+// cluster allocated yet for this page. It updates the FAT, but it does NOT copy the
+// mapper page content to the File System.
+//////////////////////////////////////////////////////////////////////////////////////////
+// @ first_page_id       : [in]  index in file mapper for an existing page.
+// @ first_cluster_id	 : [in]  cluster_id for this existing page. 
+// @ searched_page_id    : [in]  index in file mapper for the searched page.
+// @ searched_cluster_id : [out] cluster_id for the searched page.
+// @ return 0 if success / return -1 if a FAT mapper miss cannot be solved,
+//                         or if a missing cluster_id cannot be allocated.
+//////////////////////////////////////////////////////////////////////////////////////////
+static error_t fatfs_get_cluster( uint32_t   first_page_id,
+                                  uint32_t   first_cluster_id,
+                                  uint32_t   searched_page_id,
+                                  uint32_t * searched_cluster_id )
+{
+    uint32_t   current_page_id;        // index of page in file mapper
+    uint32_t   current_cluster_id;     // index of cluster in FATFS
+    xptr_t     lock_xp;                // extended pointer on FAT lock
+
+assert( (searched_page_id > first_page_id) ,
+"searched_page_id must be larger than first_page_id\n");
+
+#if DEBUG_FATFS_GET_CLUSTER
+uint32_t   cycle = (uint32_t)hal_get_cycles();
+thread_t * this  = CURRENT_THREAD;
+if( DEBUG_FATFS_GET_CLUSTER < cycle )
+printk("\n[%s] thread[%x,%x] enter / first_cluster_id %x / searched_page_id %d / cycle %d\n",
+__FUNCTION__, this->process->pid, this->trdid, first_cluster_id, searched_page_id, cycle );
+#endif
+
+    // get local pointer on VFS context (same in all clusters)
+    vfs_ctx_t * vfs_ctx = &fs_context[FS_TYPE_FATFS];
+
+    // get local pointer on local FATFS context
+    fatfs_ctx_t * loc_fatfs_ctx = vfs_ctx->extend;
+
+    // get extended pointer and cluster on FAT mapper
+    xptr_t fat_mapper_xp  = loc_fatfs_ctx->fat_mapper_xp;
+    cxy_t  fat_cxy        = GET_CXY( fat_mapper_xp );
+
+    // get local pointer on FATFS context in FAT cluster 
+    fatfs_ctx_t * fat_fatfs_ctx = hal_remote_lpt( XPTR( fat_cxy , &vfs_ctx->extend ) );
+
+    // build extended pointer on FAT lock in FAT cluster
+    lock_xp = XPTR( fat_cxy , &fat_fatfs_ctx->lock );
+
+    // take FAT lock in read mode
+    remote_rwlock_rd_acquire( lock_xp );
+
+    // initialize loop variables
+    current_page_id    = first_page_id;
+    current_cluster_id = first_cluster_id;
+
+    // scan FAT mapper (i.e. traverse FAT linked list)
+    // starting from first_page_id until searched_page_id 
+    // each iteration in this loop can change both
+    // the FAT page index and the slot index in FAT 
+    while( current_page_id < searched_page_id )
+    {
+        // FAT mapper page and slot indexes (1024 slots per FAT page)
+        uint32_t fat_page_index   = current_cluster_id >> 10;
+        uint32_t fat_slot_index   = current_cluster_id & 0x3FF;
+
+        // get pointer on current page descriptor in FAT mapper
+        xptr_t current_page_xp = mapper_remote_get_page( fat_mapper_xp , fat_page_index );
+
+        if( current_page_xp == XPTR_NULL )
+        {
+            printk("\n[ERROR] in %s : cannot get page %d from FAT mapper\n",
+            __FUNCTION__ , fat_page_index );
+            remote_rwlock_rd_release( lock_xp );
+            return -1;
+        }
+
+        // get pointer on buffer containing the FAT mapper page
+        xptr_t base_xp = ppm_page2base( current_page_xp );
+        uint32_t * buffer = (uint32_t *)GET_PTR( base_xp );
+
+        // get next_cluster_id from FAT slot  
+        uint32_t next_cluster_id = hal_remote_l32( XPTR( fat_cxy, &buffer[fat_slot_index] ) );
+
+        // allocate a new FAT cluster when there is no cluster
+        // allocated on device for the current page
+        if( next_cluster_id >= END_OF_CHAIN_CLUSTER_MIN ) 
+        {
+            // release the FAT lock in read mode,
+            remote_rwlock_rd_release( lock_xp );
+
+            // allocate a new cluster_id (and update both FAT mapper and FAT on device).
+            error_t error = fatfs_cluster_alloc( &next_cluster_id );
+
+            if( error )
+            {
+                printk("\n[ERROR] in %s : cannot allocate cluster on FAT32 for page %d\n",
+                __FUNCTION__ , current_page_id );
+                remote_rwlock_wr_release( lock_xp );
+                return -1;
+            }
+
+#if (DEBUG_FATFS_GET_CLUSTER & 1)
+if( DEBUG_FATFS_GET_CLUSTER < cycle )
+printk("\n[%s] allocated a new cluster_id %d in FATFS\n",
+__FUNCTION__, next_cluster_id );
+#endif
+            // take the FAT lock in read mode,
+            remote_rwlock_rd_acquire( lock_xp );
+        }
+
+#if (DEBUG_FATFS_GET_CLUSTER & 1)
+if( DEBUG_FATFS_GET_CLUSTER < cycle )
+printk("\n[%s] traverse FAT / fat_page_index %d / fat_slot_index %d / next_cluster_id %x\n",
+__FUNCTION__, fat_page_index, fat_slot_index , next_cluster_id );
+#endif
+
+        // update loop variables
+        current_cluster_id = next_cluster_id;
+        current_page_id++;
+    }
+   
+    // release FAT lock
+    remote_rwlock_rd_release( lock_xp );
+
+#if DEBUG_FATFS_GET_CLUSTER
+if( DEBUG_FATFS_GET_CLUSTER < cycle )
+printk("\n[%s] thread[%x,%x] exit / searched_cluster_id = %d\n",
+__FUNCTION__, this->process->pid, this->trdid, current_cluster_id );
+#endif
+
+    *searched_cluster_id = current_cluster_id;
+    return 0;
+
+}  // end fatfs_get_cluster()
+
+
+
 
 
@@ -904,12 +1056,12 @@
 //////////////////////////////////////////
 void fatfs_display_fat( uint32_t  page_id,
-                        uint32_t  nentries )
+                        uint32_t  min_slot,
+                        uint32_t  nb_slots )
 {
     uint32_t line;
-    uint32_t maxline;
 
     // compute number of lines to display
-    maxline = nentries >> 3;
-    if( nentries & 0x7 ) maxline++;
+    uint32_t min_line = min_slot >> 3;
+    uint32_t max_line = (min_slot + nb_slots - 1) >> 3;
 
     // get pointer on local FATFS context
@@ -917,30 +1069,28 @@
     fatfs_ctx_t * loc_fatfs_ctx = (fatfs_ctx_t *)vfs_ctx->extend;
 
-    // get extended pointer on FAT mapper
-    xptr_t fat_mapper_xp  = loc_fatfs_ctx->fat_mapper_xp;
-
-    // get FAT cluster identifier
-    cxy_t  fat_cxy = GET_CXY( fat_mapper_xp );
+    // get pointers on FAT mapper (in FAT cluster)
+    xptr_t     mapper_xp  = loc_fatfs_ctx->fat_mapper_xp;
+    cxy_t      mapper_cxy = GET_CXY( mapper_xp );
 
     // get pointer on FATFS context in FAT cluster
-    fatfs_ctx_t * fat_fatfs_ctx = hal_remote_lpt( XPTR( fat_cxy , &vfs_ctx->extend ) );
+    fatfs_ctx_t * fat_fatfs_ctx = hal_remote_lpt( XPTR( mapper_cxy , &vfs_ctx->extend ) );
  
     // get current value of hint and free_clusters
-    uint32_t hint = hal_remote_l32( XPTR( fat_cxy , &fat_fatfs_ctx->free_cluster_hint ) );
-    uint32_t free = hal_remote_l32( XPTR( fat_cxy , &fat_fatfs_ctx->free_clusters ) );
- 
-    // get extended pointer on requested page in FAT mapper 
-    xptr_t     page_xp  = mapper_remote_get_page( fat_mapper_xp , page_id );
-
-    // get extended pointer on requested page base
+    uint32_t hint = hal_remote_l32( XPTR( mapper_cxy , &fat_fatfs_ctx->free_cluster_hint ) );
+    uint32_t free = hal_remote_l32( XPTR( mapper_cxy , &fat_fatfs_ctx->free_clusters ) );
+
+    // get extended pointer on requested page descriptor in FAT mapper 
+    xptr_t page_xp = mapper_remote_get_page( mapper_xp , page_id );
+
+    // get pointers on requested page base
     xptr_t     base_xp  = ppm_page2base( page_xp );
     void     * base     = GET_PTR( base_xp );
 
     printk("\n***** FAT mapper / cxy %x / page_id %d / base %x / free_clusters %x / hint %x\n",
-    fat_cxy, page_id, base, free, hint );
-
-    for( line = 0 ; line < maxline ; line++ )
-    {
-        printk("%x : %X | %X | %X | %X | %X | %X | %X | %X\n", (line<<3),
+    mapper_cxy, page_id, base, free, hint );
+
+    for( line = min_line ; line <= max_line ; line++ )
+    {
+        printk("%d : %X | %X | %X | %X | %X | %X | %X | %X\n", (line<<3),
         hal_remote_l32( base_xp + ((line<<5)      ) ),
         hal_remote_l32( base_xp + ((line<<5) + 4  ) ),
@@ -954,107 +1104,4 @@
 
 }  // end fatfs_display_fat()
-
-///////////////////////////////////////////////////////
-error_t fatfs_get_cluster( uint32_t   first_cluster_id,
-                           uint32_t   searched_page_index,
-                           uint32_t * searched_cluster_id )
-{
-    xptr_t     current_page_xp;        // pointer on current page descriptor
-    uint32_t * buffer;                 // pointer on current page (array of uint32_t)
-    uint32_t   current_page_index;     // index of current page in FAT 
-    uint32_t   current_slot_index;     // index of slot in current page
-    uint32_t   page_count_in_file;     // index of page in file (index in linked list)
-    uint32_t   next_cluster_id;        // content of current FAT slot
-    xptr_t     lock_xp;                // extended pointer on FAT lock
-
-assert( (searched_page_index > 0) ,
-"no FAT access required for first page\n");
-
-#if DEBUG_FATFS_GET_CLUSTER
-uint32_t   cycle = (uint32_t)hal_get_cycles();
-thread_t * this  = CURRENT_THREAD;
-if( DEBUG_FATFS_GET_CLUSTER < cycle )
-printk("\n[%s] thread[%x,%x] enter / first_cluster_id %d / searched_index %d / cycle %d\n",
-__FUNCTION__, this->process->pid, this->trdid, first_cluster_id, searched_page_index, cycle );
-#endif
-
-    // get local pointer on VFS context (same in all clusters)
-    vfs_ctx_t * vfs_ctx = &fs_context[FS_TYPE_FATFS];
-
-    // get local pointer on local FATFS context
-    fatfs_ctx_t * loc_fatfs_ctx = vfs_ctx->extend;
-
-    // get extended pointer and cluster on FAT mapper
-    xptr_t fat_mapper_xp  = loc_fatfs_ctx->fat_mapper_xp;
-    cxy_t  fat_cxy        = GET_CXY( fat_mapper_xp );
-
-    // get local pointer on FATFS context in FAT cluster 
-    fatfs_ctx_t * fat_fatfs_ctx = hal_remote_lpt( XPTR( fat_cxy , &vfs_ctx->extend ) );
-
-    // build extended pointer on FAT lock in FAT cluster
-    lock_xp = XPTR( fat_cxy , &fat_fatfs_ctx->lock );
-
-    // take FAT lock in read mode
-    remote_rwlock_rd_acquire( lock_xp );
-
-    // initialize loop variable (1024 slots per page)
-    current_page_index  = first_cluster_id >> 10;
-    current_slot_index  = first_cluster_id & 0x3FF;
-    page_count_in_file  = 0;
-    next_cluster_id     = 0xFFFFFFFF;
-
-    // scan FAT mapper (i.e. traverse FAT linked list)
-    while( page_count_in_file < searched_page_index )
-    {
-        // get pointer on current page descriptor in FAT mapper
-        current_page_xp = mapper_remote_get_page( fat_mapper_xp , current_page_index );
-
-        if( current_page_xp == XPTR_NULL )
-        {
-            printk("\n[ERROR] in %s : cannot get next page from FAT mapper\n", __FUNCTION__);
-            remote_rwlock_rd_release( lock_xp );
-            return -1;
-        }
-
-        // get pointer on buffer for current page
-        xptr_t base_xp = ppm_page2base( current_page_xp );
-        buffer = (uint32_t *)GET_PTR( base_xp );
-
-        // get FAT slot content 
-        next_cluster_id = hal_remote_l32( XPTR( fat_cxy, &buffer[current_slot_index] ) );
-
-#if (DEBUG_FATFS_GET_CLUSTER & 1)
-if( DEBUG_FATFS_GET_CLUSTER < cycle )
-printk("\n[%s] traverse FAT / current_page_index = %d\n"
-"current_slot_index = %d / next_cluster_id = %d\n",
-__FUNCTION__, current_page_index, current_slot_index , next_cluster_id );
-#endif
-        // update loop variables
-        current_page_index = next_cluster_id >> 10;
-        current_slot_index = next_cluster_id & 0x3FF;
-        page_count_in_file++;
-    }
-
-    if( next_cluster_id == 0xFFFFFFFF )
-    {
-        printk("\n[ERROR] in %s : searched_cluster_id not found in FAT\n", __FUNCTION__ );
-        remote_rwlock_rd_release( lock_xp );
-        return -1;
-    }
-   
-    // release FAT lock
-    remote_rwlock_rd_release( lock_xp );
-
-#if DEBUG_FATFS_GET_CLUSTER
-cycle = (uint32_t)hal_get_cycles();
-if( DEBUG_FATFS_GET_CLUSTER < cycle )
-printk("\n[%s] thread[%x,%x] exit / searched_cluster_id = %d / cycle %d\n",
-__FUNCTION__, this->process->pid, this->trdid, next_cluster_id / cycle );
-#endif
-
-    *searched_cluster_id = next_cluster_id;
-    return 0;
-
-}  // end fatfs_get_cluster()
 
 
@@ -1691,5 +1738,5 @@
 // by the <mapper> argument, to find the directory entry identified by the <name> argument,
 // and return a pointer on the directory entry, described as and array of 32 bytes, and the
-// incex of this entry in the FAT32 mapper, seen as an array of 32 bytes entries.
+// index of this entry in the FAT32 mapper, seen as an array of 32 bytes entries.
 // It is called by the fatfs_new_dentry() and fatfs_update_dentry() functions.
 // It must be called by a thread running in the cluster containing the mapper.
@@ -1701,8 +1748,8 @@
 // @ return 0 if found / return 1 if not found / return -1 if mapper access error. 
 //////////////////////////////////////////////////////////////////////////////////////////////
-error_t fatfs_scan_directory( mapper_t *  mapper,
-                              char     *  name,
-                              uint8_t  ** entry,
-                              uint32_t *  index )
+static error_t fatfs_scan_directory( mapper_t *  mapper,
+                                     char     *  name,
+                                     uint8_t  ** entry,
+                                     uint32_t *  index )
 {
     // Two embedded loops to scan the directory mapper:
@@ -1725,5 +1772,5 @@
 #endif
 
-    char       cname[CONFIG_VFS_MAX_NAME_LENGTH];  // name extracted from each directory entry
+    char       cname[CONFIG_VFS_MAX_NAME_LENGTH];  // name extracted from directory entry
 
     char       lfn1[16];         // buffer for one partial cname
@@ -1761,5 +1808,5 @@
 #if (DEBUG_FATFS_SCAN_DIRECTORY & 0x1)
 if( DEBUG_FATFS_SCAN_DIRECTORY < cycle )
-mapper_display_page( mapper_xp , page_id , 256 );
+mapper_display_page( mapper_xp , page_xp , 256 );
 #endif
         // scan this page until end of directory, end of page, or name found
@@ -1883,5 +1930,5 @@
     error_t        error;
 
-    char           dir_name[CONFIG_VFS_MAX_NAME_LENGTH];
+    char           parent_name[CONFIG_VFS_MAX_NAME_LENGTH];
 
 // check arguments
@@ -1900,11 +1947,11 @@
 assert( (xlist_is_empty( root_xp ) == false ), "child inode must have one parent\n");
 
-#if DEBUG_FATFS_GET_DENTRY
+#if DEBUG_FATFS_NEW_DENTRY
 uint32_t   cycle = (uint32_t)hal_get_cycles();
 thread_t * this  = CURRENT_THREAD;
-vfs_inode_get_name( XPTR( local_cxy , parent_inode ) , dir_name );
-if( DEBUG_FATFS_GET_DENTRY < cycle )
+vfs_inode_get_name( XPTR( local_cxy , parent_inode ) , parent_name );
+if( DEBUG_FATFS_NEW_DENTRY < cycle )
 printk("\n[%s]  thread[%x,%x] enter for child <%s> in parent <%s> / cycle %d\n",
-__FUNCTION__, this->process->pid, this->trdid, name , dir_name , cycle );
+__FUNCTION__, this->process->pid, this->trdid, name , parent_name , cycle );
 #endif
 
@@ -1916,5 +1963,12 @@
 
     // return non fatal error if not found
-    if( error ) return -1;
+    if( error )
+    {
+        vfs_inode_get_name( XPTR( local_cxy , parent_inode ) , parent_name );
+        printk("\n[ERROR] in %s : cannot find <%s> entry in <%s> directory mapper\n",
+        __FUNCTION__, name , parent_name, name );
+        return -1;
+    }
+  
 
     // get relevant infos from FAT32 directory entry
@@ -1946,7 +2000,7 @@
     if( found == false )
     { 
-        vfs_inode_get_name( XPTR( local_cxy , parent_inode ) , dir_name );
+        vfs_inode_get_name( XPTR( local_cxy , parent_inode ) , parent_name );
         printk("\n[ERROR] in %s : cannot find <%s> directory in list of parents for <%s>\n",
-        __FUNCTION__, dir_name, name );
+        __FUNCTION__, parent_name, name );
         return -1;
     }
@@ -1962,9 +2016,18 @@
     dentry_ptr->extend = (void *)(intptr_t)index;
 
-#if DEBUG_FATFS_GET_DENTRY
+#if DEBUG_FATFS_NEW_DENTRY
 cycle = (uint32_t)hal_get_cycles();
-if( DEBUG_FATFS_GET_DENTRY < cycle )
-printk("\n[%s]  thread[%x,%x] exit / intialised inode & dentry for <%s> in <%s> / cycle %d\n",
-__FUNCTION__, this->process->pid, this->trdid, name, dir_name, cycle );
+if( DEBUG_FATFS_NEW_DENTRY < cycle )
+printk("\n[%s]  thread[%x,%x] exit for <%s> in <%s> / cluster_id %x / size %d  / cycle %d\n",
+__FUNCTION__, this->process->pid, this->trdid, name, parent_name, cluster, size,  cycle );
+#endif
+
+
+#if (DEBUG_FATFS_NEW_DENTRY & 1)
+if( DEBUG_FATFS_NEW_DENTRY < cycle )
+{
+    fatfs_display_fat( 0 , 0 , 64 );
+    fatfs_display_fat( cluster >> 10 ,  (cluster & 0x3FF) , 32 );
+}
 #endif
 
@@ -1988,5 +2051,4 @@
 assert( (inode  != NULL) , "inode is NULL\n" );
 assert( (dentry != NULL) , "dentry is NULL\n" );
-assert( (size   != 0   ) , "size is 0\n" );
 
 #if DEBUG_FATFS_UPDATE_DENTRY
@@ -2013,22 +2075,29 @@
     }
 
-    // set size in FAT32 directory entry
-    fatfs_set_record( DIR_FILE_SIZE , entry , size );
-
-    // get local pointer on modified page base
-    void * base = (void *)((intptr_t)entry & (~CONFIG_PPM_PAGE_MASK)); 
-
-    // get extended pointer on modified page descriptor
-    xptr_t page_xp = ppm_base2page( XPTR( local_cxy , base ) );
-
-    // synchronously update the modified page on device
-    error = fatfs_move_page( page_xp , IOC_SYNC_WRITE );
-
-    if( error )
-    { 
-        vfs_inode_get_name( XPTR( local_cxy , inode ) , dir_name );
-        printk("\n[ERROR] in %s : cannot update parent directory <%s> on device\n",
-        __FUNCTION__, dir_name );
-        return -1;
+    // get current size value
+    uint32_t current_size = fatfs_get_record( DIR_FILE_SIZE , entry );
+
+    // update dentry in mapper & device only if required
+    if( size != current_size )
+    {
+        // set size field in FAT32 directory entry
+        fatfs_set_record( DIR_FILE_SIZE , entry , size );
+
+        // get pointer on modified page base
+        void * base = (void *)((intptr_t)entry & (~CONFIG_PPM_PAGE_MASK)); 
+
+        // get extended pointer on modified page descriptor
+        xptr_t page_xp = ppm_base2page( XPTR( local_cxy , base ) );
+
+        // synchronously update the modified page on device
+        error = fatfs_move_page( page_xp , IOC_SYNC_WRITE );
+
+        if( error )
+        { 
+            vfs_inode_get_name( XPTR( local_cxy , inode ) , dir_name );
+            printk("\n[ERROR] in %s : cannot update parent directory <%s> on device\n",
+            __FUNCTION__, dir_name );
+            return -1;
+        }
     }
 
@@ -2586,5 +2655,5 @@
     return 0;
 
-}  // end fat_cluster_alloc()
+}  // end fatfs_cluster_alloc()
 
 //////////////////////////////////////////////
@@ -2737,5 +2806,5 @@
 #endif
 
-    // get page cluster an local pointer
+    // get page cluster and local pointer
     cxy_t    page_cxy = GET_CXY( page_xp );
     page_t * page_ptr = GET_PTR( page_xp );
@@ -2754,14 +2823,13 @@
     inode_ptr  = hal_remote_lpt( XPTR( page_cxy , &mapper_ptr->inode ) );
 
+    //////////////////////////////  FAT mapper  /////////////////////////////////////////
+    if( inode_ptr == NULL )
+    {
+
 #if DEBUG_FATFS_MOVE_PAGE
 if( DEBUG_FATFS_MOVE_PAGE < cycle )
-printk("\n[%s] thread[%x,%x] enters : %s / cxy %x / mapper %x / inode %x / page %x\n",
-__FUNCTION__, this->process->pid, this->trdid,
-dev_ioc_cmd_str( cmd_type ), page_cxy, mapper_ptr, inode_ptr, GET_PTR(buffer_xp) );
-#endif
-
-    //////////////////////////////  FAT mapper
-    if( inode_ptr == NULL )
-    {
+printk("\n[%s] thread[%x,%x] enters for %s /  page %d in FAT mapper / cycle %d\n",
+__FUNCTION__, this->process->pid, this->trdid, dev_ioc_cmd_str(cmd_type), page_id, cycle );
+#endif
         // get lba from FATFS context and page_id 
         uint32_t      lba = fatfs_ctx->fat_begin_lba + (page_id << 3);
@@ -2778,16 +2846,10 @@
 #if DEBUG_FATFS_MOVE_PAGE
 if( DEBUG_FATFS_MOVE_PAGE < cycle )
-{
-    if ( (cmd_type == IOC_READ) || (cmd_type == IOC_SYNC_READ) )
-        printk("\n[%s] thread[%x,%x] load FAT mapper page %d from IOC / cycle %d\n",
-        __FUNCTION__, this->process->pid, this->trdid, page_id, cycle );
-    else
-        printk("\n[%s] thread[%x,%x] sync FAT mapper page %d to IOC / cycle %d\n",
-        __FUNCTION__, this->process->pid, this->trdid, page_id, cycle );
-}
-#endif
-
-    }
-    /////////////////////////  inode mapper
+printk("\n[%s] thread[%x,%x] exit / page %d in FAT mapper\n",
+__FUNCTION__, this->process->pid, this->trdid, page_id, cycle );
+#endif
+
+    }
+    /////////////////////////  inode mapper  ////////////////////////////////////////////
     else                       
     {
@@ -2795,28 +2857,33 @@
 #if DEBUG_FATFS_MOVE_PAGE
 vfs_inode_get_name( XPTR( page_cxy , inode_ptr ) , name );
-#endif
-
-        uint32_t  searched_cluster;
-        uint32_t  first_cluster;
-
-        // get first_cluster from inode extension
-        void * extend = hal_remote_lpt( XPTR( page_cxy , &inode_ptr->extend ) );
-        first_cluster = (uint32_t)(intptr_t)extend;
-
-        // compute searched_cluster
+if( DEBUG_FATFS_MOVE_PAGE < cycle )
+printk("\n[%s] thread[%x,%x] enters for %s / page %d in <%s> mapper/ cycle %d\n",
+__FUNCTION__, this->process->pid, this->trdid, 
+dev_ioc_cmd_str( cmd_type ), page_id, name, cycle );
+#endif
+
+        uint32_t  searched_cluster_id;
+        uint32_t  first_cluster_id;
+
+        // get first_cluster_id from inode extension
+        void * extend    = hal_remote_lpt( XPTR( page_cxy , &inode_ptr->extend ) );
+        first_cluster_id = (uint32_t)(intptr_t)extend;
+
+        // compute searched_cluster_id
         if( page_id == 0 )            // no need to access FAT mapper
         {
             // searched cluster is first cluster
-            searched_cluster = first_cluster;
+            searched_cluster_id = first_cluster_id;
         }
         else                        // FAT mapper access required
         {
-            // access FAT mapper to get searched cluster
-            error = fatfs_get_cluster( first_cluster,
+            // scan FAT mapper to get searched_cluster_id
+            error = fatfs_get_cluster( 0,                    // first page in mapper
+                                       first_cluster_id,
                                        page_id,
-                                       &searched_cluster );
+                                       &searched_cluster_id );
             if( error )
             {
-                printk("\n[ERROR] in %s : cannot access FAT mapper\n", __FUNCTION__ );
+                printk("\n[ERROR] in %s : cannot get cluster_id\n", __FUNCTION__ );
                 return -1;
             }
@@ -2824,7 +2891,7 @@
 
         // get lba for searched_cluster
-        uint32_t lba = fatfs_lba_from_cluster( fatfs_ctx , searched_cluster );
-
-        // access IOC device
+        uint32_t lba = fatfs_lba_from_cluster( fatfs_ctx , searched_cluster_id );
+
+        // access IOC device to move 8 blocks
         error = dev_ioc_move_data( cmd_type , buffer_xp , lba , 8 );
 
@@ -2837,12 +2904,7 @@
 #if DEBUG_FATFS_MOVE_PAGE
 if( DEBUG_FATFS_MOVE_PAGE < cycle )
-{
-    if ( (cmd_type == IOC_READ) || (cmd_type == IOC_SYNC_READ) )
-    printk("\n[%s] thread[%x,%x] load page %d of <%s> / cluster_id %x / cycle %d\n",
-    __FUNCTION__, this->process->pid, this->trdid, page_id, name, searched_cluster, cycle );
-    else
-    printk("\n[%s] thread[%x,%x] sync page %d of <%s> / cluster_id %x / cycle %d\n",
-    __FUNCTION__, this->process->pid, this->trdid, page_id, name, searched_cluster, cycle );
-}
+vfs_inode_get_name( XPTR( page_cxy, inode_ptr ) , name );
+printk("\n[%s] thread[%x,%x] exit / page %d in <%s> mapper / cluster_id %x\n",
+__FUNCTION__, this->process->pid, this->trdid, page_id, name, searched_cluster_id );
 #endif
 
