Index: trunk/kernel/vfs/vfs.c
===================================================================
--- trunk/kernel/vfs/vfs.c	(revision 124)
+++ trunk/kernel/vfs/vfs.c	(revision 188)
@@ -52,9 +52,32 @@
 //////////////////////////////////////////////////////////////////////////////////////////
 
-extern vfs_ctx_t   fs_context[FS_TYPES_NR];    // allocate in kernel_init.c
+extern vfs_ctx_t   fs_context[FS_TYPES_NR];    // allocated in kernel_init.c
+
   
 //////////////////////////////////////////////////////////////////////////////////////////
 //           Context related functions
 //////////////////////////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////
+void vfs_ctx_init( vfs_fs_type_t   type,
+                   uint32_t        attr,
+	               uint32_t        total_clusters,
+	               uint32_t        cluster_size,
+	               xptr_t          vfs_root_xp,
+                   void          * extend )
+{
+    vfs_ctx_t * vfs_ctx = &fs_context[type];
+
+    vfs_ctx->type           = type;
+    vfs_ctx->attr           = attr;
+    vfs_ctx->total_clusters = total_clusters;
+    vfs_ctx->cluster_size   = cluster_size;
+    vfs_ctx->vfs_root_xp    = vfs_root_xp;
+    vfs_ctx->extend         = extend;
+
+    spinlock_init( &vfs_ctx->lock );
+
+    bitmap_init( vfs_ctx->bitmap , BITMAP_SIZE(CONFIG_VFS_MAX_INODES) ); 
+}
 
 ////////////////////////////////////////////
@@ -101,9 +124,21 @@
 //////////////////////////////////////////////////////////////////////////////////////////
 
+char * vfs_inode_type_str( uint32_t type )
+{
+    if     ( type == INODE_TYPE_FILE ) return "FILE";
+    else if( type == INODE_TYPE_DIR  ) return "DIR ";
+    else if( type == INODE_TYPE_FIFO ) return "FIFO";
+    else if( type == INODE_TYPE_PIPE ) return "PIPE";
+    else if( type == INODE_TYPE_SOCK ) return "SOCK";
+    else if( type == INODE_TYPE_DEV  ) return "DEV ";
+    else if( type == INODE_TYPE_SYML ) return "SYML";
+    else                               return "undefined";
+}
+
 //////////////////////////////////////////////////////
-
 error_t vfs_inode_create( xptr_t            dentry_xp,
                           vfs_fs_type_t     fs_type,
                           vfs_inode_type_t  inode_type,
+                          void            * extend,
                           uint32_t          attr,
                           uint32_t          rights,
@@ -175,4 +210,5 @@
     inode->ctx        = ctx;
     inode->mapper     = NULL;  
+    inode->extend     = extend;
 
     // initialise threads waiting queue
@@ -307,5 +343,5 @@
 	kmem_req_t       req;        // request to kernel memory allocator
 
-    // check type and get pointer on context
+    // get pointer on context
     if     ( fs_type == FS_TYPE_FATFS ) ctx = &fs_context[FS_TYPE_FATFS];
     else if( fs_type == FS_TYPE_RAMFS ) ctx = &fs_context[FS_TYPE_RAMFS];
@@ -349,5 +385,5 @@
     xhtab_insert( XPTR( local_cxy , &parent->children ),
                   name, 
-                  XPTR( local_cxy , &dentry->xlist ) );
+                  XPTR( local_cxy , &dentry->list ) );
 
     // return extended pointer on dentry 
@@ -372,4 +408,5 @@
 	kmem_free( &req );
 }
+
 
 
@@ -797,7 +834,153 @@
 
 
-/////////////////////////////////////////////////////////////////////////////////////////r
+//////////////////////////////////////////////////////////////////////////////////////////
 //            Inode Tree functions
 //////////////////////////////////////////////////////////////////////////////////////////
+
+/////////////////////////////////
+cxy_t vfs_cluster_random_select()
+{
+    uint32_t  x_size    = LOCAL_CLUSTER->x_size;
+    uint32_t  y_size    = LOCAL_CLUSTER->y_size;
+    uint32_t  y_width   = LOCAL_CLUSTER->y_width;
+    uint32_t  index     = ( hal_get_cycles() + hal_get_gid() ) % (x_size * y_size);
+    uint32_t  x         = index / y_size;    
+    uint32_t  y         = index % y_size;
+
+    return (x<<y_width) + y;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+// This static function is called by the vfs_display() function.
+//////////////////////////////////////////////////////////////////////////
+static void vfs_recursive_display( xptr_t   inode_xp,
+                                   xptr_t   name_xp,
+                                   uint32_t indent )
+{
+    cxy_t              inode_cxy;
+    vfs_inode_t      * inode_ptr;
+    vfs_inode_type_t   inode_type;
+    xptr_t             inode_children_xp;    // extended pointer on children xhtab
+
+    xptr_t             dentry_xp;
+    cxy_t              dentry_cxy;
+    vfs_dentry_t     * dentry_ptr;
+
+    char               name[CONFIG_VFS_MAX_NAME_LENGTH];
+
+    xptr_t             child_inode_xp;
+    xptr_t             dentry_name_xp;
+
+    char *             indent_str[] = { "",                                  // level 0
+                                        "  ",                                // level 1
+                                        "    ",                              // level 2
+                                        "      ",                            // level 3
+                                        "        ",                          // level 4
+                                        "          ",                        // level 5
+                                        "            ",                      // level 6
+                                        "              ",                    // level 7
+                                        "                ",                  // level 8
+                                        "                  ",                // level 9
+                                        "                    ",              // level 10
+                                        "                      ",            // level 11
+                                        "                        ",          // level 12
+                                        "                          ",        // level 13
+                                        "                            ",      // level 14
+                                        "                              " };  // level 15
+
+    assert( (inode_xp != XPTR_NULL) , __FUNCTION__ , "inode_xp cannot be NULL\n" );
+    assert( (name_xp  != XPTR_NULL) , __FUNCTION__ , "name_xp cannot be NULL\n" );
+    assert( (indent < 16)           , __FUNCTION__ , "depth cannot be larger than 15\n" );
+    
+    // get inode cluster and local pointer
+    inode_cxy = GET_CXY( inode_xp );
+    inode_ptr = (vfs_inode_t *)GET_PTR( inode_xp );
+
+    // get inode type
+    inode_type = hal_remote_lw( XPTR( inode_cxy , &inode_ptr->type ) );
+
+    // make a local copy of node name
+    hal_remote_strcpy( XPTR( local_cxy , name ) , name_xp );
+
+    // display inode
+    printk(" %s %s : %s\n", indent_str[indent], vfs_inode_type_str( inode_type ), name );
+
+    // scan directory entries  
+    if( inode_type == INODE_TYPE_DIR )
+    {
+        // get extended pointer on directory entries xhtab
+        inode_children_xp = hal_remote_lwd( XPTR( inode_cxy , &inode_ptr->children ) );
+
+        // get xhtab lock
+        xhtab_read_lock( inode_children_xp );
+
+        // get first dentry from xhtab
+        dentry_xp = xhtab_get_first( inode_children_xp );
+
+        while( dentry_xp != XPTR_NULL )
+        {
+            // get dentry cluster and local pointer
+            dentry_cxy = GET_CXY( dentry_xp );
+            dentry_ptr = (vfs_dentry_t *)GET_PTR( dentry_xp );
+
+            // get extended pointer on child inode
+            child_inode_xp = hal_remote_lwd( XPTR( dentry_cxy , &dentry_ptr->child_xp ) );
+
+            // get extended pointer on dentry name
+            dentry_name_xp = XPTR( dentry_cxy , &dentry_ptr->name );
+
+            // recursive call on child inode
+            vfs_recursive_display( child_inode_xp , dentry_name_xp , indent+1 );
+
+            // get next dentry
+            dentry_xp = xhtab_get_next( inode_children_xp );
+        }
+
+        // release xhtab lock
+        xhtab_read_unlock( inode_children_xp );
+    }
+}  // end vfs_recursive_display()
+
+///////////////////////////////////
+void vfs_display( xptr_t inode_xp )
+{
+    xptr_t         name_xp;      // extended pointer on string containing the inode name
+    xptr_t         dentry_xp; 
+    cxy_t          dentry_cxy;
+    vfs_dentry_t * dentry_ptr;
+
+printk("\n@@@ %s enters\n", __FUNCTION__ );
+
+    // get target inode cluster and local pointer 
+    cxy_t         inode_cxy = GET_CXY( inode_xp );
+    vfs_inode_t * inode_ptr = (vfs_inode_t *)GET_PTR( inode_xp );
+
+    // get extended pointer on associated dentry
+    dentry_xp = hal_remote_lwd( XPTR( inode_cxy , &inode_ptr->parent_xp ) );
+
+    // check if target inode is the File System root
+    if( dentry_xp == XPTR_NULL )
+    {
+        // build extended pointer on root name
+        name_xp = XPTR( local_cxy , "/" );
+    }
+    else
+    {
+        // get dentry cluster and local pointer
+        dentry_cxy = GET_CXY( dentry_xp );
+        dentry_ptr = (vfs_dentry_t *)GET_PTR( dentry_xp );
+
+        // get extended pointer on dentry name
+        name_xp = XPTR( dentry_cxy , &dentry_ptr->name );
+    }
+
+    // print header
+    printk("\n*** Current VFS content ***\n");
+
+    // call recursive function
+    vfs_recursive_display( inode_xp , name_xp , 0 );
+
+}  // end vfs_diplay()
 
 //////////////////////////////////////////////////////////////////////////////////////////
@@ -913,5 +1096,5 @@
     return 0;
 }
-
+   
 //////////////////////////////////////////////
 error_t vfs_lookup( xptr_t             cwd_xp,
@@ -993,8 +1176,13 @@
             else                                             inode_type = INODE_TYPE_FILE;
 
-            // insert a child dentry/inode in parent inode
-            error = vfs_add_child_in_parent( inode_type,
+            // select a cluster for child inode
+            cxy_t child_cxy = vfs_cluster_random_select();
+                     
+            // insert a new child dentry/inode in parent inode
+            error = vfs_add_child_in_parent( child_cxy,
+                                             inode_type,
                                              fs_type, 
                                              parent_xp, 
+                                             NULL,           // fs_type_specific inode extend
                                              name, 
                                              &child_xp );
@@ -1002,5 +1190,5 @@
             if( error )
             {
-                printk("\n[ERROR] in %s : inode %s not found in path %s\n",
+                printk("\n[ERROR] in %s : node %s not found in path %s\n",
                        __FUNCTION__ , name , pathname );
                 return ENOENT;
@@ -1024,16 +1212,11 @@
         // }
 
-printk("\n@@@ bloup 0 : parent lock owner = %l / child lock owner = %l\n",
-       vfs_inode_owner( parent_xp ) , vfs_inode_owner( child_xp ) );
+        // TODO TODO TODO access device and load inode mapper if required...
 
         // take lock on child inode if not last
         if( last == false ) vfs_inode_lock( child_xp );
 
-printk("\n@@@ bloup 1\n");
-
         // release lock on parent inode
         vfs_inode_unlock( parent_xp );
-
-printk("\n@@@ bloup 2\n");
 
         // update loop variables
@@ -1060,5 +1243,4 @@
 
 }  // end vfs_lookup()
-
 
 ////////////////////////////////////////////
@@ -1131,9 +1313,12 @@
 }  // end vfs_get_path()
 
-///////////////////////////////////////////////////////////////
-error_t vfs_add_child_in_parent( vfs_inode_type_t   inode_type,
+      
+//////////////////////////////////////////////////////////////
+error_t vfs_add_child_in_parent( cxy_t              child_cxy,
+                                 vfs_inode_type_t   inode_type,
                                  vfs_fs_type_t      fs_type,
                                  xptr_t             parent_xp,
                                  char             * name,
+                                 void             * extend,
                                  xptr_t           * child_xp )
 {
@@ -1174,17 +1359,7 @@
         printk("\n[ERROR] in %s : cannot create dentry in cluster %x\n",
                __FUNCTION__ , parent_cxy );
-
         return error;
     }
 
-    // select a target cluster for child inode
-    uint32_t  x_size    = LOCAL_CLUSTER->x_size;
-    uint32_t  y_size    = LOCAL_CLUSTER->y_size;
-    uint32_t  y_width   = LOCAL_CLUSTER->y_width;
-    uint32_t  index     = ( hal_get_cycles() + hal_get_gid() ) % (x_size * y_size);
-    uint32_t  x         = index / y_size;    
-    uint32_t  y         = index % y_size;
-    cxy_t     child_cxy = (x<<y_width) + y;
-                                      
     // create child inode TODO : define attr / mode / uid / gid
     uint32_t attr = 0;
@@ -1198,4 +1373,5 @@
                                   fs_type,
                                   inode_type,
+                                  extend,
                                   attr,
                                   mode,
@@ -1210,4 +1386,5 @@
                                      fs_type,
                                      inode_type,
+                                     extend,
                                      attr,
                                      mode,
