Index: trunk/kernel/libk/user_dir.c
===================================================================
--- trunk/kernel/libk/user_dir.c	(revision 613)
+++ trunk/kernel/libk/user_dir.c	(revision 614)
@@ -80,14 +80,14 @@
 }  // end user_dir_from_ident()
 
-///////////////////////////////////////////////////
-user_dir_t * user_dir_create( vfs_inode_t * inode )
+//////////////////////////////////////////////////
+user_dir_t * user_dir_create( vfs_inode_t * inode,
+                              xptr_t        ref_xp )
 { 
     user_dir_t    * dir;               // local pointer on created user_dir_t 
     vseg_t        * vseg;              // local pointer on dirent array vseg
     uint32_t        vseg_size;         // size of vseg in bytes
-    process_t     * process;           // local pointer on calling process
-    xptr_t          ref_xp;            // extended pointer on reference process
     process_t     * ref_ptr;           // local pointer on reference process
     cxy_t           ref_cxy;           // reference process cluster identifier
+    pid_t           ref_pid;           // reference process PID
     xptr_t          gpt_xp;            // extended pointer on reference process GPT
     uint32_t        gpt_attributes;    // attributes for all mapped gpt entries
@@ -109,6 +109,8 @@
     error_t         error;
 
-    // get pointer on local process descriptor
-    process = CURRENT_THREAD->process;
+    // get cluster, local pointer, and pid of reference user process
+    ref_cxy = GET_CXY( ref_xp );
+    ref_ptr = GET_PTR( ref_xp );
+    ref_pid = hal_remote_l32( XPTR( ref_cxy , &ref_ptr->pid ) );
 
 #if DEBUG_USER_DIR
@@ -116,6 +118,6 @@
 thread_t * this = CURRENT_THREAD;
 if( cycle > DEBUG_USER_DIR )
-printk("\n[%s] thread[%x,%x] enter for inode (%x,%x) / cycle %d\n",
-__FUNCTION__, process->pid, this->trdid, local_cxy, inode, cycle );
+printk("\n[%s] thread[%x,%x] enter for inode (%x,%x) and process %x / cycle %d\n",
+__FUNCTION__, this->process->pid, this->trdid, local_cxy, inode, ref_pid, cycle );
 #endif
 
@@ -128,9 +130,4 @@
     // initialise temporary list of pages
     list_root_init( &root );
-
-    // get pointers on reference process
-    ref_xp  = process->ref_xp;
-    ref_cxy = GET_CXY( ref_xp );
-    ref_ptr = GET_PTR( ref_xp );
 
     // allocate memory for a local user_dir descriptor
@@ -207,4 +204,10 @@
     } // end while
         
+#if DEBUG_USER_DIR
+if( cycle > DEBUG_USER_DIR )
+printk("\n[%s] thread[%x,%x] initialised dirent array / %d entries\n",
+__FUNCTION__, this->process->pid, this->trdid, total_dirents, cycle );
+#endif
+
     // compute required vseg size for a 64 bytes dirent
     vseg_size = total_dirents << 6;
@@ -213,5 +216,5 @@
     if( local_cxy == ref_cxy )
     {
-        vseg = vmm_create_vseg( process,
+        vseg = vmm_create_vseg( ref_ptr,
                                 VSEG_TYPE_ANON,
                                 0,                      // vseg base (unused)
@@ -220,5 +223,5 @@
                                 0,                      // file_size (unused)
                                 XPTR_NULL,              // mapper (unused)
-                                ref_cxy );
+                                local_cxy );
     }
     else
@@ -232,18 +235,19 @@
                                     0,                     // file size (unused)
                                     XPTR_NULL,             // mapper (unused)
-                                    ref_cxy,
+                                    local_cxy,
                                     &vseg ); 
     }
+
     if( vseg == NULL )
     {
-        printk("\n[ERROR] in %s : cannot create vseg for DIR in cluster %x\n",
+        printk("\n[ERROR] in %s : cannot create vseg for user_dir in cluster %x\n",
         __FUNCTION__, ref_cxy);
         goto user_dir_create_failure;
     }
 
-#if (DEBUG_USER_DIR & 1)
+#if DEBUG_USER_DIR
 if( cycle > DEBUG_USER_DIR )
 printk("\n[%s] thread[%x,%x] allocated vseg ANON / base %x / size %x\n",
-__FUNCTION__, process->pid, this->trdid, vseg->min, vseg->max - vseg->min );
+__FUNCTION__, this->process->pid, this->trdid, vseg->min, vseg->max - vseg->min );
 #endif
 
@@ -289,5 +293,5 @@
             desc.lid       = CURRENT_THREAD->core->lid;
             desc.blocking  = true;
-            desc.args[0]   = process->pid;
+            desc.args[0]   = ref_pid;
             desc.args[1]   = vpn << CONFIG_PPM_PAGE_SHIFT;
             rpc_vmm_delete_vseg_client( ref_cxy , &desc );
@@ -299,8 +303,8 @@
         }
 
-#if (DEBUG_USER_DIR & 1)
+#if DEBUG_USER_DIR 
 if( cycle > DEBUG_USER_DIR )
 printk("\n[%s] thread[%x,%x] mapped vpn %x to ppn %x\n",
-__FUNCTION__, process->pid, this->trdid, vpn + page_id, ppn );
+__FUNCTION__, this->process->pid, this->trdid, vpn + page_id, ppn );
 #endif
 
@@ -340,5 +344,5 @@
 if( cycle > DEBUG_USER_DIR )
 printk("\n[%s] thread[%x,%x] created user_dir (%x,%x) / %d entries / cycle %d\n",
-__FUNCTION__, process->pid, this->trdid, local_cxy, dir, total_dirents, cycle );
+__FUNCTION__, this->process->pid, this->trdid, local_cxy, dir, total_dirents, cycle );
 #endif
 
@@ -365,12 +369,13 @@
 }  // end user_dir_create()
 
-/////////////////////////////////////////
-void user_dir_destroy( user_dir_t * dir )
+////////////////////////////////////////
+void user_dir_destroy( user_dir_t * dir,
+                       xptr_t       ref_xp )
 {
-    process_t    * process;    // local pointer on client process
-    thread_t     * this;       // local pointer on client thread
+    thread_t     * this;       // local pointer on calling thread
+    process_t    * process;    // local pointer on calling process
     cluster_t    * cluster;    // local pointer on local cluster
     intptr_t       ident;      // user pointer on dirent array
-    xptr_t         ref_xp;     // extended pointer on reference process
+    xptr_t         ref_pid;    // reference process PID
     cxy_t          ref_cxy;    // reference process cluster identifier
     process_t    * ref_ptr;    // local pointer on reference process
@@ -379,28 +384,27 @@
     xptr_t         iter_xp;    // iteratot in xlist 
     reg_t          save_sr;    // for critical section
-    pid_t          pid;        // process descriptor
     cxy_t          owner_cxy;  // owner process cluster
     lpid_t         lpid;       // process local index
     rpc_desc_t     rpc;        // rpc descriptor
      
-    // get pointers on client process & thread
+    // get pointers on calling process & thread
     this    = CURRENT_THREAD;
     process = this->process;
     cluster = LOCAL_CLUSTER;
 
+    // get cluster, local pointer, and PID of reference user process
+    ref_cxy = GET_CXY( ref_xp );
+    ref_ptr = GET_PTR( ref_xp );
+    ref_pid = hal_remote_l32( XPTR( ref_cxy , &ref_ptr->pid ) );
+
 #if DEBUG_USER_DIR
 uint32_t cycle = (uint32_t)hal_get_cycles();
 if( cycle > DEBUG_USER_DIR )
-printk("\n[%s] thread[%x,%x] enter for user_dir (%x,%x) / cycle %d\n",
-__FUNCTION__, process->pid, this->trdid, local_cxy, dir, cycle );
+printk("\n[%s] thread[%x,%x] enter for user_dir (%x,%x) and process %x / cycle %d\n",
+__FUNCTION__, process->pid, this->trdid, local_cxy, dir, ref_pid, cycle );
 #endif
 
     // get user pointer on dirent array
     ident = dir->ident;
-
-    // get pointers on reference process
-    ref_xp  = process->ref_xp;
-    ref_cxy = GET_CXY( ref_xp );
-    ref_ptr = GET_PTR( ref_xp );
 
     // build extended pointer on lock protecting open directories list
@@ -424,7 +428,6 @@
 
     // get owner cluster identifier and process lpid
-    pid       = process->pid;
-    owner_cxy = CXY_FROM_PID( pid );
-    lpid      = LPID_FROM_PID( pid );
+    owner_cxy = CXY_FROM_PID( ref_pid );
+    lpid      = LPID_FROM_PID( ref_pid );
 
     // get root of list of copies and lock from owner cluster
@@ -444,5 +447,5 @@
     rpc.thread    = this;
     rpc.lid       = this->core->lid;
-    rpc.args[0]   = process->pid;
+    rpc.args[0]   = ref_pid;
     rpc.args[1]   = ident;
 
