Index: soft/giet_vm/giet_fat32/fat32.c
===================================================================
--- soft/giet_vm/giet_fat32/fat32.c	(revision 783)
+++ soft/giet_vm/giet_fat32/fat32.c	(revision 787)
@@ -1,3 +1,3 @@
-/////////////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////////////
 // Date     : 01/06/2015
 // Authors  : Alain Greiner
@@ -148,11 +148,9 @@
 static unsigned int _update_dir_entry( fat_inode_t*  inode );
 
-static unsigned int _add_dir_entry( fat_inode_t* child,
-                                    fat_inode_t* parent );
+static unsigned int _add_dir_entry( fat_inode_t* child );
 
 static unsigned int _remove_dir_entry( fat_inode_t*  inode );
 
-static void _add_special_directories( fat_inode_t* child,
-                                      fat_inode_t* parent );
+static void _add_special_directories( fat_inode_t* child );
 
 static unsigned int _one_cluster_allocate( fat_inode_t*   inode, 
@@ -620,11 +618,4 @@
                                   unsigned int  cluster )
 {
-
-#if GIET_DEBUG_FAT
-if ( _get_proctime() > GIET_DEBUG_FAT )
-_printf("\n[DEBUG FAT] _allocate_one_buffer(): in cache <%s> for cluster_id %d\n",
-        inode->name, cluster_id );
-#endif
-
     // add cache levels if needed
     while ( _get_levels_from_size( (cluster_id + 1) * 4096 ) > inode->levels )
@@ -633,5 +624,6 @@
 #if GIET_DEBUG_FAT
 if ( _get_proctime() > GIET_DEBUG_FAT )
-_printf("\n[DEBUG FAT] _allocate_one_buffer(): adding a cache level\n" );
+_printf("\n[DEBUG FAT] _allocate_one_buffer(): adding a cache level for %s\n",
+        inode->name );
 #endif
 
@@ -834,4 +826,10 @@
                                            unsigned int*  cluster ) 
 {
+
+#if GIET_DEBUG_FAT
+if ( _get_proctime() > GIET_DEBUG_FAT )
+_printf("\n[DEBUG FAT] _one_cluster_allocate(): enter for <%s>\n", inode->name );
+#endif
+
     // Check free cluster available
     if ( _fat.free_clusters_number == 0 )
@@ -887,13 +885,10 @@
     _fat.free_cluster_hint = new;
 
-    if ( nb_current_clusters == 0 )  // first cluster : inode and directory entry
-    {
-        // update inode
+    // update cluster chaining
+    if ( nb_current_clusters == 0 )  // first cluster : update cluster field in inode
+    {
         inode->cluster = new;
-
-        // update directory entry
-        _update_dir_entry( inode );
-    }
-    else                             // update previous last cluster in FAT
+    }
+    else                             // not the last : update previous last cluster in FAT
     {
         if ( _set_fat_entry( last , new ) ) 
@@ -922,7 +917,6 @@
 #if GIET_DEBUG_FAT
 if ( _get_proctime() > GIET_DEBUG_FAT )
-_printf("\n[DEBUG FAT] _one_cluster_allocate(): for <%s>\n"
-        " nb_clusters = %d / last_cluster = %x / new_cluster = %x\n",
-        inode->name , nb_current_clusters , last , new );
+_printf("\n[DEBUG FAT] _one_cluster_allocate(): for <%s> cluster = %x\n",
+        inode->name , new );
 #endif
 
@@ -933,4 +927,6 @@
 }  // end _one_cluster_allocate()
 
+////////////////////////////////////////////////////////////
+// recursive function called by _all_clusters_release()
 ////////////////////////////////////////////////////////////
 static unsigned int _cluster_release( unsigned int cluster )
@@ -1008,8 +1004,7 @@
 
 ///////////////////////////////////////////////////////////
-static void _add_special_directories( fat_inode_t*  child, 
-                                      fat_inode_t*  parent )
-{
-    // get first File-Cache buffer for child
+static void _add_special_directories( fat_inode_t*  child )
+{
+    // get File-Cache buffer for child and cluster_id = 0
     fat_cache_desc_t*   pdesc  = (fat_cache_desc_t*)child->cache->children[0];
     unsigned char*      entry;
@@ -1017,10 +1012,8 @@
     unsigned int i;
     unsigned int cluster;
-    unsigned int size;
 
     // set "." entry (32 bytes)
+    entry   = pdesc->buffer;
     cluster = child->cluster;
-    size    = child->size;
-    entry   = pdesc->buffer;
     
     for ( i = 0 ; i < 32 ; i++ )
@@ -1033,15 +1026,13 @@
         else if (i == 26)     entry[i] = cluster>>0;    // cluster.B0
         else if (i == 27)     entry[i] = cluster>>8;    // cluster.B1
-        else if (i == 28)     entry[i] = size>>0;       // size.B0
-        else if (i == 29)     entry[i] = size>>8;       // size.B1
-        else if (i == 30)     entry[i] = size>>16;      // size.B2
-        else if (i == 31)     entry[i] = size>>24;      // size.B3
         else                  entry[i] = 0x00;
     }
 
     // set ".." entry (32 bytes)
-    cluster = parent->cluster;
-    size    = parent->size;
     entry   = pdesc->buffer + 32;
+    cluster = child->parent->cluster;
+
+    // handling special case when parent is root directory
+    if ( cluster == 2 ) cluster = 0;
 
     for ( i = 0 ; i < 32 ; i++ )
@@ -1054,8 +1045,4 @@
         else if (i == 26)     entry[i] = cluster>>0;    // cluster.B0
         else if (i == 27)     entry[i] = cluster>>8;    // cluster.B1
-        else if (i == 28)     entry[i] = size>>0;       // size.B0
-        else if (i == 29)     entry[i] = size>>8;       // size.B1
-        else if (i == 30)     entry[i] = size>>16;      // size.B2
-        else if (i == 31)     entry[i] = size>>24;      // size.B3
         else                  entry[i] = 0x00;
     }
@@ -1304,7 +1291,6 @@
 
 
-///////////////////////////////////////////////////////////
-static unsigned int _add_dir_entry( fat_inode_t*   child,
-                                    fat_inode_t*   parent )
+//////////////////////////////////////////////////////////
+static unsigned int _add_dir_entry( fat_inode_t*   child )
 {
     // get child attributes
@@ -1312,4 +1298,7 @@
     unsigned int      size    = child->size;
     unsigned int      cluster = child->cluster;
+    fat_inode_t*      parent  = child->parent;
+
+    if ( parent == NULL ) return 1;
 
     // compute number of required 32 bytes entries to store 
@@ -1320,8 +1309,8 @@
     unsigned char   checksum;
     if ( _get_sfn_name( child->name, 
-                             &length,
-                             &nb_lfn,
-                             sfn,
-                             &checksum ) )  return 1;
+                        &length,
+                        &nb_lfn,
+                        sfn,
+                        &checksum ) )  return 1;
 
 #if GIET_DEBUG_FAT
@@ -1379,5 +1368,5 @@
 #endif
 
-    // enter FSM :
+    // enter FSM to modify parent directory:
     // The new child requires to write 3, 4, or 5 directory entries.
     // To actually register the new child, we use a 5 steps FSM
@@ -1536,6 +1525,6 @@
             case 1:   // write NOMORE entry  
             {
+                entry [0] = 0x00;
                 step--;
-                entry [0] = 0x00;
                 break;
             }
@@ -1553,5 +1542,5 @@
 
     return 0;        
-} // end _add_dir_entry
+} // end _add_dir_entry()
 
 
@@ -2531,5 +2520,6 @@
 
         // add an entry in the parent directory Cache_file
-        if ( _add_dir_entry( child , parent ) )
+        // and update the dentry field in child inode
+        if ( _add_dir_entry( child ) )
         {
             _spin_lock_release( &_fat.fat_lock );
@@ -3632,5 +3622,5 @@
                                old->size,
                                0,              // count
-                               0,              // dentry
+                               0,              // dentry set by _add_dir_entry()
                                0 );            // no cache_allocate
  
@@ -3639,6 +3629,10 @@
     new->cache  = old->cache;
 
+    // add "new" to "new_parent" directory in Inode-Tree
+    _add_inode_in_tree( new , new_parent );
+    
     // add "new" to "new_parent" directory File-Cache
-    if ( _add_dir_entry( new , new_parent ) )
+    // and update the dentry field in new inode
+    if ( _add_dir_entry( new ) )
     {
         _spin_lock_release( &_fat.fat_lock );
@@ -3650,7 +3644,4 @@
     }
 
-    // add "new" to "new_parent" directory in Inode-Tree
-    _add_inode_in_tree( new , new_parent );
-    
     // updates "new_parent" directory on device
     if ( _update_device_from_cache( new_parent->levels,
@@ -3796,17 +3787,17 @@
         // allocate a new inode and an empty Cache-File 
         child = _allocate_one_inode( name,
-                                     1,           // it's a directory
-                                     0xFFFFFFFF,  // cluster index not defined yet
-                                     0,           // size = 0 for a directory
-                                     0,           // count
-                                     0,           // dentry set by _add_dir_entry()
-                                     1 );         // cache_allocate
+                                     1,                         // it's a directory
+                                     END_OF_CHAIN_CLUSTER_MAX,  // cluster set later
+                                     0,                         // size = 0 for directory
+                                     0,                         // count
+                                     0,                         // dentry set later
+                                     1 );                       // cache_allocate
 
         // introduce inode in Inode-Tree
         _add_inode_in_tree( child , parent );
  
-        // allocate cluster from FAT
+        // allocate one cluster from FAT for child
         unsigned int cluster;
-        if ( _one_cluster_allocate( inode , &cluster ) )
+        if ( _one_cluster_allocate( child , &cluster ) )
         {
             _spin_lock_release( &_fat.fat_lock );
@@ -3821,15 +3812,8 @@
         child->cluster = cluster;
 
-        // allocate and initialise one 4 Kbytes buffer and associated descriptor
-        _allocate_one_buffer( child,
-                              0,            // cluster_id,
-                              cluster );
-
-        _add_special_directories( child, 
-                                  parent );
-
-        // add an entry in the parent directory Cache_file
-        if ( _add_dir_entry( child , parent ) )
-        { 
+        // add new entry in parent directory File-Cache
+        // and update dentry field in child inode
+        if ( _add_dir_entry( child ) )
+        {
             _spin_lock_release( &_fat.fat_lock );
             _atomic_and( &psched->context[ltid].slot[CTX_LOCKS_ID] , ~LOCKS_MASK_FAT ); 
@@ -3839,4 +3823,7 @@
             return GIET_FAT32_IO_ERROR;
         } 
+
+        // add "." and ".." directories in child directory
+        _add_special_directories( child );
 
         // update DATA region on block device for parent directory
