Changeset 610


Ignore:
Timestamp:
Dec 27, 2018, 7:38:58 PM (5 years ago)
Author:
alain
Message:

Fix several bugs in VFS to support the following
ksh commandis : cp, mv, rm, mkdir, cd, pwd

Location:
trunk
Files:
58 edited

Legend:

Unmodified
Added
Removed
  • trunk/Makefile

    r590 r610  
    119119        mmd                     -o -i $(DISK_IMAGE) ::/bin/user    || true
    120120        mmd                     -o -i $(DISK_IMAGE) ::/home        || true
     121        mcopy           -o -i $(DISK_IMAGE) Makefile ::/home
    121122        mdir             -/ -b -i $(DISK_IMAGE) ::/
    122        
     123
    123124##############################################################
    124125# Rules to generate hardware description files (hard_config.h,
  • trunk/boot/tsar_mips32/boot.ld

    r572 r610  
    1 /**********************************************************************************************
    2  * This is the linker script for the ALMOS-MK boot-loader used for the TSAR architecture.
    3  * It describes the memory layout for the 'boot.elf' binary file.
    4  *********************************************************************************************/
     1/*******************************************************************
     2 * This is the linker script for the ALMOS-MKH boot-loader,
     3 * to generate the 'boot.elf' file used for the TSAR architecture.
     4 *******************************************************************/
    55
    66/* define the boot code base address */
     
    88boot_code_base = 0x100000;
    99
    10 /* Set the entry point of the boot-loader (e_entry field in the "boot.elf" file header) */
     10/* Set the entry point of the boot-loader */
     11/* (e_entry field in the "boot.elf" file header) */
    1112
    1213ENTRY(boot_entry)
  • trunk/hal/tsar_mips32/core/hal_exception.c

    r587 r610  
    158158// This function is called when an MMU exception has been detected (IBE / DBE).
    159159// It get the relevant exception arguments from the MMU.
    160 // It signal a fatal error in case of illegal access. In case of page unmapped
    161 // it checks that the faulty address belongs to a registered vseg. It update the local
     160// It signal a fatal error in case of illegal access. In case of page unmapped,
     161// it get the client process to access the relevant VMM: for a RPC thread, the client
     162// process is NOT the calling thread process.
     163// Then, it checks that the faulty address belongs to a registered vseg, update the local
    162164// vseg list from the reference cluster if required, and signal a fatal user error
    163165// in case of illegal virtual address. Finally, it updates the local page table from the
     
    183185    uint32_t         bad_vaddr;
    184186    uint32_t         excp_code;
    185        
     187
     188    // check thread type
     189    if( CURRENT_THREAD->type != THREAD_USER )
     190    {
     191        printk("\n[KERNEL PANIC] in %s : illegal thread type %s\n",
     192        __FUNCTION__, thread_type_str(CURRENT_THREAD->type) );
     193
     194        return EXCP_KERNEL_PANIC;
     195    }
     196
     197    // get faulty thread process 
    186198    process = this->process;
    187199
     
    207219uint32_t cycle = (uint32_t)hal_get_cycles();
    208220if( DEBUG_HAL_EXCEPTIONS < cycle )
    209 printk("\n[DBG] %s : thread[%x,%x] enter / is_ins %d / %s / vaddr %x / cycle %d\n",
    210 __FUNCTION__, process->pid, this->trdid,
     221printk("\n[%s] thread[%x,%x] on core [%x,%x] enter / is_ins %d / %s / vaddr %x / cycle %d\n",
     222__FUNCTION__, process->pid, this->trdid, local_cxy, this->core->lid,
    211223is_ins, hal_mmu_exception_str(excp_code), bad_vaddr, cycle);
    212224#endif
     
    215227    switch( excp_code )
    216228    {
    217         case MMU_WRITE_PT1_UNMAPPED:      // non fatal
    218         case MMU_WRITE_PT2_UNMAPPED:
    219         case MMU_READ_PT1_UNMAPPED:
    220         case MMU_READ_PT2_UNMAPPED:
     229        case MMU_WRITE_PT1_UNMAPPED:      // can be non fatal
     230        case MMU_WRITE_PT2_UNMAPPED:      // can be non fatal
     231        case MMU_READ_PT1_UNMAPPED:       // can be non fatal
     232        case MMU_READ_PT2_UNMAPPED:       // can be non fatal
    221233        {
    222234            // try to map the unmapped PTE
     
    230242cycle = (uint32_t)hal_get_cycles();
    231243if( DEBUG_HAL_EXCEPTIONS < cycle )
    232 printk("\n[DBG] %s : thread[%x,%x] exit / page-fault handled for vaddr = %x\n",
    233 __FUNCTION__, process->pid, this->trdid, bad_vaddr );
     244printk("\n[%s] thread[%x,%x] on core [%x,%x] exit / page-fault handled for vaddr = %x\n",
     245__FUNCTION__, process->pid, this->trdid, local_cxy, this->core->lid, bad_vaddr );
    234246#endif
    235247 
     
    238250            else if( error == EXCP_USER_ERROR )      // illegal vaddr
    239251            {
    240                 printk("\n[USER ERROR] in %s for thread %x in process %x\n"
    241                 "   illegal vaddr = %x / is_ins %d / epc %x\n",
    242                 __FUNCTION__, this->trdid, this->process->pid, bad_vaddr, is_ins, excPC );
     252                printk("\n[USER ERROR] in %s : thread[%x,%x] on core[%x,%x] / cycle %d\n"
     253                "  %s : epc %x / badvaddr %x / is_ins %d\n",
     254                __FUNCTION__, this->process->pid, this->trdid, local_cxy,
     255                this->core->lid, (uint32_t)hal_get_cycles(),
     256                hal_mmu_exception_str(excp_code), excPC, bad_vaddr, is_ins );
    243257
    244258                        return EXCP_USER_ERROR;
     
    246260            else  // error == EXCP_KERNEL_PANIC 
    247261            {
    248                 printk("\n[KERNEL ERROR] in %s for thread %x in process %x\n"
    249                 "   no memory to map vaddr = %x / is_ins %d / epc %x\n",
    250                 __FUNCTION__, this->trdid, this->process->pid, bad_vaddr, is_ins, excPC );
     262                printk("\n[KERNEL PANIC] in %s : thread[%x,%x] on core[%x,%x] / cycle %d\n"
     263                "  %s : epc %x / badvaddr %x / is_ins %d\n",
     264                __FUNCTION__, this->process->pid, this->trdid, local_cxy,
     265                this->core->lid, (uint32_t)hal_get_cycles(),
     266                hal_mmu_exception_str(excp_code), excPC, bad_vaddr, is_ins );
    251267
    252268                        return EXCP_KERNEL_PANIC;
    253269            }
    254270        }
    255         case MMU_WRITE_PRIVILEGE_VIOLATION:  // illegal access user error
    256         case MMU_READ_PRIVILEGE_VIOLATION:
    257         {
    258             printk("\n[USER ERROR] in %s : thread %x in process %x\n"
    259             "   illegal user access to vaddr = %x / is_ins %d / epc %x\n",
    260             __FUNCTION__, this->trdid, this->process->pid, bad_vaddr, is_ins, excPC );
     271        case MMU_WRITE_PRIVILEGE_VIOLATION:  // illegal user error
     272        case MMU_READ_PRIVILEGE_VIOLATION:   // illegal
     273        {
     274            printk("\n[USER ERROR] in %s : thread[%x,%x] on core[%x,%x] / cycle %d\n"
     275            "  %s : epc %x / badvaddr %x / is_ins %d\n",
     276            __FUNCTION__, this->process->pid, this->trdid, local_cxy,
     277            this->core->lid, (uint32_t)hal_get_cycles(),
     278            hal_mmu_exception_str(excp_code), excPC, bad_vaddr, is_ins );
    261279
    262280            return EXCP_USER_ERROR;
    263281        }
    264         case MMU_WRITE_ACCESS_VIOLATION:     // user error, or Copy-on-Write
    265         {
    266             // access page table to get GPT_COW flag
    267             bool_t cow = hal_gpt_pte_is_cow( &(process->vmm.gpt),
    268                                              bad_vaddr >> CONFIG_PPM_PAGE_SHIFT );
    269 
    270             if( cow )                        // Copy-on-Write
    271             {
    272                 // try to allocate and copy the page
    273                 error = vmm_handle_cow( process,
    274                                         bad_vaddr >> CONFIG_PPM_PAGE_SHIFT );
    275 
    276                 if( error == EXCP_NON_FATAL )        // Copy on write successfull
    277                 {
     282        case MMU_WRITE_ACCESS_VIOLATION:    // can be non fatal if COW
     283        {
     284            // try to handle a possible COW
     285            error = vmm_handle_cow( process,
     286                                    bad_vaddr >> CONFIG_PPM_PAGE_SHIFT );
     287
     288            if( error == EXCP_NON_FATAL )        // COW successfully handled
     289            {
    278290
    279291#if DEBUG_HAL_EXCEPTIONS
    280292cycle = (uint32_t)hal_get_cycles();
    281293if( DEBUG_HAL_EXCEPTIONS < cycle )
    282 printk("\n[DBG] %s : thread[%x,%x] exit / copy-on-write handled for vaddr = %x\n",
     294printk("\n[%s] thread[%x,%x] exit / copy-on-write handled for vaddr = %x\n",
    283295__FUNCTION__, process->pid, this->trdid, bad_vaddr );
    284296#endif
    285 
    286                     return EXCP_NON_FATAL;
    287                 }
    288                 else if( error == EXCP_USER_ERROR )  // illegal user access
    289                 {
    290                     printk("\n[USER ERROR] in %s : thread %x in process %x\n"
    291                     "   cannot cow vaddr = %x / is_ins %d / epc %x\n",
    292                     __FUNCTION__, this->trdid, this->process->pid, bad_vaddr, is_ins, excPC );
     297                return EXCP_NON_FATAL;
     298            }
     299            else if( error == EXCP_USER_ERROR )  // illegal write access
     300            {
     301                    printk("\n[USER ERROR] in %s : thread[%x,%x] on core[%x,%x] / cycle %d\n"
     302                    "  %s : epc %x / badvaddr %x / is_ins %d\n",
     303                    __FUNCTION__, this->process->pid, this->trdid, local_cxy,
     304                    this->core->lid, (uint32_t)hal_get_cycles(),
     305                    hal_mmu_exception_str(excp_code), excPC, bad_vaddr, is_ins );
    293306
    294307                            return EXCP_USER_ERROR;
    295                 }
    296                 else   // error == EXCP_KERNEL_PANIC
    297                 {
    298                     printk("\n[KERNEL ERROR] in %s : thread %x in process %x\n"
    299                     "   no memoty to cow vaddr = %x / is_ins %d / epc %x\n",
    300                     __FUNCTION__, this->trdid, this->process->pid, bad_vaddr, is_ins, excPC );
    301 
    302                             return EXCP_USER_ERROR;
    303                 }
    304308            }
    305             else                             // non writable user error
    306             {
    307                 printk("\n[USER ERROR] in %s : thread %x in process %x\n"
    308                 "   non-writable vaddr = %x / is_ins %d / epc %x\n",
    309                 __FUNCTION__, this->trdid, this->process->pid, bad_vaddr, is_ins, excPC );
    310 
    311                 return EXCP_USER_ERROR;
     309            else   // error == EXCP_KERNEL_PANIC
     310            {
     311                printk("\n[KERNEL PANIC] in %s : thread[%x,%x] on core[%x,%x] / cycle %d\n"
     312                "  %s : epc %x / badvaddr %x / is_ins %d\n",
     313                __FUNCTION__, this->process->pid, this->trdid, local_cxy,
     314                this->core->lid, (uint32_t)hal_get_cycles(),
     315                hal_mmu_exception_str(excp_code), excPC, bad_vaddr, is_ins );
     316
     317                        return EXCP_USER_ERROR;
    312318            }
    313319        }
    314320        case MMU_READ_EXEC_VIOLATION:        // user error
    315321        {
    316             printk("\n[USER_ERROR] in %s : thread %x in process %x\n"
    317             "   non-executable vaddr = %x / is_ins %d / epc %x\n",
    318             __FUNCTION__, this->trdid, this->process->pid, bad_vaddr, is_ins, excPC );
     322            printk("\n[USER ERROR] in %s : thread[%x,%x] on core[%x,%x] / cycle %d\n"
     323            "  %s : epc %x / badvaddr %x / is_ins %d\n",
     324            __FUNCTION__, this->process->pid, this->trdid, local_cxy,
     325            this->core->lid, (uint32_t)hal_get_cycles(),
     326            hal_mmu_exception_str(excp_code), excPC, bad_vaddr, is_ins );
    319327
    320328            return EXCP_USER_ERROR;
     
    322330        default:                             // this is a kernel error   
    323331        {
    324             printk("\n[KERNEL ERROR] in %s : thread %x in process %x\n"
    325             "  epc %x / badvaddr %x / is_ins %d\n",
    326             __FUNCTION__, this->trdid, this->process->pid, excPC, bad_vaddr, is_ins );
     332            printk("\n[KERNEL PANIC] in %s : thread[%x,%x] on core[%x,%x] / cycle %d\n"
     333            "  %s : epc %x / badvaddr %x / is_ins %d\n",
     334            __FUNCTION__, this->process->pid, this->trdid, local_cxy,
     335            this->core->lid, (uint32_t)hal_get_cycles(),
     336            hal_mmu_exception_str(excp_code), excPC, bad_vaddr, is_ins );
    327337
    328338            return EXCP_KERNEL_PANIC;
     
    359369    if( error == EXCP_USER_ERROR )
    360370    {
    361         nolock_printk("\n=== USER ERROR / trdid %x / pid %x / core[%x,%d] / cycle %d ===\n",
    362         this->trdid, process->pid, local_cxy, core->lid , (uint32_t)hal_get_cycles() );
     371        nolock_printk("\n=== USER ERROR / thread(%x,%x) / core[%d] / cycle %d ===\n",
     372        process->pid, this->trdid, core->lid, (uint32_t)hal_get_cycles() );
    363373    }
    364374    else
    365375    {
    366         nolock_printk("\n=== KERNEL ERROR / trdid %x / pid %x / core[%x,%d] / cycle %d ===\n",
    367         this->trdid, process->pid, local_cxy, core->lid , (uint32_t)hal_get_cycles() );
     376        nolock_printk("\n=== KERNEL PANIC / thread(%x,%x) / core[%d] / cycle %d ===\n",
     377        process->pid, this->trdid, core->lid, (uint32_t)hal_get_cycles() );
    368378    }
    369379
     
    400410}  // end hal_exception_dump()
    401411
    402 ///////////////////////
     412/////////////////////////////
    403413void hal_do_exception( void )
    404414{
     
    420430uint32_t cycle = (uint32_t)hal_get_cycles();
    421431if( DEBUG_HAL_EXCEPTIONS < cycle )
    422 printk("\n[DBG] %s : thread %x in process %x enter / core[%x,%d] / epc %x / xcode %x / cycle %d\n",
    423 __FUNCTION__, this->trdid, this->process->pid, local_cxy, this->core->lid, excPC, excCode, cycle );
     432printk("\n[%s] thread[%x,%x] enter / core[%x,%d] / epc %x / xcode %x / cycle %d\n",
     433__FUNCTION__, this->process->pid, this->trdid,
     434local_cxy, this->core->lid, excPC, excCode, cycle );
    424435#endif
    425436
     
    473484        {
    474485            printk("\n[USER_ERROR] in %s for thread %x in process %x\n"
    475             "   illegal data load address / epc %x\n",
    476             __FUNCTION__, this->trdid, this->process->pid, excPC );
     486            "   illegal data load address / epc %x / bad_address %x\n",
     487            __FUNCTION__, this->trdid, this->process->pid, excPC, hal_get_bad_vaddr() );
    477488
    478489                    error = EXCP_USER_ERROR;
     
    482493        {
    483494            printk("\n[USER_ERROR] in %s for thread %x in process %x\n"
    484             "   illegal data store address / epc %x\n",
    485             __FUNCTION__, this->trdid, this->process->pid, excPC );
     495            "   illegal data store address / epc %x / bad_address %x\n",
     496            __FUNCTION__, this->trdid, this->process->pid, excPC, hal_get_bad_vaddr() );
    486497
    487498                    error = EXCP_USER_ERROR;
     
    505516        hal_exception_dump( this , uzone , error );
    506517
    507         assert( false , "Exception raised kernel panic see information below.\n" );
     518        hal_core_sleep();
    508519    }
    509520
     
    511522cycle = (uint32_t)hal_get_cycles();
    512523if( DEBUG_HAL_EXCEPTIONS < cycle )
    513 printk("\n[DBG] %s : thread %x in process %x exit / core[%x,%d] / epc %x / xcode %x / cycle %d\n",
    514 __FUNCTION__, this->trdid, this->process->pid, local_cxy, this->core->lid, excPC, excCode, cycle );
     524printk("\n[%s] thread[%x,%x] exit / core[%x,%d] / epc %x / xcode %x / cycle %d\n",
     525__FUNCTION__, this->process->pid, this->trdid,
     526local_cxy, this->core->lid, excPC, excCode, cycle );
    515527#endif
    516528
  • trunk/hal/tsar_mips32/core/hal_ppm.c

    r570 r610  
    22 * hal_ppm.c - Generic Physical Page Manager API implementation for TSAR
    33 *
    4  * Authors  Alain Greiner (2016,2017)
     4 * Authors  Alain Greiner (2016,2017,2018)
    55 *
    66 * Copyright (c) UPMC Sorbonne Universites
     
    6363
    6464        // initialize lock protecting the dirty_pages list
    65         queuelock_init( &ppm->dirty_lock , LOCK_PPM_DIRTY );
     65        remote_queuelock_init( XPTR( local_cxy , &ppm->dirty_lock ) , LOCK_PPM_DIRTY );
    6666
    6767        // initialize all free_pages[] lists as empty
  • trunk/hal/tsar_mips32/core/hal_remote.c

    r570 r610  
    381381    uint32_t scxy = (uint32_t)GET_CXY( src );
    382382
     383/*
     384if( local_cxy == 1 )
     385printk("\n@@@ %s : scxy %x / sptr %x / dcxy %x / dptr %x\n",
     386__FUNCTION__, scxy, sptr, dcxy, dptr );
     387*/
    383388    hal_disable_irq( &save_sr );
    384389
  • trunk/hal/tsar_mips32/core/hal_uspace.c

    r457 r610  
    4343    uint32_t dst = (uint32_t)k_dst;
    4444
     45#if DEBUG_HAL_USPACE
     46thread_t * this = CURRENT_THREAD;
     47printk("\n[%s] thread[%x,%x] enter in cluster %x / u_src %x / k_dst %x / size %d\n",
     48__FUNCTION__, this->process->pid, this->trdid, local_cxy, u_src, k_dst, size );
     49#endif
     50
    4551        if( (dst & 0x3) || (src & 0x3) ) wsize = 0;          // do it all in bytes
    4652    else                             wsize = size >> 2;
     
    8086
    8187    hal_restore_irq( save_sr );
     88
     89#if DEBUG_HAL_USPACE
     90printk("\n[%s] thread[%x,%x] exit\n",
     91__FUNCTION__, this->process->pid, this->trdid );
     92#endif
    8293
    8394}  // end hal_copy_from_uspace()
     
    94105    uint32_t dst = (uint32_t)u_dst;
    95106
     107#if DEBUG_HAL_USPACE
     108thread_t * this = CURRENT_THREAD;
     109printk("\n[%s] thread[%x,%x] enter in cluster %x / k_src %x / u_dst %x / size %d\n",
     110__FUNCTION__, this->process->pid, this->trdid, local_cxy, k_src, u_dst, size );
     111#endif
     112
    96113        if( (dst & 0x3) || (src & 0x3) ) wsize = 0;          // not aligned
    97114    else                             wsize = size >> 2;
     
    118135        asm volatile(
    119136        "mfc2   $15,   $1           \n"   /* save   MMU_MODE                */
    120         "lw         $13,   0(%0)        \n"   /* read data from kernel space    */
     137        "lb         $13,   0(%0)        \n"   /* read data from kernel space    */
    121138        "ori    $14,   $0,  0x7     \n" 
    122139        "mtc2   $14,   $1                       \n"   /* MMU_MODE <= DTLB ON            */
     
    130147
    131148    hal_restore_irq( save_sr );
     149
     150#if DEBUG_HAL_USPACE
     151printk("\n[%s] thread[%x,%x] exit\n",
     152__FUNCTION__, this->process->pid, this->trdid );
     153#endif
    132154
    133155}  // end hal_copy_to_uspace()
  • trunk/hal/tsar_mips32/drivers/soclib_bdv.c

    r570 r610  
    3232void soclib_bdv_init( chdev_t * chdev )
    3333{
    34     // get extended pointer on SOCLIB_BDV peripheral base address
     34    // get extended pointer on SOCLIB_BDV peripheral base
    3535        xptr_t  bdv_xp = chdev->base;
    3636
     
    6262    xptr_t     buf_xp;
    6363    xptr_t     ioc_xp;
     64    uint32_t   status;      // I/0 operation status (from BDV)
     65    reg_t      save_sr;     // for critical section
     66    uint32_t   op;          // BDV_OP_READ / BDV_OP_WRITE
    6467
    6568    // get client thread cluster and local pointer
     
    6770    thread_t * th_ptr = GET_PTR( th_xp );
    6871
     72#if (DEBUG_HAL_IOC_RX || DEBUG_HAL_IOC_TX)
     73uint32_t    cycle        = (uint32_t)hal_get_cycles();
     74thread_t  * this         = CURRENT_THREAD;
     75process_t * process      = hal_remote_lpt( XPTR( th_cxy , &th_ptr->process ) );
     76pid_t       client_pid   = hal_remote_l32( XPTR( th_cxy , &process->pid ) );
     77trdid_t     client_trdid = hal_remote_l32( XPTR( th_cxy , &th_ptr->trdid ) );
     78#endif
     79
    6980    // get command arguments and extended pointer on IOC device
    70     cmd_type =         hal_remote_l32 ( XPTR( th_cxy , &th_ptr->ioc_cmd.type   ) );
    71     lba      =         hal_remote_l32 ( XPTR( th_cxy , &th_ptr->ioc_cmd.lba    ) );
    72     count    =         hal_remote_l32 ( XPTR( th_cxy , &th_ptr->ioc_cmd.count  ) );
     81    cmd_type =         hal_remote_l32( XPTR( th_cxy , &th_ptr->ioc_cmd.type   ) );
     82    lba      =         hal_remote_l32( XPTR( th_cxy , &th_ptr->ioc_cmd.lba    ) );
     83    count    =         hal_remote_l32( XPTR( th_cxy , &th_ptr->ioc_cmd.count  ) );
    7384    buf_xp   = (xptr_t)hal_remote_l64( XPTR( th_cxy , &th_ptr->ioc_cmd.buf_xp ) );
    7485    ioc_xp   = (xptr_t)hal_remote_l64( XPTR( th_cxy , &th_ptr->ioc_cmd.dev_xp ) );
    7586
    7687#if DEBUG_HAL_IOC_RX
    77 uint32_t cycle = (uint32_t)hal_get_cycles();
    7888if( (DEBUG_HAL_IOC_RX < cycle) && (cmd_type != IOC_WRITE ) )
    79 printk("\n[DBG] %s : thread %x enter for RX / cycle %d\n",
    80 __FUNCTION__ , CURRENT_THREAD , cycle );
    81 #endif
    82 
    83 #if DEBUG_HAL_IOC_TX
    84 uint32_t cycle = (uint32_t)hal_get_cycles();
     89printk("\n[%s] thread[%x,%x] enters for client thread[%x,%x] / RX / cycle %d\n",
     90__FUNCTION__ , this->process->pid, this->trdid, client_pid, client_trdid, cycle );
     91#endif
     92
     93#if DEBUG_HAL_IOC_TX
    8594if( (DEBUG_HAL_IOC_TX < cycle) && (cmd_type == IOC_WRITE) )
    86 printk("\n[DBG] %s : thread %x enter for TX / cycle %d\n",
    87 __FUNCTION__ , CURRENT_THREAD , cycle );
     95printk("\n[%s] thread[%x,%x] enters for client thread[%x,%x] / TX / cycle %d\n",
     96__FUNCTION__ , this->process->pid, this->trdid, client_pid, client_trdid, cycle );
    8897#endif
    8998
     
    101110    uint32_t   buf_msb = (uint32_t)(buf_xp>>32);
    102111
    103     // set operation
    104     uint32_t   op;
     112    // select operation
    105113    if( cmd_type == IOC_WRITE ) op = BDV_OP_WRITE;
    106114    else                        op = BDV_OP_READ;
    107115
    108     // set SOCLIB_BDV registers to start one I/O operation
     116    // set SOCLIB_BDV registers to configure the I/O operation
    109117    hal_remote_s32( XPTR( seg_cxy , seg_ptr + BDV_IRQ_ENABLE_REG ) , 1       );
    110118    hal_remote_s32( XPTR( seg_cxy , seg_ptr + BDV_BUFFER_REG     ) , buf_lsb );
     
    112120    hal_remote_s32( XPTR( seg_cxy , seg_ptr + BDV_LBA_REG        ) , lba     );
    113121    hal_remote_s32( XPTR( seg_cxy , seg_ptr + BDV_COUNT_REG      ) , count   );
    114     hal_remote_s32( XPTR( seg_cxy , seg_ptr + BDV_OP_REG         ) , op      );
    115122
    116123    // waiting policy  depends on the command type
    117124    // - for IOC_READ / IOC_WRITE commands, this function is called by the server thread
    118     // - for IOC_SYNC_READ command, this function is directly called by the client thread
     125    //   that blocks and deschedules after launching the I/O transfer.
     126    //   The I/O operation status is reported in the command by the ISR.
     127    // - for IOC_SYNC_READ command, this function is called by the client thread
     128    //   that polls the BDV status register until I/O transfer completion.
    119129
    120130    if( cmd_type == IOC_SYNC_READ )                   // status polling policy
    121131    {
    122         uint32_t status;
     132        // launch I/O operation on BDV device
     133        hal_remote_s32( XPTR( seg_cxy , seg_ptr + BDV_OP_REG ) , op );
     134       
     135        // wait completion
    123136        while (1)
    124137        {
     
    143156    else                                            // descheduling + IRQ policy
    144157    {
     158        // enter critical section to atomically
     159        // lauch I/O operation and deschedule 
     160        hal_disable_irq( &save_sr );
     161
     162        // launch I/O operation on BDV device
     163        hal_remote_s32( XPTR( seg_cxy , seg_ptr + BDV_OP_REG ) , op );
     164       
     165        // server thread blocks on ISR
    145166        thread_block( XPTR( local_cxy , CURRENT_THREAD ) , THREAD_BLOCKED_ISR );
     167
     168#if DEBUG_HAL_IOC_RX
     169if( (DEBUG_HAL_IOC_RX < cycle) && (cmd_type != IOC_WRITE ) )
     170printk("\n[%s] thread[%x,%x] blocks & deschedules after lauching RX transfer\n",
     171__FUNCTION__ , this->process->pid, this->trdid );
     172#endif
     173
     174#if DEBUG_HAL_IOC_TX
     175if( (DEBUG_HAL_IOC_TX < cycle) && (cmd_type == IOC_WRITE) )
     176printk("\n[%s] thread[%x,%x] blocks & deschedules after lauching TX transfer\n",
     177__FUNCTION__ , this->process->pid, this->trdid );
     178#endif
     179        // server thread deschedules
    146180        sched_yield("blocked on ISR");
    147181
    148         // the IO operation status is reported in the command by the ISR
     182        // exit critical section
     183        hal_restore_irq( save_sr );
    149184    }
    150185   
    151186#if DEBUG_HAL_IOC_RX
    152187cycle = (uint32_t)hal_get_cycles();
    153 if( (DEBUG_HAL_IOC_RX < cycle) && (cmd_type != TXT_WRITE) )
    154 printk("\n[DBG] %s : thread %x exit after RX / cycle %d\n",
    155 __FUNCTION__ , CURRENT_THREAD , cycle );
     188if( (DEBUG_HAL_IOC_RX < cycle) && (cmd_type != IOC_WRITE) )
     189printk("\n[%s] thread[%x,%x] exit after RX for client thread[%x,%x] / cycle %d\n",
     190__FUNCTION__, this->process->pid, this->trdid, client_pid, client_trdid, cycle );
    156191#endif
    157192
    158193#if DEBUG_HAL_IOC_TX
    159194cycle = (uint32_t)hal_get_cycles();
    160 if( (DEBUG_HAL_IOC_TX < cycle) && (cmd_type == TXT_WRITE) )
    161 printk("\n[DBG] %s : thread %x exit after TX / cycle %d\n",
    162 __FUNCTION__ , CURRENT_THREAD , cycle );
     195if( (DEBUG_HAL_IOC_TX < cycle) && (cmd_type == IOC_WRITE) )
     196printk("\n[%s] thread[%x,%x] exit after TX for client thread[%x,%x] / cycle %d\n",
     197__FUNCTION__, this->process->pid, this->trdid, client_pid, client_trdid, cycle );
    163198#endif
    164199
     
    171206    error_t  error = 0;
    172207
     208    // get extended pointer on server thread
     209    xptr_t server_xp = XPTR( local_cxy , chdev->server );
     210
    173211    // get extended pointer on client thread
    174     xptr_t root = XPTR( local_cxy , &chdev->wait_root );
     212    xptr_t root      = XPTR( local_cxy , &chdev->wait_root );
    175213    xptr_t client_xp = XLIST_FIRST( root , thread_t , wait_list );
    176 
    177     // get extended pointer on server thread
    178     xptr_t server_xp = XPTR( local_cxy , &chdev->server );
    179214
    180215    // get client thread cluster and local pointer
    181216    cxy_t      client_cxy = GET_CXY( client_xp );
    182     thread_t * client_ptr = (thread_t *)GET_PTR( client_xp );
     217    thread_t * client_ptr = GET_PTR( client_xp );
    183218
    184219    // get command type
    185220    uint32_t   cmd_type = hal_remote_l32( XPTR( client_cxy , &client_ptr->ioc_cmd.type ) );
    186221   
     222#if (DEBUG_HAL_IOC_RX || DEBUG_HAL_IOC_TX)
     223uint32_t    cycle        = (uint32_t)hal_get_cycles();
     224process_t * process      = hal_remote_lpt( XPTR( client_cxy , &client_ptr->process ) );
     225pid_t       client_pid   = hal_remote_l32( XPTR( client_cxy , &process->pid ) );
     226trdid_t     client_trdid = hal_remote_l32( XPTR( client_cxy , &client_ptr->trdid ) );
     227thread_t  * server       = GET_PTR( server_xp );
     228pid_t       server_pid   = server->process->pid;
     229trdid_t     server_trdid = server->trdid;
     230#endif
     231
    187232    // get SOCLIB_BDV device cluster and local pointer
    188233    cxy_t      bdv_cxy  = GET_CXY( chdev->base );
    189     uint32_t * bdv_ptr  = (uint32_t *)GET_PTR( chdev->base );
     234    uint32_t * bdv_ptr  = GET_PTR( chdev->base );
    190235
    191236    // get BDV status register and acknowledge IRQ
     
    197242
    198243#if DEBUG_HAL_IOC_RX
    199 uint32_t cycle = (uint32_t)hal_get_cycles();
    200244if( DEBUG_HAL_IOC_RX < cycle )
    201 printk("\n[DBG] %s : IOC_IRQ / RX transfer / client %x / server %x / cycle %d\n",
    202 __FUNCTION__, client_ptr , chdev->server , cycle );
     245printk("\n[%s] RX transfer completed for client[%x,%x] / server[%x,%x] / cycle %d\n",
     246__FUNCTION__, client_pid, client_trdid, server_pid, server_trdid, cycle );
    203247#endif
    204248
     
    209253
    210254#if DEBUG_HAL_IOC_TX
    211 uint32_t cycle = (uint32_t)hal_get_cycles();
    212255if( DEBUG_HAL_IOC_TX < cycle )
    213 printk("\n[DBG] %s : IOC_IRQ / RX transfer / client %x / server %x / cycle %d\n",
    214 __FUNCTION__, client_ptr , chdev->server , cycle );
     256printk("\n[%s] TX transfer completed for client[%x,%x] / server[%x,%x] / cycle %d\n",
     257__FUNCTION__, client_pid, client_trdid, server_pid, server_trdid, cycle );
    215258#endif
    216259
  • trunk/kernel/Makefile

    r590 r610  
    138138              build/syscalls/sys_condvar.o         \
    139139              build/syscalls/sys_barrier.o         \
    140               build/syscalls/sys_mutex.o
    141 
    142 SYS_OBJS_1  = build/syscalls/sys_exit.o            \
     140              build/syscalls/sys_mutex.o 
     141
     142SYS_OBJS_1  = build/syscalls/sys_rename.o          \
    143143              build/syscalls/sys_munmap.o          \
    144144              build/syscalls/sys_open.o            \
     
    183183              build/syscalls/sys_fg.o              \
    184184              build/syscalls/sys_is_fg.o
     185
     186SYS_OBJS_5  = build/syscalls/sys_exit.o
    185187
    186188VFS_OBJS    = build/fs/vfs.o              \
     
    292294                        $(SYS_OBJS_3)                \
    293295                        $(SYS_OBJS_4)                \
     296                        $(SYS_OBJS_5)                \
    294297                        $(HAL_ARCH)/kernel.ld
    295298        $(LD) -o $@ -T $(HAL_ARCH)/kernel.ld $(LIBGCC)         \
     
    297300          $(LIBK_OBJS) $(DRIVERS_OBJS) $(VFS_OBJS)         \
    298301          $(SYS_OBJS_0) $(SYS_OBJS_1) $(SYS_OBJS_2)        \
    299           $(SYS_OBJS_3) $(SYS_OBJS_4) -lgcc
     302          $(SYS_OBJS_3) $(SYS_OBJS_4) $(SYS_OBJS_5) -lgcc
    300303        $(DU) -D $@ > $@.txt
    301304
  • trunk/kernel/fs/devfs.c

    r602 r610  
    9393    xptr_t   unused_xp;   // required by vfs_add_child_in_parent()
    9494
    95     // creates DEVFS "dev" inode in cluster 0
     95    // create DEVFS "dev" inode in cluster 0
    9696    error = vfs_add_child_in_parent( 0,                // cxy
    9797                                     INODE_TYPE_DIR,
     
    102102                                     devfs_dev_inode_xp );
    103103
    104     assert( (error == 0) , "cannot create <dev>\n" );
     104// check success
     105assert( (error == 0) , "cannot create <dev>\n" );
    105106
    106107#if DEBUG_DEVFS_INIT
     
    149150    // create "internal" directory
    150151    snprintf( node_name , 16 , "internal_%x" , local_cxy );
     152
    151153    vfs_add_child_in_parent( local_cxy,
    152154                             INODE_TYPE_DIR,
     
    169171    {
    170172        chdev_ptr = GET_PTR( chdev_xp );
     173        chdev_cxy = GET_CXY( chdev_xp );
     174
     175assert( (chdev_cxy == local_cxy ),
     176"illegal MMC chdev_xp in cluster %x\n", local_cxy );
     177
    171178        vfs_add_child_in_parent( local_cxy,
    172179                                 INODE_TYPE_DEV,
     
    198205        {
    199206            chdev_ptr = GET_PTR( chdev_xp );
     207            chdev_cxy = GET_CXY( chdev_xp );
     208
     209assert( (chdev_cxy == local_cxy ),
     210"illegal DMA[%d] chdev_xp in cluster %x\n", channel, local_cxy );
     211
    200212            vfs_add_child_in_parent( local_cxy,
    201213                                     INODE_TYPE_DEV,
     
    226238        chdev_cxy = GET_CXY( chdev_xp );
    227239        chdev_ptr = GET_PTR( chdev_xp );
     240
    228241        if( chdev_cxy == local_cxy )
    229242        {
     
    256269        chdev_cxy = GET_CXY( chdev_xp );
    257270        chdev_ptr = GET_PTR( chdev_xp );
     271
    258272        if( chdev_cxy == local_cxy )
    259273        {
     
    288302            chdev_cxy = GET_CXY( chdev_xp );
    289303            chdev_ptr = GET_PTR( chdev_xp );
     304
    290305            if( chdev_cxy == local_cxy )
    291306            {
     
    321336            chdev_cxy = GET_CXY( chdev_xp );
    322337            chdev_ptr = GET_PTR( chdev_xp );
     338
    323339            if( chdev_cxy == local_cxy )
    324340            {
     
    354370            chdev_cxy = GET_CXY( chdev_xp );
    355371            chdev_ptr = GET_PTR( chdev_xp );
     372
    356373            if( chdev_cxy == local_cxy )
    357374            {
     
    387404            chdev_cxy = GET_CXY( chdev_xp );
    388405            chdev_ptr = GET_PTR( chdev_xp );
     406
    389407            if( chdev_cxy == local_cxy )
    390408            {
     
    419437        {
    420438            chdev_cxy = GET_CXY( chdev_xp );
    421             chdev_ptr = (chdev_t *)GET_PTR( chdev_xp );
     439            chdev_ptr = GET_PTR( chdev_xp );
     440
    422441            if( chdev_cxy == local_cxy )
    423442            {
     
    447466            chdev_cxy = GET_CXY( chdev_xp );
    448467            chdev_ptr = GET_PTR( chdev_xp );
     468
    449469            if( chdev_cxy == local_cxy )
    450470            {
  • trunk/kernel/fs/fatfs.c

    r602 r610  
    12461246vfs_inode_get_name( XPTR( local_cxy , inode ) , dir_name );
    12471247if( DEBUG_FATFS_REMOVE_DENTRY < cycle )
    1248 printk("\n[%s]  thread[%x,%x] enter / parent <%s> / child <%s> / cycle %d\n",
     1248printk("\n[%s] thread[%x,%x] enter / parent <%s> / child <%s> / cycle %d\n",
    12491249__FUNCTION__, this->process->pid, this->trdid, dir_name, dentry->name, cycle );
    12501250#endif
     
    12801280    uint32_t  page_id    = dentry_id >> 7;
    12811281    uint32_t  offset     = (dentry_id & 0x7F)<<5;
     1282
     1283#if DEBUG_FATFS_REMOVE_DENTRY & 1
     1284if( DEBUG_FATFS_REMOVE_DENTRY < cycle )
     1285printk("\n[%s] dentry_id %x / page_id %x / offset %x\n",
     1286__FUNCTION__, dentry_id, page_id, offset );
     1287#endif
    12821288
    12831289    // get extended pointer on page descriptor from parent directory mapper
     
    13451351cycle = (uint32_t)hal_get_cycles();
    13461352if( DEBUG_FATFS_REMOVE_DENTRY < cycle )
    1347 printk("\n[%s]  thread[%x,%x] exit / parent %s / child %s / cycle %d\n",
     1353printk("\n[%s] thread[%x,%x] exit / parent %s / child %s / cycle %d\n",
    13481354__FUNCTION__, this->process->pid, this->trdid, dir_name, dentry->name, cycle );
    13491355#endif
     
    13581364                          xptr_t        child_inode_xp )
    13591365{
    1360     // Two embedded loops:
     1366    // Two embedded loops to scan the directory mapper:
    13611367    // - scan the parent directory mapper pages
    13621368    // - scan the directory entries in each 4 Kbytes page
     
    15121518    // get child inode cluster and local pointer
    15131519    cxy_t          inode_cxy = GET_CXY( child_inode_xp );
    1514     vfs_inode_t  * inode_ptr = (vfs_inode_t *)GET_PTR( child_inode_xp );
     1520    vfs_inode_t  * inode_ptr = GET_PTR( child_inode_xp );
     1521
     1522    // build extended pointer on parent dentried root
     1523    xptr_t parents_root_xp = XPTR( inode_cxy , &inode_ptr->parents );
     1524
     1525// check child inode has at least one parent
     1526assert( (xlist_is_empty( parents_root_xp ) == false ), "child inode must have one parent\n");
    15151527
    15161528    // get dentry pointers and cluster
    1517     xptr_t         dentry_xp  = hal_remote_l64( XPTR( inode_cxy , &inode_ptr->parent_xp ) ); 
     1529    xptr_t         dentry_xp  = XLIST_FIRST( parents_root_xp , vfs_dentry_t , parents );
    15181530    vfs_dentry_t * dentry_ptr = GET_PTR( dentry_xp );
    15191531    cxy_t          dentry_cxy = GET_CXY( dentry_xp );
    15201532
    1521 // dentry descriptor must be in same cluster as parent inode
     1533// check dentry descriptor in same cluster as parent inode
    15221534assert( (dentry_cxy == local_cxy) , "illegal dentry cluster\n" );
    15231535
  • trunk/kernel/fs/fatfs.h

    r602 r610  
    311311 * This function implements the generic vfs_fs_child_init() function for the FATFS.
    312312 *****************************************************************************************
    313  * It scan the mapper of an existing parent directory, identified by the <parent>
    314  * argument, to find a directory entry identified by the <name> argument.
    315  * It updates the existing remote child inode, identified by the <child_xp> argument,
     313 * It tries to initialise a new child (new inode/dentry couple in Inode Tree), identified
     314 * by the <child_inode_xp> argument, from the parent directory mapper, identified by the
     315 * <parent_inode> argument.
     316 * - It scan the parent mapper to find the <name> argument.
    316317 * - it set the "type", "size", and "extend" fields in inode descriptor.
    317318 * - it set the " extend" field in dentry descriptor.
  • trunk/kernel/fs/vfs.c

    r602 r610  
    141141}
    142142
    143 //////////////////////////////////////////////////////
    144 error_t vfs_inode_create( xptr_t            dentry_xp,
    145                           vfs_fs_type_t     fs_type,
     143////////////////////////////////////////////////////
     144error_t vfs_inode_create( vfs_fs_type_t     fs_type,
    146145                          vfs_inode_type_t  inode_type,
    147146                          uint32_t          attr,
     
    212211        vfs_ctx_inum_release( ctx , inum );
    213212        mapper_destroy( mapper );
    214         return ENOMEM;
     213        return -1;
    215214    }
    216215
    217216    // initialize inode descriptor
    218     inode->gc         = 0;
    219217    inode->type       = inode_type;
    220218    inode->inum       = inum;
     
    223221    inode->uid        = uid;
    224222    inode->gid        = gid;
    225     inode->refcount   = 0;
    226     inode->parent_xp  = dentry_xp;
    227223    inode->ctx        = ctx;
    228224    inode->mapper     = mapper;
    229225    inode->extend     = NULL;
     226    inode->links      = 0;
    230227
    231228    // initialise inode field in mapper
     
    233230 
    234231    // initialise threads waiting queue
    235     xlist_root_init( XPTR( local_cxy , &inode->wait_root ) );
    236 
    237     // initialize dentries hash table
     232    // xlist_root_init( XPTR( local_cxy , &inode->wait_root ) );
     233
     234    // initialize chidren dentries xhtab
    238235    xhtab_init( &inode->children , XHTAB_DENTRY_TYPE );
    239236
    240     // initialize inode lock
    241     remote_rwlock_init( XPTR( local_cxy , &inode->data_lock ), LOCK_VFS_INODE );
    242 
    243     // initialise lock protecting inode three traversal
    244     remote_busylock_init( XPTR( local_cxy , &inode->main_lock ), LOCK_VFS_MAIN );
     237    // initialize parents dentries xlist
     238    xlist_root_init( XPTR( local_cxy , &inode->parents ) );
     239 
     240    // initialize lock protecting size
     241    remote_rwlock_init( XPTR( local_cxy , &inode->size_lock ), LOCK_VFS_SIZE );
     242
     243    // initialise lock protecting inode tree traversal
     244    remote_rwlock_init( XPTR( local_cxy , &inode->main_lock ), LOCK_VFS_MAIN );
     245
     246    // return extended pointer on inode
     247    *inode_xp = XPTR( local_cxy , inode );
    245248
    246249#if DEBUG_VFS_INODE_CREATE
     
    251254#endif
    252255 
    253     // return extended pointer on inode
    254     *inode_xp = XPTR( local_cxy , inode );
    255256    return 0;
    256257
     
    260261void vfs_inode_destroy( vfs_inode_t * inode )
    261262{
    262 
    263 // check inode refcount
    264 assert( (inode->refcount == 0) , "inode refcount non zero\n" );
    265 
    266263    // release memory allocated for mapper
    267264    mapper_destroy( inode->mapper );
     
    275272}  // end vfs_inode_destroy()
    276273
    277 ////////////////////////////////////////////
    278 void vfs_inode_remote_up( xptr_t  inode_xp )
    279 {
    280     // get inode cluster and local pointer
    281     cxy_t         inode_cxy = GET_CXY( inode_xp );
    282     vfs_inode_t * inode_ptr = GET_PTR( inode_xp );
    283 
    284     hal_remote_atomic_add( XPTR( inode_cxy , &inode_ptr->refcount ) , 1 );   
    285 }
    286 
    287 //////////////////////////////////////////////
    288 void vfs_inode_remote_down( xptr_t  inode_xp )
    289 {
    290     // get inode cluster and local pointer
    291     cxy_t         inode_cxy = GET_CXY( inode_xp );
    292     vfs_inode_t * inode_ptr = GET_PTR( inode_xp );
    293 
    294     hal_remote_atomic_add( XPTR( inode_cxy , &inode_ptr->refcount ) , -1 );   
    295 }
    296 
    297274//////////////////////////////////////////////
    298275uint32_t vfs_inode_get_size( xptr_t inode_xp )
     
    303280
    304281    // get size
    305     remote_rwlock_rd_acquire( XPTR( cxy , &ptr->data_lock ) );
     282    remote_rwlock_rd_acquire( XPTR( cxy , &ptr->size_lock ) );
    306283    uint32_t size = hal_remote_l32( XPTR( cxy , &ptr->size ) );
    307     remote_rwlock_rd_release( XPTR( cxy , &ptr->data_lock ) );
     284    remote_rwlock_rd_release( XPTR( cxy , &ptr->size_lock ) );
    308285    return size;
    309286}
     
    318295
    319296    // set size
    320     remote_rwlock_wr_release( XPTR( cxy , &ptr->data_lock ) );
     297    remote_rwlock_wr_release( XPTR( cxy , &ptr->size_lock ) );
    321298    hal_remote_s32( XPTR( cxy , &ptr->size ) , size );
    322     remote_rwlock_wr_release( XPTR( cxy , &ptr->data_lock ) );
     299    remote_rwlock_wr_release( XPTR( cxy , &ptr->size_lock ) );
    323300}
    324301
     
    345322}
    346323
    347 /////////////////////////////////////////
    348 void vfs_inode_get_name( xptr_t inode_xp,
    349                          char * name )
    350 {
    351     cxy_t          inode_cxy;
    352     vfs_inode_t  * inode_ptr;
    353     xptr_t         dentry_xp;
    354     cxy_t          dentry_cxy;
    355     vfs_dentry_t * dentry_ptr;
     324///////////////////////////////////////////
     325void vfs_inode_get_name( xptr_t   inode_xp,
     326                         char   * name )
     327{
     328    cxy_t          inode_cxy;          // inode cluster identifier
     329    vfs_inode_t  * inode_ptr;          // local pointer on inode
     330    xptr_t         parents_root_xp;    // extended pointer on inode parents root
    356331   
    357332    // get inode cluster and local pointer
     
    359334    inode_ptr = GET_PTR( inode_xp );
    360335
    361     // get parent dentry
    362     dentry_xp  = hal_remote_l64( XPTR( inode_cxy , &inode_ptr->parent_xp ) );
    363 
    364     // get local copy of name
    365     if( dentry_xp == XPTR_NULL )  // it is the VFS root
     336    // build extended pointer on parents dentries root
     337    parents_root_xp  = XPTR( inode_cxy , &inode_ptr->parents );
     338
     339    // check VFS root
     340    if( xlist_is_empty( parents_root_xp ) )  // inode is the VFS root
    366341    {
    367342        strcpy( name , "/" );
    368343    }
    369     else                          // not the VFS root
    370     {
     344    else                                     // not the VFS root
     345    {
     346        xptr_t         dentry_xp;
     347        cxy_t          dentry_cxy;
     348        vfs_dentry_t * dentry_ptr;
     349
     350        // get first name in list of parents
     351        dentry_xp  = XLIST_FIRST( parents_root_xp , vfs_dentry_t , parents );
    371352        dentry_cxy = GET_CXY( dentry_xp );
    372353        dentry_ptr = GET_PTR( dentry_xp );
    373354
    374355        hal_remote_strcpy( XPTR( local_cxy  , name ) ,
    375                            XPTR( dentry_cxy , &dentry_ptr->name ) );
    376     }
     356                           XPTR( dentry_cxy , dentry_ptr->name ) );
     357    }
     358
    377359}  // end vfs_inode_get_name()
    378360
     
    433415error_t vfs_dentry_create( vfs_fs_type_t   fs_type,
    434416                           char          * name,
    435                            vfs_inode_t   * parent,
    436417                           xptr_t        * dentry_xp )
    437418{
     
    439420    vfs_dentry_t   * dentry;     // dentry descriptor (to be allocated)
    440421        kmem_req_t       req;        // request to kernel memory allocator
    441     error_t          error;
    442422
    443423#if DEBUG_VFS_DENTRY_CREATE
     
    456436    {
    457437        ctx = NULL;
    458         return EINVAL;
     438        return -1;
    459439    }
    460440
     
    470450        dentry     = (vfs_dentry_t *)kmem_alloc( &req );
    471451
    472     if( dentry == NULL ) return ENOMEM;
     452    if( dentry == NULL )
     453    {
     454        printk("\n[ERROR] in %s : cannot allocate dentry descriptor\n",
     455        __FUNCTION__ );
     456        return -1;
     457    }
    473458
    474459    // initialize dentry descriptor
    475 
    476460    dentry->ctx     = ctx;
    477461    dentry->length  = length;
    478     dentry->parent  = parent;
    479462    dentry->extend  = NULL;
    480463    strcpy( dentry->name , name );
    481 
    482 #if( DEBUG_VFS_DENTRY_CREATE & 1 )
    483 cycle = (uint32_t)hal_get_cycles();
    484 if( DEBUG_VFS_DENTRY_CREATE < cycle )
    485 printk("\n[%s] thread[%x,%x] / dentry <%s> initialised / cycle %d\n",
    486 __FUNCTION__, this->process->pid, this->trdid, dentry->name, cycle );
    487 #endif
    488 
    489     // register dentry in hash table rooted in parent inode
    490     error = xhtab_insert( XPTR( local_cxy , &parent->children ),
    491                           name,
    492                           XPTR( local_cxy , &dentry->list ) );
    493 
    494     if( error ) return EINVAL;
    495 
    496 #if( DEBUG_VFS_DENTRY_CREATE & 1 )
    497 cycle = (uint32_t)hal_get_cycles();
    498 if( DEBUG_VFS_DENTRY_CREATE < cycle )
    499 printk("\n[%s] thread[%x,%x] / dentry <%s> registered / cycle %d\n",
    500 __FUNCTION__, this->process->pid, this->trdid, dentry->name, cycle );
    501 #endif
    502464
    503465    // return extended pointer on dentry
     
    518480void vfs_dentry_destroy( vfs_dentry_t * dentry )
    519481{
    520 
    521 // check dentry refcount
    522 assert( (dentry->refcount == 0) , "dentry refcount non zero\n" );
    523 
    524     // get pointer on parent inode
    525     vfs_inode_t * parent = dentry->parent;
    526 
    527     // remove this dentry from parent inode htab
    528     xhtab_remove( XPTR( local_cxy , &parent->children ),
    529                   dentry->name,
    530                   XPTR( local_cxy , &dentry->list ) );
    531 
    532482    // release memory allocated to dentry
    533483        kmem_req_t req;
     
    537487
    538488}  // end vfs_dentry_destroy()
    539 
    540 //////////////////////////////////////////////
    541 void vfs_dentry_remote_up( xptr_t  dentry_xp )
    542 {
    543     // get dentry cluster and local pointer
    544     cxy_t          dentry_cxy = GET_CXY( dentry_xp );
    545     vfs_dentry_t * dentry_ptr = GET_PTR( dentry_xp );
    546 
    547     hal_remote_atomic_add( XPTR( dentry_cxy , &dentry_ptr->refcount ) , 1 );   
    548 }
    549 
    550 ////////////////////////////////////////////////
    551 void vfs_dentry_remote_down( xptr_t  dentry_xp )
    552 {
    553     // get dentry cluster and local pointer
    554     cxy_t          dentry_cxy = GET_CXY( dentry_xp );
    555     vfs_dentry_t * dentry_ptr = GET_PTR( dentry_xp );
    556 
    557     hal_remote_atomic_add( XPTR( dentry_cxy , &dentry_ptr->refcount ) , -1 );   
    558 }
    559 
    560489
    561490
     
    616545void vfs_file_destroy( vfs_file_t *  file )
    617546{
    618     if( file->refcount )
    619     {
    620         assert( false , "refcount non zero\n" );
    621     }       
     547
     548// check refcount
     549assert( (file->refcount == 0) , "refcount non zero\n" );
    622550
    623551        kmem_req_t req;
     
    664592
    665593//////////////////////////////////////
    666 error_t vfs_open( process_t * process,
     594error_t vfs_open( xptr_t      root_xp,
    667595                          char      * path,
     596                  xptr_t      process_xp,
    668597                          uint32_t    flags,
    669598                  uint32_t    mode,
     
    671600                  uint32_t  * new_file_id )
    672601{
    673     error_t       error;
    674     xptr_t        inode_xp;     // extended pointer on target inode
    675     cxy_t         inode_cxy;    // inode cluster identifier       
    676     vfs_inode_t * inode_ptr;    // inode local pointer
    677     uint32_t      file_attr;    // file descriptor attributes
    678     uint32_t      lookup_mode;  // lookup working mode       
    679     xptr_t        file_xp;      // extended pointer on created file descriptor
    680     uint32_t      file_id;      // created file descriptor index in reference fd_array
    681 
     602    error_t        error;
     603    xptr_t         inode_xp;       // extended pointer on target inode
     604    cxy_t          inode_cxy;      // inode cluster identifier       
     605    vfs_inode_t  * inode_ptr;      // inode local pointer
     606    uint32_t       file_attr;      // file descriptor attributes
     607    uint32_t       lookup_mode;    // lookup working mode       
     608    xptr_t         file_xp;        // extended pointer on created file descriptor
     609    uint32_t       file_id;        // created file descriptor index in reference fd_array
     610    xptr_t         vfs_root_xp;    // extended pointer on VFS root inode
     611    vfs_inode_t  * vfs_root_ptr;   // local pointer on VFS root inode
     612    cxy_t          vfs_root_cxy;   // VFS root inode cluster identifier
     613    xptr_t         lock_xp;        // extended pointer on Inode Tree lock
    682614
    683615    if( mode != 0 )
     
    687619    }
    688620
     621    thread_t  * this    = CURRENT_THREAD;
     622    process_t * process = this->process;
     623
    689624#if DEBUG_VFS_OPEN
    690 thread_t * this = CURRENT_THREAD;
    691625uint32_t cycle = (uint32_t)hal_get_cycles();
    692626if( DEBUG_VFS_OPEN < cycle )
    693 printk("\n[%s]   thread[%x,%x] enter for <%s> / cycle %d\n",
    694 __FUNCTION__, this->process->pid, this->trdid, path, cycle );
     627printk("\n[%s] thread[%x,%x] enter for <%s> / root_inode (%x,%x) / cycle %d\n",
     628__FUNCTION__, process->pid, this->trdid, path, GET_CXY(root_xp), GET_PTR(root_xp), cycle );
    695629#endif
    696630
     
    709643    if( (flags & O_CLOEXEC)      )  file_attr |= FD_ATTR_CLOSE_EXEC;
    710644
     645    // build extended pointer on lock protecting Inode Tree
     646    vfs_root_xp  = process->vfs_root_xp;
     647    vfs_root_ptr = GET_PTR( vfs_root_xp );
     648    vfs_root_cxy = GET_CXY( vfs_root_xp );
     649    lock_xp      = XPTR( vfs_root_cxy , &vfs_root_ptr->main_lock );
     650
     651    // take lock protecting Inode Tree in read mode
     652    remote_rwlock_rd_acquire( lock_xp );
     653
    711654    // get extended pointer on target inode
    712     error = vfs_lookup( process->vfs_cwd_xp , path , lookup_mode , &inode_xp );
    713 
    714     if( error ) return error;
     655    error = vfs_lookup( root_xp,
     656                        path,
     657                        lookup_mode,
     658                        &inode_xp,
     659                        NULL );
     660
     661    // release lock protecting Inode Tree
     662    remote_rwlock_rd_release( lock_xp );
     663
     664    if( error )
     665    {
     666        printk("\n[ERROR] in %s : cannot get inode <%s>\n",
     667        __FUNCTION__ , path );
     668        return -1;
     669    }
    715670
    716671    // get target inode cluster and local pointer
     
    718673    inode_ptr = GET_PTR( inode_xp );
    719674   
     675#if (DEBUG_VFS_OPEN & 1)
     676cycle = (uint32_t)hal_get_cycles();
     677if( DEBUG_VFS_OPEN < cycle )
     678printk("\n[%s] thread[%x,%x] found inode(%x,%x) for <%s>\n",
     679__FUNCTION__, process->pid, this->trdid, inode_cxy, inode_ptr, path );
     680#endif
     681
    720682    // create a new file descriptor in cluster containing inode
    721683    if( inode_cxy == local_cxy )      // target cluster is local
     
    730692    if( error )  return error;
    731693
     694#if (DEBUG_VFS_OPEN & 1)
     695cycle = (uint32_t)hal_get_cycles();
     696if( DEBUG_VFS_OPEN < cycle )
     697printk("\n[%s] thread[%x,%x] created file descriptor (%x,%x) for <%s>\n",
     698__FUNCTION__, process->pid, this->trdid, GET_CXY(file_xp), GET_PTR(file_xp), path );
     699#endif
     700
    732701    // allocate and register a new file descriptor index in reference process
    733     error = process_fd_register( process , file_xp , &file_id );
     702    error = process_fd_register( process_xp , file_xp , &file_id );
    734703
    735704    if( error ) return error;
     
    738707cycle = (uint32_t)hal_get_cycles();
    739708if( DEBUG_VFS_OPEN < cycle )
    740 printk("\n[%s]   thread[%x,%x] exit for <%s> / fdid %d / cluster %x / cycle %d\n",
    741 __FUNCTION__, this->process->pid, this->trdid, path, file_id, GET_CXY( file_xp ), cycle );
     709printk("\n[%s] thread[%x,%x] exit for <%s> / fdid %d / cluster %x / cycle %d\n",
     710__FUNCTION__, process->pid, this->trdid, path, file_id, GET_CXY( file_xp ), cycle );
    742711#endif
    743712
     
    780749
    781750    // move data between mapper and buffer
    782     if( file_cxy == local_cxy )
    783     {
    784         error = mapper_move_user( mapper,
    785                                   to_buffer,
    786                                   file_offset,
    787                                   buffer,
    788                                   size );
    789     }
    790     else
    791     {
    792         rpc_mapper_move_user_client( file_cxy,
    793                                      mapper,
    794                                      to_buffer,
    795                                      file_offset,
    796                                      buffer,
    797                                      size,
    798                                      &error );
    799     }
     751    error = mapper_move_user( XPTR( file_cxy , mapper ),
     752                              to_buffer,
     753                              file_offset,
     754                              buffer,
     755                              size );
    800756
    801757    // update file offset in file descriptor
     
    834790    // get inode type from remote file descriptor
    835791    inode_type = hal_remote_l32( XPTR( file_cxy , &file_ptr->type   ) );
    836    
     792
    837793    // action depends on inode type
    838794    if( inode_type == INODE_TYPE_FILE )
     
    10441000
    10451001////////////////////////////////////
    1046 error_t vfs_unlink( xptr_t   cwd_xp,
     1002error_t vfs_mkdir( xptr_t   root_xp,
     1003                   char   * path,
     1004                   uint32_t rights )
     1005{
     1006    error_t        error;
     1007    xptr_t         vfs_root_xp;        // extended pointer on VFS root inode
     1008    vfs_inode_t  * vfs_root_ptr;       // local pointer on VFS root inode
     1009    cxy_t          vfs_root_cxy;       // VFS root inode cluster identifier
     1010    xptr_t         lock_xp;            // extended pointer on lock protecting Inode Tree
     1011    xptr_t         inode_xp;           // extended pointer on target inode
     1012    vfs_inode_t  * inode_ptr;          // local pointer on target inode
     1013    cxy_t          inode_cxy;          // target inode cluster identifier
     1014    xptr_t         dentry_xp;          // extended pointer on new dentry
     1015    vfs_dentry_t * dentry_ptr;         // target dentry local pointer
     1016    xptr_t         parent_xp;          // extended pointer on new parent inode
     1017    vfs_inode_t  * parent_ptr;         // local pointer on new parent inode 
     1018    cxy_t          parent_cxy;         // new parent inode cluster identifier
     1019    vfs_ctx_t    * parent_ctx_ptr;     // local pointer on target inode context
     1020    uint32_t       parent_fs_type;     // target inode file system type
     1021
     1022    xptr_t         parents_root_xp;    // extended pointer on parents field in inode (root)
     1023    xptr_t         parents_entry_xp;   // extended pointer on parents field in dentry
     1024    xptr_t         children_xhtab_xp;  // extended pointer on children field in inode (root)
     1025    xptr_t         children_entry_xp;  // extended pointer on children field in dentry
     1026
     1027    char           last_name[CONFIG_VFS_MAX_NAME_LENGTH];
     1028
     1029    thread_t  * this    = CURRENT_THREAD;
     1030    process_t * process = this->process;
     1031
     1032#if DEBUG_VFS_MKDIR
     1033char root_name[CONFIG_VFS_MAX_NAME_LENGTH];
     1034vfs_inode_get_name( root_xp , root_name );
     1035uint32_t   cycle = (uint32_t)hal_get_cycles();
     1036if( DEBUG_VFS_MKDIR < cycle )
     1037printk("\n[%s] thread[%x,%x] enter / root <%s> / path <%s> / cycle %d\n",
     1038__FUNCTION__, process->pid, this->trdid, root_name, path, cycle );
     1039#endif
     1040
     1041    // build extended pointer on lock protecting Inode Tree (in VFS root inode)
     1042    vfs_root_xp  = process->vfs_root_xp;
     1043    vfs_root_ptr = GET_PTR( vfs_root_xp );
     1044    vfs_root_cxy = GET_CXY( vfs_root_xp );
     1045    lock_xp      = XPTR( vfs_root_cxy , &vfs_root_ptr->main_lock );
     1046
     1047    // take the lock protecting Inode Tree in write mode
     1048    remote_rwlock_wr_acquire( lock_xp );
     1049
     1050    // 1. get pointers on parent inode
     1051    error = vfs_lookup( root_xp,
     1052                        path,
     1053                        VFS_LOOKUP_DIR | VFS_LOOKUP_PARENT,
     1054                        &parent_xp,
     1055                        last_name );
     1056    if( error )
     1057    {
     1058        remote_rwlock_wr_release( lock_xp );
     1059        printk("\n[ERROR] in %s : cannot get parent inode for <%s>\n",
     1060        __FUNCTION__, path );
     1061        return -1;
     1062    }
     1063
     1064    // get parent inode cluster and local pointer
     1065    parent_cxy = GET_CXY( parent_xp );
     1066    parent_ptr = GET_PTR( parent_xp );
     1067
     1068#if( DEBUG_VFS_MKDIR & 1 )
     1069if( DEBUG_VFS_MKDIR < cycle )
     1070printk("\n[%s] thread[%x,%x] get parent inode (%x,%x) for <%s>\n",
     1071__FUNCTION__, process->pid, this->trdid, parent_cxy, parent_ptr, path );
     1072#endif
     1073
     1074    // get parent inode context, and FS type
     1075    parent_ctx_ptr = hal_remote_lpt( XPTR( parent_cxy , &parent_ptr->ctx ) );
     1076    parent_fs_type = hal_remote_l32( XPTR( parent_cxy , &parent_ctx_ptr->type ) );
     1077
     1078    // 2. create one new dentry in parent cluster
     1079    if( parent_cxy == local_cxy ) 
     1080    {
     1081        error = vfs_dentry_create( parent_fs_type,
     1082                                   last_name,
     1083                                   &dentry_xp );
     1084    }
     1085    else
     1086    {
     1087        rpc_vfs_dentry_create_client( parent_cxy,
     1088                                      parent_fs_type,
     1089                                      last_name,
     1090                                      &dentry_xp,
     1091                                      &error );
     1092    }
     1093
     1094    if( error )
     1095    {
     1096        remote_rwlock_wr_release( lock_xp );
     1097        printk("\n[ERROR] in %s : cannot create new dentry in cluster %x for <%s>\n",
     1098        __FUNCTION__, parent_cxy, path );
     1099        return -1;
     1100    }
     1101
     1102    // get local pointer on dentry
     1103    dentry_ptr = GET_PTR( dentry_xp );
     1104
     1105#if( DEBUG_VFS_MKDIR & 1 )
     1106if( DEBUG_VFS_MKDIR < cycle )
     1107printk("\n[%s] thread[%x,%x] created new dentry (%x,%x) for <%s>\n",
     1108__FUNCTION__, process->pid, this->trdid, parent_cxy, dentry_ptr, path );
     1109#endif
     1110
     1111    // 3. create new directory inode in child cluster
     1112    // TODO : define attr / uid / gid
     1113    uint32_t attr = 0;
     1114    uint32_t uid  = 0;
     1115    uint32_t gid  = 0;
     1116
     1117    // select a target cluster for new inode
     1118    inode_cxy = cluster_random_select();
     1119   
     1120    if( inode_cxy == local_cxy )      // child cluster is local
     1121    {
     1122        error = vfs_inode_create( parent_fs_type,
     1123                                  INODE_TYPE_DIR,
     1124                                  attr,
     1125                                  rights,
     1126                                  uid,
     1127                                  gid,
     1128                                  &inode_xp );
     1129    }
     1130    else                              // child cluster is remote
     1131    {
     1132        rpc_vfs_inode_create_client( inode_cxy,
     1133                                     parent_fs_type,
     1134                                     INODE_TYPE_DIR,
     1135                                     attr,
     1136                                     rights,
     1137                                     uid,
     1138                                     gid,
     1139                                     &inode_xp,
     1140                                     &error );
     1141    }
     1142                                     
     1143    if( error )
     1144    {
     1145        printk("\n[ERROR] in %s : cannot create new inode in cluster %x for <%s>\n",
     1146               __FUNCTION__ , inode_cxy , path );
     1147 
     1148        if( parent_cxy == local_cxy ) vfs_dentry_destroy( dentry_ptr );
     1149        else rpc_vfs_dentry_destroy_client( parent_cxy , dentry_ptr );
     1150        return -1;
     1151    }
     1152
     1153    // get new inode local pointer
     1154    inode_ptr = GET_PTR( inode_xp );
     1155   
     1156#if(DEBUG_VFS_MKDIR & 1)
     1157if( DEBUG_VFS_MKDIR < cycle )
     1158printk("\n[%s] thread[%x,%x] created new inode (%x,%x) for <%s>\n",
     1159__FUNCTION__ , process->pid, this->trdid, inode_cxy, inode_ptr, path );
     1160#endif
     1161
     1162    // 4. register dentry in new inode list of parents
     1163    parents_root_xp  = XPTR( inode_cxy  , &inode_ptr->parents );
     1164    parents_entry_xp = XPTR( parent_cxy , &dentry_ptr->parents );
     1165    xlist_add_first( parents_root_xp , parents_entry_xp );
     1166    hal_remote_atomic_add( XPTR( inode_cxy , &inode_ptr->links ) , 1 );
     1167
     1168    // 5. register dentry in parent inode
     1169    children_xhtab_xp = XPTR( parent_cxy , &parent_ptr->children );
     1170    children_entry_xp = XPTR( parent_cxy , &dentry_ptr->children );
     1171    xhtab_insert( children_xhtab_xp , last_name , children_entry_xp );
     1172
     1173    // 6. update "parent" and "child_xp" fields in dentry
     1174    hal_remote_s64( XPTR( parent_cxy , &dentry_ptr->child_xp ) , inode_xp );
     1175    hal_remote_spt( XPTR( parent_cxy , &dentry_ptr->parent ) , parent_ptr );
     1176
     1177#if(DEBUG_VFS_MKDIR & 1)
     1178if( DEBUG_VFS_MKDIR < cycle )
     1179printk("\n[%s] thread[%x,%x] updated Inode Tree for <%s>\n",
     1180__FUNCTION__, process->pid, this->trdid, path );
     1181#endif
     1182
     1183    // release the lock protecting Inode Tree
     1184    remote_rwlock_wr_release( lock_xp );
     1185
     1186    // 5. update parent directory mapper
     1187    //    and synchronize the parent directory on IOC device
     1188    if (parent_cxy == local_cxy)
     1189    {
     1190        error = vfs_fs_add_dentry( parent_ptr,
     1191                                   dentry_ptr );
     1192    }
     1193    else
     1194    {
     1195        rpc_vfs_fs_add_dentry_client( parent_cxy,
     1196                                      parent_ptr,
     1197                                      dentry_ptr,
     1198                                      &error );
     1199    }
     1200
     1201    if( error )
     1202    {
     1203        printk("\n[ERROR] in %s : cannot update parent directory for <%s>\n",
     1204        __FUNCTION__, path );
     1205        return -1;
     1206    }
     1207
     1208#if(DEBUG_VFS_MKDIR & 1)
     1209if( DEBUG_VFS_MKDIR < cycle )
     1210printk("\n[%s] thread[%x,%x] updated parent dir (mapper and IOC) for <%s>\n",
     1211__FUNCTION__, process->pid, this->trdid, path );
     1212#endif
     1213
     1214    return 0;
     1215
     1216}  // end vfs_mkdir()
     1217
     1218///////////////////////////////////////
     1219error_t vfs_link( xptr_t   old_root_xp,
     1220                  char   * old_path,
     1221                  xptr_t   new_root_xp,
     1222                  char   * new_path )
     1223{
     1224    error_t        error;
     1225    xptr_t         vfs_root_xp;        // extended pointer on VFS root inode
     1226    vfs_inode_t  * vfs_root_ptr;       // local pointer on VFS root inode
     1227    cxy_t          vfs_root_cxy;       // VFS root inode cluster identifier
     1228    xptr_t         lock_xp;            // extended pointer on lock protecting Inode Tree
     1229    xptr_t         inode_xp;           // extended pointer on target inode
     1230    vfs_inode_t  * inode_ptr;          // local pointer on target inode
     1231    cxy_t          inode_cxy;          // target inode cluster identifier
     1232    uint32_t       inode_type;         // target inode type
     1233    vfs_ctx_t    * inode_ctx_ptr;      // local pointer on target inode context
     1234    uint32_t       inode_fs_type;      // target inode file system type
     1235    xptr_t         dentry_xp;          // extended pointer on new dentry
     1236    vfs_dentry_t * dentry_ptr;         // target dentry local pointer
     1237    xptr_t         new_parent_xp;      // extended pointer on new parent inode
     1238    vfs_inode_t  * new_parent_ptr;     // local pointer on new parent inode 
     1239    cxy_t          new_parent_cxy;     // new parent inode cluster identifier
     1240
     1241    xptr_t         parents_root_xp;    // extended pointer on parents field in inode (root)
     1242    xptr_t         parents_entry_xp;   // extended pointer on parents field in dentry
     1243    xptr_t         children_xhtab_xp;  // extended pointer on children field in inode (root)
     1244    xptr_t         children_entry_xp;  // extended pointer on children field in dentry
     1245
     1246    char           new_name[CONFIG_VFS_MAX_NAME_LENGTH];
     1247
     1248    thread_t  * this    = CURRENT_THREAD;
     1249    process_t * process = this->process;
     1250
     1251#if DEBUG_VFS_LINK
     1252char old_root_name[CONFIG_VFS_MAX_NAME_LENGTH];
     1253char new_root_name[CONFIG_VFS_MAX_NAME_LENGTH];
     1254vfs_inode_get_name( old_root_xp , old_root_name );
     1255vfs_inode_get_name( new_root_xp , new_root_name );
     1256uint32_t   cycle = (uint32_t)hal_get_cycles();
     1257if( DEBUG_VFS_LINK < cycle )
     1258printk("\n[%s] thread[%x,%x] enter / old_root <%s> / old_path <%s> / "
     1259"new_root <%s> / new_path <%s> / cycle %d\n",
     1260__FUNCTION__, process->pid, this->trdid,
     1261old_root_name, old_path, new_root_name, new_path, cycle );
     1262#endif
     1263
     1264    // build extended pointer on lock protecting Inode Tree (in VFS root inode)
     1265    vfs_root_xp  = process->vfs_root_xp;
     1266    vfs_root_ptr = GET_PTR( vfs_root_xp );
     1267    vfs_root_cxy = GET_CXY( vfs_root_xp );
     1268    lock_xp      = XPTR( vfs_root_cxy , &vfs_root_ptr->main_lock );
     1269
     1270    // take the lock protecting Inode Tree in write mode
     1271    remote_rwlock_wr_acquire( lock_xp );
     1272
     1273    // get extended pointer on target inode
     1274    error = vfs_lookup( old_root_xp,
     1275                        old_path,
     1276                        0,
     1277                        &inode_xp,
     1278                        NULL );
     1279    if( error )
     1280    {
     1281        remote_rwlock_wr_release( lock_xp );
     1282        printk("\n[ERROR] in %s : cannot get target inode for <%s>\n",
     1283        __FUNCTION__, old_path );
     1284        return -1;
     1285    }
     1286
     1287#if( DEBUG_VFS_LINK & 1 )
     1288if( DEBUG_VFS_LINK < cycle )
     1289printk("\n[%s] thread[%x,%x] get child inode (%x,%x) for <%s>\n",
     1290__FUNCTION__, process->pid, this->trdid,
     1291GET_CXY(inode_xp), GET_PTR(inode_xp), old_path, cycle );
     1292#endif
     1293
     1294    // get extended pointer on parent inode in new path
     1295    error = vfs_lookup( new_root_xp,
     1296                        new_path,
     1297                        VFS_LOOKUP_PARENT,
     1298                        &new_parent_xp,
     1299                        new_name );
     1300    if( error )
     1301    {
     1302        remote_rwlock_wr_release( lock_xp );
     1303        printk("\n[ERROR] in %s : cannot get parent inode for <%s>\n",
     1304        __FUNCTION__, new_path );
     1305        return -1;
     1306    }
     1307
     1308#if( DEBUG_VFS_LINK & 1 )
     1309if( DEBUG_VFS_LINK < cycle )
     1310printk("\n[%s] thread[%x,%x] get parent inode (%x,%x) for <%s>\n",
     1311__FUNCTION__, process->pid, this->trdid,
     1312GET_CXY(new_parent_xp), GET_PTR(new_parent_xp), new_path );
     1313#endif
     1314
     1315    // get target inode cluster and local pointer
     1316    inode_cxy = GET_CXY( inode_xp );
     1317    inode_ptr = GET_PTR( inode_xp );
     1318
     1319    // get target inode type, context, and FS type
     1320    inode_type        = hal_remote_l32( XPTR( inode_cxy , &inode_ptr->type ) );
     1321    inode_ctx_ptr     = hal_remote_lpt( XPTR( inode_cxy , &inode_ptr->ctx ) );
     1322    inode_fs_type     = hal_remote_l32( XPTR( inode_cxy , &inode_ctx_ptr->type ) );
     1323
     1324    // get new parent inode cluster an local pointer
     1325    new_parent_ptr = GET_PTR( new_parent_xp );
     1326    new_parent_cxy = GET_CXY( new_parent_xp );
     1327
     1328    ///////////////////////////////////////////////////////////////////////
     1329    if( (inode_type == INODE_TYPE_FILE) || (inode_type == INODE_TYPE_DIR) )
     1330    {
     1331        // 1. create one new dentry
     1332        if( new_parent_cxy == local_cxy ) 
     1333        {
     1334            error = vfs_dentry_create( inode_fs_type,
     1335                                       new_name,
     1336                                       &dentry_xp );
     1337        }
     1338        else
     1339        {
     1340            rpc_vfs_dentry_create_client( new_parent_cxy,
     1341                                          inode_fs_type,
     1342                                          new_name,
     1343                                          &dentry_xp,
     1344                                          &error );
     1345        }
     1346
     1347        if( error )
     1348        {
     1349            remote_rwlock_wr_release( lock_xp );
     1350            printk("\n[ERROR] in %s : cannot create new dentry for <%s>\n",
     1351            __FUNCTION__, new_path );
     1352            return -1;
     1353        }
     1354
     1355        // get local pointer on dentry
     1356        dentry_ptr = GET_PTR( dentry_xp );
     1357
     1358        // 2. register dentry in target inode
     1359        parents_root_xp  = XPTR( inode_cxy      , &inode_ptr->parents );
     1360        parents_entry_xp = XPTR( new_parent_cxy , &dentry_ptr->parents );
     1361        xlist_add_first( parents_root_xp , parents_entry_xp );
     1362        hal_remote_atomic_add( XPTR( inode_cxy , &inode_ptr->links ) , 1 );
     1363
     1364        // 3. register dentry in parent inode
     1365        children_xhtab_xp = XPTR( new_parent_cxy , &new_parent_ptr->children );
     1366        children_entry_xp = XPTR( new_parent_cxy , &dentry_ptr->children );
     1367        xhtab_insert( children_xhtab_xp , new_name , children_entry_xp );
     1368
     1369        // 4. update "parent" and "child_xp" fields in dentry
     1370        hal_remote_s64( XPTR( new_parent_cxy , &dentry_ptr->child_xp ) , inode_xp );
     1371        hal_remote_spt( XPTR( new_parent_cxy , &dentry_ptr->parent ) , new_parent_ptr );
     1372
     1373#if(DEBUG_VFS_LINK & 1)
     1374if( DEBUG_VFS_LINK < cycle )
     1375printk("\n[%s] thread[%x,%x] updated Inode Tree / old <%s> / new <%s>\n",
     1376__FUNCTION__, process->pid, this->trdid, old_path, new_path );
     1377vfs_display( new_parent_xp );
     1378#endif
     1379
     1380        // release the lock protecting Inode Tree
     1381        remote_rwlock_wr_release( lock_xp );
     1382
     1383        // 5. update new parent directory mapper in Inode Tree
     1384        //    and synchronize the parent directory on IOC device
     1385        if (new_parent_cxy == local_cxy)
     1386        {
     1387            error = vfs_fs_add_dentry( new_parent_ptr,
     1388                                       dentry_ptr );
     1389        }
     1390        else
     1391        {
     1392            rpc_vfs_fs_add_dentry_client( new_parent_cxy,
     1393                                          new_parent_ptr,
     1394                                          dentry_ptr,
     1395                                          &error );
     1396        }
     1397        if( error )
     1398        {
     1399            printk("\n[ERROR] in %s : cannot update new parent directory for <%s>\n",
     1400            __FUNCTION__, new_path );
     1401            return -1;
     1402        }
     1403
     1404#if(DEBUG_VFS_LINK & 1)
     1405if( DEBUG_VFS_LINK < cycle )
     1406printk("\n[%s] thread[%x,%x] updated new parent dir (mapper and IOC) / old <%s> / new <%s>\n",
     1407__FUNCTION__, process->pid, this->trdid, old_path, new_path );
     1408#endif
     1409        return 0;
     1410    }
     1411    else
     1412    {
     1413        // release the lock protecting Inode Tree
     1414        remote_rwlock_wr_release( lock_xp );
     1415
     1416        printk("\n[ERROR] in %s : unsupported inode type %s\n",
     1417        __FUNCTION__ , vfs_inode_type_str( inode_type ) );
     1418        return -1;
     1419    }
     1420
     1421}  // end vfs_link()
     1422
     1423/////////////////////////////////////
     1424error_t vfs_unlink( xptr_t   root_xp,
    10471425                    char   * path )
    10481426{
    10491427    error_t           error;
     1428    xptr_t            vfs_root_xp;        // extended pointer on VFS root inode
     1429    vfs_inode_t     * vfs_root_ptr;       // local_pointer on VFS root inode
     1430    cxy_t             vfs_root_cxy;       // VFS root inode cluster identifier
     1431    xptr_t            lock_xp;            // extended pointer on lock protecting Inode Tree
     1432    xptr_t            parent_xp;          // extended pointer on target inode
     1433    cxy_t             parent_cxy;         // target inode cluster identifier       
     1434    vfs_inode_t     * parent_ptr;         // target inode local pointer
    10501435    xptr_t            inode_xp;           // extended pointer on target inode
    10511436    cxy_t             inode_cxy;          // target inode cluster identifier       
    10521437    vfs_inode_t     * inode_ptr;          // target inode local pointer
    1053     uint32_t          inode_refcount;     // target inode refcount
    1054     vfs_inode_type_t  type;               // target inode type
    1055     mapper_t        * mapper;             // pointer on target inode mapper
    1056     xptr_t            dentry_xp;          // extended pointer on target dentry
    1057     cxy_t             dentry_cxy;         // target dentry cluster identifier
    1058     vfs_dentry_t    * dentry_ptr;         // target dentry local pointer
    1059     uint32_t          dentry_refcount;    // target dentry refcount
    1060     vfs_inode_t     * dentry_parent_ptr;  // parent inode local pointer
     1438    uint32_t          inode_links;        // target inode links count
     1439    vfs_inode_type_t  inode_type;         // target inode type
     1440    uint32_t          inode_children;     // target inode number of children
     1441    xptr_t            dentry_xp;          // extended pointer on dentry to unlink
     1442    vfs_dentry_t    * dentry_ptr;         // local pointer on dentry to unlink
     1443
     1444    char              name[CONFIG_VFS_MAX_NAME_LENGTH];  // name of link to remove
     1445
     1446    thread_t  * this    = CURRENT_THREAD;
     1447    process_t * process = this->process;
    10611448
    10621449#if DEBUG_VFS_UNLINK
    1063 thread_t * this  = CURRENT_THREAD;
    10641450uint32_t   cycle = (uint32_t)hal_get_cycles();
     1451char root_name[CONFIG_VFS_MAX_NAME_LENGTH];
     1452vfs_inode_get_name( root_xp , root_name );
    10651453if( DEBUG_VFS_UNLINK < cycle )
    1066 printk("\n[%s] thread[%x,%x] enter for <%s> / cycle %d\n",
    1067 __FUNCTION__, this->process->pid, this->trdid, path, cycle );
    1068 #endif
    1069 
    1070     // get extended pointer on target inode
    1071     error = vfs_lookup( cwd_xp , path , 0 , &inode_xp );
    1072 
    1073     if( error ) return error;
    1074 
    1075     // get inode cluster and local pointer
     1454printk("\n[%s] thread[%x,%x] enter / root <%s> / path <%s> / cycle %d\n",
     1455__FUNCTION__, process->pid, this->trdid, root_name, path, cycle );
     1456#endif
     1457
     1458    // build extended pointer on lock protecting Inode Tree (in VFS root inode)
     1459    vfs_root_xp  = process->vfs_root_xp;
     1460    vfs_root_ptr = GET_PTR( root_xp );
     1461    vfs_root_cxy = GET_CXY( root_xp );
     1462    lock_xp      = XPTR( vfs_root_cxy , &vfs_root_ptr->main_lock );
     1463
     1464    // take the lock protecting Inode Tree
     1465    remote_rwlock_wr_acquire( lock_xp );
     1466
     1467    // get extended pointer on parent inode
     1468    error = vfs_lookup( root_xp,
     1469                        path,
     1470                        VFS_LOOKUP_PARENT,
     1471                        &parent_xp,
     1472                        name );
     1473    if( error )
     1474    {
     1475        remote_rwlock_wr_release( lock_xp );
     1476        printk("\n[ERROR] in %s : cannot get parent inode for <%s> in <%s>\n",
     1477        __FUNCTION__, name, path );
     1478        return -1;
     1479    }
     1480
     1481    // get parent inode cluster and local pointer
     1482    parent_cxy = GET_CXY( parent_xp );
     1483    parent_ptr = GET_PTR( parent_xp );
     1484 
     1485#if( DEBUG_VFS_UNLINK & 1 )
     1486char parent_name[CONFIG_VFS_MAX_NAME_LENGTH];
     1487vfs_inode_get_name( parent_xp , parent_name );
     1488if( DEBUG_VFS_UNLINK < cycle )
     1489printk("\n[%s] thread[%x,%x] parent inode <%s> is (%x,%x)\n",
     1490__FUNCTION__, process->pid, this->trdid, parent_name, parent_cxy, parent_ptr );
     1491#endif
     1492
     1493    // build extended pointer on parent inode "children" xhtab
     1494    xptr_t children_xp = XPTR( parent_cxy , &parent_ptr->children );
     1495
     1496    // get extended pointer on dentry to unlink
     1497    dentry_xp = xhtab_lookup( children_xp , name );
     1498   
     1499    if( dentry_xp == XPTR_NULL )
     1500    {
     1501        remote_rwlock_wr_release( lock_xp );
     1502        printk("\n[ERROR] in %s : cannot get target dentry <%s> in <%s>\n",
     1503        __FUNCTION__, name, path );
     1504        return -1;
     1505    }
     1506   
     1507    // get local pointer on dentry to unlink
     1508    dentry_ptr = GET_PTR( dentry_xp );
     1509
     1510#if( DEBUG_VFS_UNLINK & 1 )
     1511if( DEBUG_VFS_UNLINK < cycle )
     1512printk("\n[%s] thread[%x,%x] dentry <%s> to unlink is (%x,%x)\n",
     1513__FUNCTION__, process->pid, this->trdid, name, parent_cxy, dentry_ptr );
     1514#endif
     1515
     1516    // get pointer on target inode
     1517    inode_xp  = hal_remote_l64( XPTR( parent_cxy , &dentry_ptr->child_xp ) );
    10761518    inode_cxy = GET_CXY( inode_xp );
    10771519    inode_ptr = GET_PTR( inode_xp );
    1078 
    1079     // get inode type, refcount, mapper, dentry_xp
    1080     type              = hal_remote_l32( XPTR( inode_cxy , &inode_ptr->type ) );
    1081     inode_refcount    = hal_remote_l32( XPTR( inode_cxy , &inode_ptr->refcount ) );
    1082     mapper            = hal_remote_lpt( XPTR( inode_cxy , &inode_ptr->mapper ) );
    1083     dentry_xp         = hal_remote_l64( XPTR( inode_cxy , &inode_ptr->parent_xp ) );
    1084 
    1085     // get dentry cluster, local pointer, refcount, and pointers on parent inode
    1086     dentry_ptr        = GET_PTR( dentry_xp );
    1087     dentry_cxy        = GET_CXY( dentry_xp );
    1088     dentry_refcount   = hal_remote_l32( XPTR( dentry_cxy , &dentry_ptr->refcount ) );
    1089     dentry_parent_ptr = hal_remote_lpt( XPTR( dentry_cxy , &dentry_ptr->parent ) );
    1090 
    1091 // check inode & dentry refcount
    1092 assert( (inode_refcount  == 1), "illegal inode refcount for <%s>\n", path );
    1093 assert( (dentry_refcount == 1), "illegal dentry refcount for <%s>\n", path );
    1094 
    1095     /////////////////////////////
    1096     if( type == INODE_TYPE_FILE )
    1097     {
    1098         // 1. release clusters allocated to file in the FAT mapper
    1099         //    synchronize the FAT on IOC device
    1100         error = vfs_fs_release_inode( inode_xp );
    1101         if( error )
     1520 
     1521#if( DEBUG_VFS_UNLINK & 1 )
     1522char inode_name[CONFIG_VFS_MAX_NAME_LENGTH];
     1523vfs_inode_get_name( inode_xp , inode_name );
     1524if( DEBUG_VFS_UNLINK < cycle )
     1525printk("\n[%s] thread[%x,%x] target inode <%s> is (%x,%x) / cycle %d\n",
     1526__FUNCTION__, process->pid, this->trdid, inode_name, inode_cxy, inode_ptr, cycle );
     1527#endif
     1528
     1529    // get target inode "type" and "links"
     1530    inode_type   = hal_remote_l32( XPTR( inode_cxy , &inode_ptr->type ) );
     1531    inode_links  = hal_remote_l32( XPTR( inode_cxy , &inode_ptr->links ) );
     1532
     1533// check target inode links counter
     1534assert( (inode_links >= 1), "illegal inode links count %d for <%s>\n", inode_links, path );
     1535
     1536    ///////////////////////////////////////////////////////////////////////
     1537    if( (inode_type == INODE_TYPE_FILE) || (inode_type == INODE_TYPE_DIR) )
     1538    {
     1539        // 1. Release clusters allocated to target inode
     1540        //    and synchronize the FAT on IOC device if last link.
     1541        if( inode_links == 1 )
    11021542        {
    1103             printk("\n[ERROR] in %s : cannot update FAT mapper <%s>\n", path );
    1104             return -1;
    1105         }
     1543            // build extended pointer on target inode "children" number
     1544            xptr_t inode_children_xp = XPTR( inode_cxy , &inode_ptr->children.items );
     1545
     1546            // get target inode number of children
     1547            inode_children = hal_remote_l32( inode_children_xp );
     1548
     1549            // check no children
     1550            if( inode_children != 0 )
     1551            {
     1552                remote_rwlock_wr_release( lock_xp );
     1553                printk("\n[ERROR] in %s : cannot remove <%s> inode that has children\n",
     1554                __FUNCTION__, path );
     1555                return -1;
     1556            }
     1557
     1558            // release clusters on IOC device
     1559            error = vfs_fs_release_inode( inode_xp );
     1560
     1561            if( error )
     1562            {
     1563                remote_rwlock_wr_release( lock_xp );
     1564                printk("\n[ERROR] in %s : cannot update FAT mapper to remove <%s> inode\n",
     1565                __FUNCTION__ , path );
     1566                return -1;
     1567            }
    11061568
    11071569#if(DEBUG_VFS_UNLINK & 1)
    11081570if( DEBUG_VFS_UNLINK < cycle )
    11091571printk("\n[%s] thread[%x,%x] removed <%s> inode from FAT (mapper and IOC device)\n",
    1110 __FUNCTION__, this->process->pid, this->trdid, path );
    1111 #endif
    1112 
    1113         // 2. update parent directory in Inode Tree
    1114         //    synchronize the parent directory on IOC device
    1115         if (dentry_cxy == local_cxy)                           // dentry is local
     1572__FUNCTION__, process->pid, this->trdid, path );
     1573#endif
     1574        }
     1575
     1576        // 2. update parent directory mapper
     1577        //    and synchronize the parent directory on IOC device
     1578        if (parent_cxy == local_cxy)
    11161579        {
    1117             error = vfs_fs_remove_dentry( dentry_parent_ptr,
     1580            error = vfs_fs_remove_dentry( parent_ptr,
    11181581                                          dentry_ptr );
    11191582        }
    1120         else                                                  // dentry is remote
     1583        else           
    11211584        {
    1122             rpc_vfs_fs_remove_dentry_client( dentry_cxy,
    1123                                              dentry_parent_ptr,
     1585            rpc_vfs_fs_remove_dentry_client( parent_cxy,
     1586                                             parent_ptr,
    11241587                                             dentry_ptr,
    11251588                                             &error );
    11261589        }
     1590
    11271591        if( error )
    11281592        {
    1129             printk("\n[ERROR] in %s : cannot update dentry on device for <%s>\n", path );
     1593            remote_rwlock_wr_release( lock_xp );
     1594            printk("\n[ERROR] in %s : cannot update dentry on device for <%s>\n",
     1595            __FUNCTION__ , path );
    11301596            return -1;
    11311597        }
     
    11341600if( DEBUG_VFS_UNLINK < cycle )
    11351601printk("\n[%s] thread[%x,%x] removed <%s> inode from parent dir (mapper and IOC device)\n",
    1136 __FUNCTION__, this->process->pid, this->trdid, path );
    1137 #endif
    1138         // 3. remove inode (including mapper & dentry) from Inode Tree
    1139         vfs_remove_child_from_parent( inode_xp );
     1602__FUNCTION__, process->pid, this->trdid, path );
     1603#endif
     1604        // 3. remove dentry from Inode Tree (and associated chils inode when last link)
     1605        vfs_remove_child_from_parent( dentry_xp );
     1606
     1607        // release the lock protecting Inode Tree
     1608        remote_rwlock_wr_release( lock_xp );
    11401609
    11411610#if DEBUG_VFS_UNLINK
    11421611if( DEBUG_VFS_UNLINK < cycle )
    11431612printk("\n[%s] thread[%x,%x] exit / removed <%s> inode from Inode Tree / cycle %d\n",
    1144 __FUNCTION__, this->process->pid, this->trdid, path, cycle );
     1613__FUNCTION__, process->pid, this->trdid, path, cycle );
    11451614#endif
    11461615        return 0;
    11471616    }
    1148     /////////////////////////////////
    1149     else if( type == INODE_TYPE_DIR )
    1150     {
    1151         printk("\n[ERROR] in %s : unsupported type %s\n", vfs_inode_type_str( type ) );
     1617    else
     1618    {
     1619        remote_rwlock_wr_release( lock_xp );
     1620        printk("\n[ERROR] in %s : unsupported inode type %s\n",
     1621        __FUNCTION__ , vfs_inode_type_str( inode_type ) );
    11521622        return -1;
    11531623    }
    1154     ////
    1155     else
    1156     {
    1157         printk("\n[ERROR] in %s : unsupported type %s\n", vfs_inode_type_str( type ) );
     1624
     1625}  // end vfs_unlink()
     1626
     1627///////////////////////////////////////////
     1628error_t vfs_stat( xptr_t     root_inode_xp,
     1629                  char     * path,
     1630                  stat_t   * st )
     1631{
     1632    error_t       error;
     1633    xptr_t        inode_xp;           // extended pointer on target inode
     1634    vfs_inode_t * inode_ptr;          // local pointer on target inode
     1635    cxy_t         inode_cxy;          // target inode cluster identifier
     1636    xptr_t        vfs_root_xp;        // extended pointer on VFS root inode
     1637    vfs_inode_t * vfs_root_ptr;       // local_pointer on VFS root inode
     1638    cxy_t         vfs_root_cxy;       // VFS root inode cluster identifier
     1639    xptr_t        lock_xp;            // extended pointer on lock protecting Inode Tree
     1640
     1641    thread_t  * this    = CURRENT_THREAD;
     1642    process_t * process = this->process;
     1643
     1644    // build extended pointer on lock protecting Inode Tree (in VFS root inode)
     1645    vfs_root_xp  = process->vfs_root_xp;
     1646    vfs_root_ptr = GET_PTR( vfs_root_xp );
     1647    vfs_root_cxy = GET_CXY( vfs_root_xp );
     1648    lock_xp      = XPTR( vfs_root_cxy , &vfs_root_ptr->main_lock );
     1649
     1650    // get the lock protecting Inode Tree in read mode
     1651    remote_rwlock_rd_acquire( lock_xp );
     1652
     1653    // get extended pointer on target inode
     1654    error = vfs_lookup( root_inode_xp,
     1655                        path,
     1656                        0,
     1657                        &inode_xp,
     1658                        NULL );
     1659
     1660    // release the lock protecting Inode Tree
     1661    remote_rwlock_rd_release( lock_xp );
     1662
     1663    if( error )
     1664    {
     1665        printk("\n[ERROR] in %s : cannot found inode <%s>\n",
     1666        __FUNCTION__ , path );
    11581667        return -1;
    11591668    }
    11601669
    1161 }  // end vfs_unlink()
    1162 
    1163 //////////////////////////////////////
    1164 error_t vfs_stat( xptr_t     inode_xp,
    1165                   stat_t   * st )
    1166 {
    11671670    // get cluster and local pointer on inode descriptor
    1168     vfs_inode_t * inode_ptr = GET_PTR( inode_xp );
    1169     cxy_t         inode_cxy = GET_CXY( inode_xp );
     1671    inode_ptr = GET_PTR( inode_xp );
     1672    inode_cxy = GET_CXY( inode_xp );
    11701673
    11711674    // get relevant infos from inode descriptor
     
    11861689#if DEBUG_VFS_STAT
    11871690uint32_t cycle  = (uint32_t)hal_get_cycles();
    1188 thread_t * this = CURRENT_THREAD;
    11891691if( DEBUG_VFS_STAT < cycle )
    11901692printk("\n[%s] thread[%x,%x] set stat %x for inode %x in cluster %x / cycle %d\n"
    11911693       " %s / inum %d / size %d\n",
    1192 __FUNCTION__, this->process->pid, this->trdid, st, inode_ptr, inode_cxy, cycle,
     1694__FUNCTION__, process->pid, this->trdid, st, inode_ptr, inode_cxy, cycle,
    11931695vfs_inode_type_str( type ), inum, size );
    11941696#endif
     
    12071709}
    12081710
    1209 //////////////////////////////////////
    1210 error_t vfs_mkdir( xptr_t     file_xp,
    1211                    char     * path,
    1212                    uint32_t   mode )
    1213 {
    1214     assert( false , "not implemented file_xp: %x, path <%s>, mode: %x\n",
    1215       file_xp, path, mode );
    1216     return 0;
    1217 }
    1218 
    12191711////////////////////////////////////
    12201712error_t vfs_rmdir( xptr_t   file_xp,
     
    12261718}
    12271719
    1228 ///////////////////////////////////
    1229 error_t vfs_chdir( xptr_t   cwd_xp,
     1720////////////////////////////////////
     1721error_t vfs_chdir( xptr_t   root_xp,
    12301722                   char   * path )
    12311723{
    12321724    error_t           error;
    1233     xptr_t            inode_xp;     // extended pointer on target inode
    1234     cxy_t             inode_cxy;    // target inode cluster identifier       
    1235     vfs_inode_t     * inode_ptr;    // target inode local pointer
    1236     uint32_t          mode;         // lookup working mode       
    1237     vfs_inode_type_t  inode_type;   // target inode type
    1238 
    1239     // set lookup working mode
    1240     mode = 0;
     1725    xptr_t            inode_xp;           // extended pointer on target inode
     1726    cxy_t             inode_cxy;          // target inode cluster identifier       
     1727    vfs_inode_t     * inode_ptr;          // target inode local pointer
     1728    vfs_inode_type_t  inode_type;         // target inode type
     1729    xptr_t            vfs_root_xp;        // extended pointer on VFS root inode
     1730    vfs_inode_t     * vfs_root_ptr;       // local_pointer on VFS root inode
     1731    cxy_t             vfs_root_cxy;       // VFS root inode cluster identifier
     1732    xptr_t            main_lock_xp;       // extended pointer on lock protecting Inode Tree
     1733    xptr_t            ref_xp;             // extended pointer on reference process
     1734    process_t       * ref_ptr;            // local pointer on reference process
     1735    cxy_t             ref_cxy;            // reference process cluster
     1736    xptr_t            cwd_lock_xp;        // extended pointer on lock protecting CWD change
     1737    xptr_t            cwd_xp_xp;          // extended pointer on cwd_xp in reference process
     1738
     1739    thread_t  * this    = CURRENT_THREAD;
     1740    process_t * process = this->process;
     1741
     1742#if DEBUG_VFS_CHDIR
     1743uint32_t cycle = (uint32_t)hal_get_cycles();
     1744if( DEBUG_VFS_CHDIR < cycle )
     1745printk("\n[%s] thread[%x,%x] enter for path <%s> / cycle %d\n",
     1746__FUNCTION__, process->pid, this->trdid, path, cycle );
     1747#endif
     1748
     1749    // build extended pointer on lock protecting Inode Tree (in VFS root inode)
     1750    vfs_root_xp  = process->vfs_root_xp;
     1751    vfs_root_ptr = GET_PTR( vfs_root_xp );
     1752    vfs_root_cxy = GET_CXY( vfs_root_xp );
     1753    main_lock_xp = XPTR( vfs_root_cxy , &vfs_root_ptr->main_lock );
     1754
     1755    // take lock protecting Inode Tree in read mode
     1756    remote_rwlock_rd_acquire( main_lock_xp );
    12411757
    12421758    // get extended pointer on target inode
    1243     error = vfs_lookup( cwd_xp , path , mode , &inode_xp );
    1244 
    1245     if( error ) return error;
    1246 
    1247     // get inode cluster and local pointer
     1759    error = vfs_lookup( root_xp,
     1760                        path,
     1761                        VFS_LOOKUP_DIR,
     1762                        &inode_xp,
     1763                        NULL );
     1764
     1765    // release lock protecting Inode Tree in read mode
     1766    remote_rwlock_rd_release( main_lock_xp );
     1767
     1768    if( error )
     1769    {
     1770        printk("\n[ERROR] in %s : <%s> not found\n",
     1771        __FUNCTION__, path );
     1772        return -1;
     1773    }
     1774
     1775    // get inode type from remote file
    12481776    inode_cxy = GET_CXY( inode_xp );
    12491777    inode_ptr = GET_PTR( inode_xp );
    1250 
    1251     // get inode type from remote file
    12521778    inode_type = hal_remote_l32( XPTR( inode_cxy , &inode_ptr->type ) );
    12531779
    12541780    if( inode_type != INODE_TYPE_DIR )
    12551781    {
    1256         CURRENT_THREAD->errno = ENOTDIR;
     1782        printk("\n[ERROR] in %s : <%s> is not a directory\n",
     1783        __FUNCTION__, path );
    12571784        return -1;
    12581785    }
    12591786
    1260     // TODO implement this function using process CWD lock
    1261 
    1262 assert( false , "not implemented\n" );
     1787    // build extended pointer on cwd_lock and cwd_xp
     1788    ref_xp       = process->ref_xp;
     1789    ref_ptr      = GET_PTR( ref_xp );
     1790    ref_cxy      = GET_CXY( ref_xp );
     1791    cwd_lock_xp  = XPTR( ref_cxy , &ref_ptr->cwd_lock );
     1792    cwd_xp_xp    = XPTR( ref_cxy , &ref_ptr->cwd_xp );
     1793
     1794    // take lock protecting CWD changes
     1795    remote_busylock_acquire( cwd_lock_xp );
     1796
     1797    // update cwd_xp field in reference process descriptor
     1798    hal_remote_s64( cwd_xp_xp , inode_xp );
     1799
     1800    // release lock protecting CWD changes
     1801    remote_busylock_release( cwd_lock_xp );
     1802
     1803#if DEBUG_VFS_CHDIR
     1804cycle = (uint32_t)hal_get_cycles();
     1805if( DEBUG_VFS_CHDIR < cycle )
     1806printk("\n[%s] thread[%x,%x] exit : inode (%x,%x) / &cwd_xp (%x,%x) / cycle %d\n",
     1807__FUNCTION__, process->pid, this->trdid, inode_cxy, inode_ptr,
     1808GET_CXY(cwd_xp_xp), GET_PTR(cwd_xp_xp), cycle );
     1809#endif
    12631810
    12641811    return 0;
    1265 }
     1812
     1813}  // end vfs_chdir()
    12661814
    12671815///////////////////////////////////
     
    12811829 
    12821830    // get extended pointer on target inode
    1283     error = vfs_lookup( cwd_xp , path , 0 , &inode_xp );
     1831    error = vfs_lookup( cwd_xp,
     1832                        path,
     1833                        0,
     1834                        &inode_xp,
     1835                        NULL );
    12841836
    12851837    if( error ) return error;
     
    12921844    inode_type = hal_remote_l32( XPTR( inode_cxy , &inode_ptr->type ) );
    12931845
    1294    
    1295     assert( false , "not implemented\n" );
     1846    // TODO implement this function
     1847
     1848assert( false , "not implemented\n" );
     1849
    12961850    return 0;
    12971851}
     
    13601914assert( (indent < 16)           , "depth cannot be larger than 15\n" );
    13611915   
    1362     // get inode cluster and local pointer
     1916    // get current inode cluster and local pointer
    13631917    inode_cxy = GET_CXY( inode_xp );
    13641918    inode_ptr = GET_PTR( inode_xp );
     
    14281982    cxy_t          dentry_cxy;
    14291983    vfs_dentry_t * dentry_ptr;
     1984    xptr_t         parents_root_xp;   // root of parent dentries xlist
    14301985
    14311986    // get target inode cluster and local pointer
     
    14331988    vfs_inode_t * inode_ptr = GET_PTR( inode_xp );
    14341989
    1435     // get extended pointer on associated dentry
    1436     dentry_xp   = hal_remote_l64( XPTR( inode_cxy , &inode_ptr->parent_xp ) );
    1437 
    1438     // check if target inode is the File System root
    1439     if( dentry_xp == XPTR_NULL )
     1990    // build extended pointer on parents dentries root
     1991    parents_root_xp = XPTR( inode_cxy , &inode_ptr->parents );
     1992
     1993    // check VFS root     
     1994    if( xlist_is_empty( parents_root_xp ) )  // inode is the VFS root
    14401995    {
    14411996        // build extended pointer on root name
     
    14441999    else
    14452000    {
    1446         // get dentry cluster and local pointer
     2001        // get first parent dentry cluster and pointers
     2002        dentry_xp  = XLIST_FIRST( parents_root_xp , vfs_dentry_t , parents );
    14472003        dentry_cxy = GET_CXY( dentry_xp );
    14482004        dentry_ptr = GET_PTR( dentry_xp );
     
    15202076                             xptr_t * child_xp )
    15212077{
    1522     xptr_t  xhtab_xp;    // extended pointer on hash table containing children dentries
    1523     xptr_t  dentry_xp;   // extended pointer on children dentry
     2078    xptr_t         xhtab_xp;    // extended pointer on hash table for children dentries
     2079    xptr_t         dentry_xp;   // extended pointer on children dentry
     2080    cxy_t          dentry_cxy;
     2081    vfs_dentry_t * dentry_ptr;
    15242082
    15252083    // get parent inode cluster and local pointer
     
    15302088    xhtab_xp = XPTR( parent_cxy , &parent_ptr->children );
    15312089
    1532     // search extended pointer on matching dentry
    1533     dentry_xp = xhtab_lookup( xhtab_xp , name );
    1534 
    1535     if( dentry_xp == XPTR_NULL ) return false;
    1536 
    1537     // get dentry cluster and local pointer
    1538     cxy_t          dentry_cxy = GET_CXY( dentry_xp );
    1539     vfs_dentry_t * dentry_ptr = GET_PTR( dentry_xp );
    1540 
    1541     // return child inode
    1542     *child_xp = (xptr_t)hal_remote_l64( XPTR( dentry_cxy , &dentry_ptr->child_xp ) );
    1543     return true;
     2090    // get pointers on matching dentry
     2091    dentry_xp  = xhtab_lookup( xhtab_xp , name );
     2092    dentry_cxy = GET_CXY( dentry_xp );
     2093    dentry_ptr = GET_PTR( dentry_xp );
     2094
     2095    if( dentry_xp == XPTR_NULL )
     2096    {
     2097        return false;
     2098    }
     2099    else
     2100    {
     2101        *child_xp = (xptr_t)hal_remote_l64( XPTR( dentry_cxy , &dentry_ptr->child_xp ) );
     2102        return true;
     2103    }
    15442104
    15452105}  // end vfs_get_child()
     
    15532113// last name in the path. The names are supposed to be separated by one or several '/'
    15542114// characters, that are not written in  the <name> buffer.
     2115//
     2116// WARNING: the leading characters '/' in the path are skiped before analysis.
     2117//          The path "/" identifies the VFS root, and is therefore anaysed as an empty
     2118//          string. This empty string is dignaled by the (-1) return value. 
    15552119//////////////////////////////////////////////////////////////////////////////////////////
    15562120// @ current   : pointer on first character to analyse in buffer containing the path.
     
    15582122// @ next      : [out] pointer on next character to analyse in buffer containing the path.
    15592123// @ last      : [out] true if the returned name is the last (NUL character found).
    1560 // @ return 0 if success / return EINVAL if string empty (first chracter is NUL).
     2124// @ return 0 if success / return -1 if string empty (first chracter is NUL).
    15612125//////////////////////////////////////////////////////////////////////////////////////////
    15622126static error_t vfs_get_name_from_path( char     * current,
     
    15702134    while( *ptr == '/' ) ptr++;
    15712135
    1572     // return EINVAL if string empty
    1573     if( *ptr == 0 ) return EINVAL;
     2136    // signal empty string
     2137    if( *ptr == 0 )
     2138    {
     2139        *last = true;
     2140        return -1;
     2141    }
    15742142
    15752143    // copy all characters in name until NUL or '/'
     
    15942162}  // end vfs_get name_from_path()
    15952163   
    1596 //////////////////////////////////////////////
    1597 error_t vfs_lookup( xptr_t             cwd_xp,
     2164///////////////////////////////////////////////
     2165error_t vfs_lookup( xptr_t             root_xp,
    15982166                    char             * pathname,
    1599                     uint32_t           mode,
    1600                                         xptr_t           * inode_xp )
     2167                    uint32_t           lookup_mode,
     2168                                        xptr_t           * inode_xp,
     2169                                        char             * last_name )
    16012170{
    16022171    char               name[CONFIG_VFS_MAX_NAME_LENGTH];   // one name in path
     
    16192188    bool_t             create;       // searched inode must be created if not found
    16202189    bool_t             excl;         // searched inode must not exist
     2190    bool_t             par;          // searched inode is the parent
    16212191    thread_t         * this;         // pointer on calling thread descriptor
    16222192    process_t        * process;      // pointer on calling process descriptor
     
    16262196    process = this->process;
    16272197
     2198// check pathname / root_xp consistency
     2199assert( ((pathname[0] != '/') || (root_xp == process->vfs_root_xp)),
     2200"root inode must be VFS root for path <%s>\n", pathname );
     2201
    16282202#if DEBUG_VFS_LOOKUP
    16292203uint32_t cycle = (uint32_t)hal_get_cycles();
     2204char     root_name[CONFIG_VFS_MAX_NAME_LENGTH];
     2205vfs_inode_get_name( root_xp , root_name );
    16302206if( DEBUG_VFS_LOOKUP < cycle )
    1631 printk("\n[%s] thread[%x,%x] enter for <%s> / cycle %d\n",
    1632 __FUNCTION__, process->pid, this->trdid, pathname, cycle );
     2207printk("\n[%s] thread[%x,%x] enter / root <%s> / path <%s> / mode %x / cycle %d\n",
     2208__FUNCTION__, process->pid, this->trdid, root_name, pathname, lookup_mode, cycle );
    16332209#endif
    16342210
    16352211    // compute lookup flags
    1636     dir    = mode & VFS_LOOKUP_DIR;
    1637     create = mode & VFS_LOOKUP_CREATE;
    1638     excl   = mode & VFS_LOOKUP_EXCL;
    1639    
    1640     // get extended pointer on first inode to search
    1641     if( pathname[0] == '/' ) parent_xp = process->vfs_root_xp;
    1642     else                     parent_xp = cwd_xp;
    1643 
    1644     // initialise other loop variables
    1645     current  = pathname;
    1646     next     = NULL;
    1647     last     = false;
    1648     child_xp = XPTR_NULL;
    1649 
    1650     // take lock on parent inode
    1651     vfs_inode_lock( parent_xp );
    1652 
    1653     // sequencially loop on nodes in pathname
    1654     // load from device if one node in path not found in inode tree
     2212    dir    = (lookup_mode & VFS_LOOKUP_DIR)    == VFS_LOOKUP_DIR;
     2213    create = (lookup_mode & VFS_LOOKUP_CREATE) == VFS_LOOKUP_CREATE;
     2214    excl   = (lookup_mode & VFS_LOOKUP_EXCL)   == VFS_LOOKUP_EXCL;
     2215    par    = (lookup_mode & VFS_LOOKUP_PARENT) == VFS_LOOKUP_PARENT;
     2216
     2217    // initialise loop variables
     2218    parent_xp = root_xp;
     2219    current   = pathname;
     2220    next      = NULL;
     2221    last      = false;
     2222    child_xp  = XPTR_NULL;
     2223
     2224    // loop on nodes in pathname
     2225    // load from device if one node in path not found in Inode Tree
    16552226    // exit loop when last name found (i.e. last == true)
    1656     do
    1657     {
    1658         // get one name from path, and "last" flag
    1659         vfs_get_name_from_path( current , name , &next , &last );
     2227    while( 1 )
     2228    {
     2229        // get parent inode cluster and local pointer
     2230        parent_cxy = GET_CXY( parent_xp );
     2231        parent_ptr = GET_PTR( parent_xp );
     2232
     2233        // get one "name" from path, and "last" flag
     2234        error = vfs_get_name_from_path( current , name , &next , &last );
     2235
     2236        // VFS root case
     2237        if ( error )
     2238        {
     2239
     2240#if DEBUG_VFS_LOOKUP
     2241cycle = (uint32_t)hal_get_cycles();
     2242if( DEBUG_VFS_LOOKUP < cycle )
     2243printk("\n[%s] thread[%x,%x] exit / parent inode(%x,%x) / <%s> / cycle %d\n",
     2244__FUNCTION__ , process->pid, this->trdid, parent_cxy, parent_ptr, pathname, cycle );
     2245#endif
     2246            *inode_xp = process->vfs_root_xp;
     2247            break;
     2248        }
    16602249
    16612250#if (DEBUG_VFS_LOOKUP & 1)
     
    16652254#endif
    16662255
    1667         // search a child dentry matching name in parent inode
     2256        // search the child dentry matching name in parent inode
    16682257        found = vfs_get_child( parent_xp,
    16692258                               name,
    16702259                               &child_xp );
    16712260
    1672         if (found == false )  // child not found in inode tree
     2261        // analyse found & last, depending on lookup_mode
     2262        if( found == false )                              // not found in Inode Tree
    16732263        {
     2264            // when a inode is not found in the Inode Tree:
     2265            // - if (last and par) the Inode Tree is not modified
     2266            // - else we speculatively introduce a new (dentry/inode) in inode tree,
     2267            //        and scan the parent directory mapper to initialise it.
     2268            //     . if it is not found in the parent mapper:
     2269            //         - if(last and create), a brand new file or directory is created
     2270            //         - else, an error is reported
     2271            //     . if it is found in parent mapper:
     2272            //         - if( last and excl ), an error is reported
     2273            //         - else the new child (inode & dentry) is initialised in Inode Tree
     2274            //         - if the child is a directory, the child mapper is loaded from device
     2275
     2276            if( last && par )   //  does nothing
     2277            {
    16742278
    16752279#if (DEBUG_VFS_LOOKUP & 1)
    16762280if( DEBUG_VFS_LOOKUP < cycle )
    1677 printk("\n[%s] thread[%x,%x] miss <%s> node => try to create it\n",
     2281printk("\n[%s] thread[%x,%x] child not found but only parent requested in <%s>\n",
     2282__FUNCTION__, process->pid, this->trdid, pathname );
     2283#endif
     2284            }
     2285            else                                    // try to get it from parent mapper
     2286            {
     2287
     2288#if (DEBUG_VFS_LOOKUP & 1)
     2289if( DEBUG_VFS_LOOKUP < cycle )
     2290printk("\n[%s] thread[%x,%x] miss <%s> inode in Inode Tree => build from parent mapper\n",
    16782291__FUNCTION__, process->pid, this->trdid, name );
    16792292#endif
    1680             // if a child node is not found in the inode tree,
    1681             // we introduce a new (dentry/inode) in inode tree,
    1682             // and try to find it by scanning the parent directory mapper.
    1683             // . if it is found in parent mapper:
    1684             //   - if the child is a directory, the child mapper is loaded from device
    1685             //   - if the child is not a directory, the search is completed
    1686             // . if it is not found in the parent mapper:
    1687             //   - if ( not last or not create ) an error is reported
    1688             //   - if (last and create) a new file or directory is created
    1689 
    1690             // release lock on parent inode
    1691             vfs_inode_unlock( parent_xp );
     2293                // get parent inode FS type
     2294                ctx_ptr    = hal_remote_lpt( XPTR( parent_cxy,&parent_ptr->ctx ) );
     2295                fs_type    = hal_remote_l32( XPTR( parent_cxy , &ctx_ptr->type ) );
     2296
     2297                // select a cluster for new inode
     2298                child_cxy = cluster_random_select();
     2299
     2300                // define child inode type
     2301                if( dir ) child_type = INODE_TYPE_DIR;
     2302                else      child_type = INODE_TYPE_FILE;
    16922303 
    1693             // get parent inode cluster and local pointer
    1694             parent_cxy = GET_CXY( parent_xp );
    1695             parent_ptr = GET_PTR( parent_xp );
    1696 
    1697             // get parent inode FS type
    1698             ctx_ptr    = hal_remote_lpt( XPTR( parent_cxy,&parent_ptr->ctx ) );
    1699             fs_type    = hal_remote_l32( XPTR( parent_cxy , &ctx_ptr->type ) );
    1700 
    1701             // select a cluster for missing inode
    1702             child_cxy = cluster_random_select();
    1703 
    1704             // define child inode type
    1705             if( dir ) child_type = INODE_TYPE_DIR;
    1706             else      child_type = INODE_TYPE_FILE;
    1707  
    1708             // insert a new child dentry/inode in inode tree
    1709             error = vfs_add_child_in_parent( child_cxy,
    1710                                              child_type,
    1711                                              fs_type,
    1712                                              parent_xp,
    1713                                              name,
    1714                                              &dentry_xp,
    1715                                              &child_xp );
    1716             if( error )
    1717             {
    1718                 printk("\n[ERROR] in %s : cannot create node <%s> in path <%s>\n",
    1719                 __FUNCTION__ , name, pathname );
    1720                 return -1;
    1721             }
    1722 
    1723             // get child inode local pointer
    1724             child_ptr = GET_PTR( child_xp );
     2304                // insert (speculatively) a new child dentry/inode in inode tree
     2305                error = vfs_add_child_in_parent( child_cxy,
     2306                                                 child_type,
     2307                                                 fs_type,
     2308                                                 parent_xp,
     2309                                                 name,
     2310                                                 &dentry_xp,
     2311                                                 &child_xp );
     2312                if( error )
     2313                {
     2314                    printk("\n[ERROR] in %s : cannot create inode <%s> in path <%s>\n",
     2315                    __FUNCTION__ , name, pathname );
     2316                    return -1;
     2317                }
     2318
     2319                // get child inode local pointer
     2320                child_ptr = GET_PTR( child_xp );
    17252321
    17262322#if (DEBUG_VFS_LOOKUP & 1)
     
    17292325__FUNCTION__, process->pid, this->trdid, name, child_cxy );
    17302326#endif
    1731             // scan parent mapper to find the missing dentry, and complete
    1732             // the initialisation of dentry and child inode desciptors
    1733             if( parent_cxy == local_cxy )
    1734 
    1735             {
    1736                 error = vfs_fs_child_init( parent_ptr,
    1737                                            name,
    1738                                            child_xp );
    1739             }
    1740             else
    1741             {
    1742                 rpc_vfs_fs_child_init_client( parent_cxy,
    1743                                               parent_ptr,
    1744                                               name,
    1745                                               child_xp,
    1746                                               &error );
    1747             }
    1748 
    1749             if ( error )   // child not found in parent mapper
    1750             {
    1751                 if ( last && create )  // add a new dentry in parent
     2327                // scan parent mapper to find the missing dentry, and complete
     2328                // the initialisation of dentry and child inode desciptors
     2329                if( parent_cxy == local_cxy )
     2330
    17522331                {
    1753                     error = vfs_new_child_init( parent_xp,               
    1754                                                 dentry_xp,
    1755                                                 child_xp );
    1756                     if ( error )
     2332                    error = vfs_fs_child_init( parent_ptr,
     2333                                               name,
     2334                                               child_xp );
     2335                }
     2336                else
     2337                {
     2338                    rpc_vfs_fs_child_init_client( parent_cxy,
     2339                                                  parent_ptr,
     2340                                                  name,
     2341                                                  child_xp,
     2342                                                  &error );
     2343                }
     2344
     2345                if ( error )   // child not found in parent mapper
     2346                {
     2347                    if ( last && create )  // add a brand new dentry in parent
    17572348                    {
    1758                         printk("\n[ERROR] in %s : cannot init inode <%s> in path <%s>\n",
    1759                         __FUNCTION__, name, pathname );
    1760                         vfs_remove_child_from_parent( child_xp );
     2349                        error = vfs_new_child_init( parent_xp,               
     2350                                                    dentry_xp,
     2351                                                    child_xp );
     2352                        if ( error )
     2353                        {
     2354                            printk("\n[ERROR] in %s : cannot init inode <%s> in path <%s>\n",
     2355                            __FUNCTION__, name, pathname );
     2356                            vfs_remove_child_from_parent( dentry_xp );
     2357                            return -1;
     2358                        }
     2359
     2360#if (DEBUG_VFS_LOOKUP & 1)
     2361if( DEBUG_VFS_LOOKUP < cycle )
     2362printk("\n[%s] thread[%x,%x] child <%s> not found in parent mapper => create it\n",
     2363__FUNCTION__, process->pid, this->trdid, name );
     2364#endif
     2365                    }
     2366                    else                   // not last or not create => error
     2367                    {                       
     2368                        printk("\n[ERROR] in %s : <%s> node not found in parent for <%s>\n",
     2369                        __FUNCTION__ , name , pathname );
     2370                        vfs_remove_child_from_parent( dentry_xp );
    17612371                        return -1;
    17622372                    }
     2373                }
     2374                else          // child has been found in parent mapper
     2375                {
     2376                    // check the excl
     2377                    if( last && create && excl )
     2378                    {
     2379                        printk("\n[ERROR] in %s : node already exist <%s>\n",
     2380                        __FUNCTION__, name );
     2381                       return -1;
     2382                    }
    17632383
    17642384#if (DEBUG_VFS_LOOKUP & 1)
    17652385if( DEBUG_VFS_LOOKUP < cycle )
    1766 printk("\n[%s] thread[%x,%x] created inode <%s> in path\n",
     2386printk("\n[%s] thread[%x,%x] initialised inode <%s> from parent mapper\n",
    17672387__FUNCTION__, process->pid, this->trdid, name );
    17682388#endif
    1769                 }
    1770                 else                   // not last or not create => error
    1771                 {                       
    1772                      printk("\n[ERROR] in %s : <%s> node not found in parent for <%s>\n",
    1773                      __FUNCTION__ , name , pathname );
    1774                      vfs_remove_child_from_parent( child_xp );
    1775                      return ENOENT;
     2389                    // load child mapper from device if child is a directory (prefetch)
     2390                    uint32_t type = hal_remote_l32( XPTR( child_cxy , &child_ptr->type ) );
     2391                    if( type == INODE_TYPE_DIR )
     2392                    {
     2393                        if( child_cxy == local_cxy )
     2394                        {
     2395                            error = vfs_inode_load_all_pages( child_ptr );
     2396                        }
     2397                        else
     2398                        {
     2399                            rpc_vfs_inode_load_all_pages_client( child_cxy,
     2400                                                                 child_ptr,
     2401                                                                 &error );
     2402                        }
     2403                        if ( error )
     2404                        {
     2405                            printk("\n[ERROR] in %s : cannot load <%s> from device\n",
     2406                            __FUNCTION__ , name );
     2407                            vfs_remove_child_from_parent( dentry_xp );
     2408                            return -1;
     2409                        }
     2410
     2411#if (DEBUG_VFS_LOOKUP & 1)
     2412if( DEBUG_VFS_LOOKUP < cycle )
     2413printk("\n[%s] thread[%x,%x] loaded directory mapper for <%s> from IOC\n",
     2414__FUNCTION__ , process->pid, this->trdid, name );
     2415#endif
     2416                    }
    17762417                }
    17772418            }
    1778             else          // child found in parent mapper
    1779             {
    1780                 // load child mapper from device if child is a directory (prefetch)
    1781                 if( hal_remote_l32( XPTR( child_cxy , &child_ptr->type ) ) == INODE_TYPE_DIR )
    1782                 {
    1783                     if( child_cxy == local_cxy )
    1784                     {
    1785                         error = vfs_inode_load_all_pages( child_ptr );
    1786                     }
    1787                     else
    1788                     {
    1789                         rpc_vfs_inode_load_all_pages_client( child_cxy,
    1790                                                              child_ptr,
    1791                                                              &error );
    1792                     }
    1793                     if ( error )
    1794                     {
    1795                         printk("\n[ERROR] in %s : cannot load <%s> from device\n",
    1796                         __FUNCTION__ , name );
    1797                         vfs_remove_child_from_parent( child_xp );
    1798                         return EIO;
    1799                     }
    1800 
    1801 #if (DEBUG_VFS_LOOKUP & 1)
    1802 if( DEBUG_VFS_LOOKUP < cycle )
    1803 printk("\n[%s] thread[%x,%x] loaded from IOC device mapper for <%s> in <%s>\n",
    1804 __FUNCTION__ , process->pid, this->trdid, name, pathname );
    1805 #endif
    1806                 }
    1807             }
    1808 
    1809             // take lock on parent inode
    1810             vfs_inode_lock( parent_xp );
    18112419        }
    1812         else   // child found in inode tree
     2420        else                                    // child directly found in inode tree
    18132421        {
    18142422       
    18152423#if (DEBUG_VFS_LOOKUP & 1)
    18162424if( DEBUG_VFS_LOOKUP < cycle )
    1817 printk("\n[%s] thread[%x,%x] found <%s> / inode %x in cluster %x\n",
    1818 __FUNCTION__, process->pid, this->trdid, name, GET_PTR(child_xp), GET_CXY(child_xp) );
    1819 #endif
     2425printk("\n[%s] thread[%x,%x] found <%s> in Inode Tree / inode (%x,%x)\n",
     2426__FUNCTION__, process->pid, this->trdid, name, GET_CXY(child_xp), GET_PTR(child_xp) );
     2427#endif
     2428            // get child inode local pointer and cluster
    18202429            child_ptr  = GET_PTR( child_xp );
    18212430            child_cxy  = GET_CXY( child_xp );
    1822             parent_cxy = GET_CXY( parent_xp );
    1823             parent_ptr = GET_PTR( parent_xp );
    1824 
    1825             if( last && (mode & VFS_LOOKUP_CREATE) && (mode & VFS_LOOKUP_EXCL) )
     2431
     2432            // check the excl flag
     2433            if( last && create && excl )
    18262434            {
    1827                 printk("\n[ERROR] in %s : node already exist <%s>\n", __FUNCTION__, name );
    1828                 return EINVAL;
     2435                printk("\n[ERROR] in %s : node <%s> already exist\n",
     2436                __FUNCTION__, name );
     2437                return -1;
    18292438            }
    18302439        }
     
    18422451
    18432452        // take lock on child inode and release lock on parent
    1844         vfs_inode_lock( child_xp );
    1845         vfs_inode_unlock( parent_xp );
    1846 
    1847         // update loop variables
    1848         parent_xp = child_xp;
    1849         current   = next;
    1850     }
    1851     while( last == false );
    1852 
    1853     // release lock
    1854     vfs_inode_unlock( parent_xp );
     2453        // vfs_inode_lock( child_xp );
     2454        // vfs_inode_unlock( parent_xp );
     2455
     2456        // exit when last
     2457        if ( last )           // last inode in path  => return relevant info
     2458        {
     2459            if ( par )  // return parent inode and child name
     2460            {
    18552461
    18562462#if DEBUG_VFS_LOOKUP
    18572463cycle = (uint32_t)hal_get_cycles();
    18582464if( DEBUG_VFS_LOOKUP < cycle )
    1859 printk("\n[%s] thread[%x,%x] exit for <%s> cycle %d\n",
    1860 __FUNCTION__ , process->pid, this->trdid, pathname, cycle );
    1861 #endif
    1862 
    1863     // return searched pointer
    1864     if( mode & VFS_LOOKUP_PARENT ) *inode_xp = parent_xp;
    1865     else                           *inode_xp = child_xp;
     2465printk("\n[%s] thread[%x,%x] exit / parent inode(%x,%x) / <%s> / cycle %d\n",
     2466__FUNCTION__ , process->pid, this->trdid, parent_cxy, parent_ptr, pathname, cycle );
     2467#endif
     2468                *inode_xp = parent_xp;
     2469                strcpy( last_name , name );
     2470                break;
     2471            }
     2472            else        // return child inode name     
     2473            {
     2474
     2475#if DEBUG_VFS_LOOKUP
     2476cycle = (uint32_t)hal_get_cycles();
     2477if( DEBUG_VFS_LOOKUP < cycle )
     2478printk("\n[%s] thread[%x,%x] exit / child inode (%x,%x) / <%s> / cycle %d\n",
     2479__FUNCTION__ , process->pid, this->trdid, child_cxy, child_ptr, pathname, cycle );
     2480#endif
     2481                *inode_xp = child_xp;
     2482                break;
     2483            }
     2484        }
     2485        else                     // not the last inode in path => update loop variables
     2486        {
     2487            parent_xp = child_xp;
     2488            current   = next;
     2489        }
     2490    }
    18662491
    18672492    return 0;
    18682493
    18692494}  // end vfs_lookup()
    1870 
    1871 
    18722495
    18732496///////////////////////////////////////////////
     
    19542577cycle = (uint32_t)hal_get_cycles();
    19552578if( DEBUG_VFS_NEW_CHILD_INIT < cycle )
    1956 printk("\n[%s] thread[%x,%x] exit / parent <%s> / child <%> / cycle %d\n",
     2579printk("\n[%s] thread[%x,%x] exit / parent <%s> / child <%s> / cycle %d\n",
    19572580__FUNCTION__ , this->process->pid, this->trdid, parent_name, child_name, cycle );
    19582581#endif
     
    19622585}  // end vfs_new_child_init()
    19632586
    1964 ////////////////////////////////////////////
    1965 error_t vfs_get_path( xptr_t    searched_xp,
    1966                       char    * buffer,
    1967                       uint32_t  max_size )
    1968 {
    1969         xptr_t       dentry_xp;   // extended pointer on current dentry
    1970     char       * name;        // local pointer on current dentry name
    1971         uint32_t     length;      // length of current dentry name
    1972         uint32_t     count;       // number of characters written in buffer
    1973         uint32_t     index;       // slot index in buffer
    1974     xptr_t       inode_xp;    // extended pointer on   
    1975 
    1976     // implementation note:
    1977     // we use two variables "index" and "count" because the buffer
    1978     // is written in decreasing index order (from leaf to root)
    1979     // TODO  : handle conflict with a concurrent rename [AG]
    1980     // FIXME : handle synchro in the loop  [AG]
    1981 
    1982         // set the NUL character in buffer / initialise buffer index and count
     2587//////////////////////////////////////////
     2588error_t vfs_get_path( xptr_t     inode_xp,
     2589                      char     * buffer,
     2590                      char    ** first,
     2591                      uint32_t   max_size )
     2592{
     2593        xptr_t         dentry_xp;        // extended pointer on current dentry
     2594    vfs_dentry_t * dentry_ptr;       // local pointer on current dentry
     2595    cxy_t          dentry_cxy;       // current dentry cluster identifier
     2596    xptr_t         name_xp;          // extended pointer on current dentry name
     2597        uint32_t       length;           // length of current dentry name
     2598        int32_t        index;            // slot index in buffer
     2599    xptr_t         current_xp;       // extended pointer on current inode
     2600    vfs_inode_t  * current_ptr;      // local pointer on current inode
     2601    cxy_t          current_cxy;      // current inode cluster identifier
     2602    xptr_t         vfs_root_xp;      // extended pointer on VFS root inode
     2603    vfs_inode_t  * vfs_root_ptr;     // local pointer on VFS root inode
     2604    cxy_t          vfs_root_cxy;     // VFS root inode cluster identifier
     2605    xptr_t         lock_xp;          // extended pointer on Inode Tree lock
     2606    xptr_t         parents_root_xp;  // extended pointer on current inode parents root
     2607    bool_t         found;            // condition to exit the while loop
     2608
     2609    thread_t  * this    = CURRENT_THREAD;
     2610    process_t * process = this->process;
     2611
     2612#if DEBUG_VFS_GET_PATH
     2613uint32_t cycle = (uint32_t)hal_get_cycles();
     2614if( DEBUG_VFS_GET_PATH < cycle )
     2615printk("\n[%s] thread[%x,%x] enter : inode (%x,%x) / cycle %d\n",
     2616__FUNCTION__ , process->pid, this->trdid,
     2617GET_CXY( inode_xp ), GET_PTR( inode_xp ), cycle );
     2618#endif
     2619
     2620        // set the NUL character in buffer / initialise buffer index
    19832621        buffer[max_size - 1] = 0;
    1984         count    = 1;
    1985     index    = max_size - 2;
     2622    index    = (int32_t)(max_size - 1);
    19862623
    19872624    // initialize current inode
    1988     inode_xp  = searched_xp;
    1989 
    1990     // exit when root inode found (i.e. dentry_xp == XPTR_NULL)
     2625    current_xp  = inode_xp;
     2626
     2627    // build extended pointer on lock protecting Inode Tree
     2628    vfs_root_xp  = process->vfs_root_xp;
     2629    vfs_root_ptr = GET_PTR( vfs_root_xp );
     2630    vfs_root_cxy = GET_CXY( vfs_root_xp );
     2631    lock_xp      = XPTR( vfs_root_cxy , &vfs_root_ptr->main_lock );
     2632
     2633    // take lock protecting Inode Tree in read mode
     2634    remote_rwlock_rd_acquire( lock_xp );
     2635
     2636    // traverse Inode Tree from target inode to VFS root
     2637    // selecting always the first parent dentry
     2638    // the buffer is written in "reverse order" (from target inode to root)
     2639    // exit the while loop when the VFS root has been found
    19912640        do
    19922641    {
    1993         // get inode cluster and local pointer
    1994         cxy_t         inode_cxy = GET_CXY( inode_xp );
    1995         vfs_inode_t * inode_ptr = GET_PTR( inode_xp );
    1996 
    1997         // get extended pointer on parent dentry               
    1998         dentry_xp = (xptr_t)hal_remote_l64( XPTR( inode_cxy , inode_ptr->parent_xp ) );
    1999 
    2000         // get dentry cluster and local pointer
    2001         cxy_t          dentry_cxy = GET_CXY( dentry_xp );
    2002         vfs_dentry_t * dentry_ptr = GET_PTR( dentry_xp );
    2003 
    2004         // get dentry name length and pointer
    2005         length =  hal_remote_l32( XPTR( dentry_cxy , &dentry_ptr->length ) );
    2006         name   = (char *)hal_remote_lpt( XPTR( dentry_cxy , &dentry_ptr->name ) );
    2007 
    2008         // update index and count
    2009         index -= (length + 1);
    2010         count += (length + 1);
    2011 
    2012         // check buffer overflow
    2013         if( count >= max_size )
     2642        // get current inode cluster and local pointer
     2643        current_cxy = GET_CXY( current_xp );
     2644        current_ptr = GET_PTR( current_xp );
     2645
     2646        // build extended pointer on parents dentries root
     2647        parents_root_xp = XPTR( current_cxy , &current_ptr->parents );
     2648
     2649        // compute exit condition <=> current inode is VFS root   
     2650        found = xlist_is_empty( parents_root_xp );
     2651
     2652        if( found )                              // parent is the VFS root
    20142653        {
    2015             printk("\n[ERROR] in %s : kernel buffer too small\n", __FUNCTION__ );
    2016             return EINVAL;
     2654            if( index == (int32_t)(max_size - 1) )
     2655            {
     2656                // update index
     2657                index--;
     2658                 
     2659                // set separator 
     2660                        buffer[index] = '/';
     2661
     2662// check buffer overflow
     2663assert( (index >= 0) , "kernel buffer too small\n" );
     2664
     2665            }
    20172666        }
    2018 
    2019         // update pathname
    2020         hal_remote_memcpy( XPTR( local_cxy , &buffer[index + 1] ) ,
    2021                            XPTR( dentry_cxy , name ) , length );
    2022                 buffer[index] = '/';
    2023 
    2024                 // get extended pointer on next inode
    2025         inode_xp = (xptr_t)hal_remote_l64( XPTR( dentry_cxy , dentry_ptr->parent ) );
    2026     }
    2027     while( (dentry_xp != XPTR_NULL) );
    2028 
     2667        else                                     // not the VFS root
     2668        {
     2669            // get first parent dentry cluster and pointers
     2670            dentry_xp  = XLIST_FIRST( parents_root_xp , vfs_dentry_t , parents );
     2671            dentry_cxy = GET_CXY( dentry_xp );
     2672            dentry_ptr = GET_PTR( dentry_xp );
     2673
     2674            // get extended pointer on dentry name and name length
     2675            name_xp = XPTR( dentry_cxy , dentry_ptr->name );
     2676            length  = hal_remote_l32( XPTR( dentry_cxy , &dentry_ptr->length ) );
     2677
     2678#if (DEBUG_VFS_GET_PATH & 1)
     2679char debug_name[CONFIG_VFS_MAX_NAME_LENGTH];
     2680hal_remote_strcpy( XPTR( local_cxy , debug_name ) , name_xp );
     2681if( DEBUG_VFS_GET_PATH < cycle )
     2682printk("\n[%s] thread(%x,%s) get current dentry <%s> in cluster %x\n",
     2683__FUNCTION__ , process->pid, this->trdid, debug_name, current_cxy );
     2684#endif
     2685            // update index
     2686            index -= (length + 1);
     2687
     2688// check buffer overflow
     2689assert( (index >= 0) , "kernel buffer too small\n" );
     2690
     2691            // update pathname
     2692            hal_remote_memcpy( XPTR( local_cxy , &buffer[index + 1] ) ,
     2693                               name_xp , length );
     2694
     2695            // set separator 
     2696                    buffer[index] = '/';
     2697
     2698            // get extended pointer on parent inode
     2699            current_xp = XPTR( dentry_cxy ,
     2700                               hal_remote_lpt( XPTR( dentry_cxy , &dentry_ptr->parent ) ) );
     2701        }
     2702    }
     2703    while( found == false );
     2704
     2705    // release lock protecting Inode Tree in read mode
     2706    remote_rwlock_rd_release( lock_xp );
     2707
     2708#if DEBUG_VFS_GET_PATH
     2709cycle = (uint32_t)hal_get_cycles();
     2710if( DEBUG_VFS_GET_PATH < cycle )
     2711printk("\n[%s] thread[%x,%x] exit : path <%s> / cycle %d\n",
     2712__FUNCTION__ , process->pid, this->trdid, &buffer[index], cycle );
     2713#endif
     2714
     2715    // return pointer on first character in buffer
     2716    *first = &buffer[index];
    20292717        return 0;
    20302718
     
    20332721     
    20342722////////////////////////////////////////////////////////////////////
    2035 error_t vfs_add_child_in_parent( cxy_t              child_inode_cxy,
    2036                                  vfs_inode_type_t   child_inode_type,
     2723error_t vfs_add_child_in_parent( cxy_t              child_cxy,
     2724                                 vfs_inode_type_t   child_type,
    20372725                                 vfs_fs_type_t      fs_type,
    20382726                                 xptr_t             parent_inode_xp,
    20392727                                 char             * name,
    2040                                  xptr_t           * dentry_xp,
     2728                                 xptr_t           * child_dentry_xp,
    20412729                                 xptr_t           * child_inode_xp )
    20422730{
    2043     error_t         error;
    2044     xptr_t          new_dentry_xp;       // extended pointer on created dentry
    2045     vfs_dentry_t  * new_dentry_ptr;      // created dentry local pointer
    2046     xptr_t          new_inode_xp;        // extended pointer on created child inode
    2047     cxy_t           parent_inode_cxy;    // parent inode cluster identifier
    2048     vfs_inode_t   * parent_inode_ptr;    // parent inode local pointer
    2049 
    2050     // get parent inode cluster and local pointer
    2051     parent_inode_cxy = GET_CXY( parent_inode_xp );
     2731    error_t        error;
     2732    cxy_t          parent_cxy;          // parent inode cluster identifier
     2733    vfs_inode_t  * parent_inode_ptr;    // parent inode local pointer
     2734    xptr_t         new_dentry_xp;       // extended pointer on created dentry
     2735    vfs_dentry_t * new_dentry_ptr;      // created dentry local pointer
     2736    xptr_t         new_inode_xp;        // extended pointer on created child inode
     2737    vfs_inode_t  * new_inode_ptr;       // local pointer on created child inode
     2738
     2739    xptr_t         parents_root_xp;     // extended pointer on child inode  "parents" field
     2740    xptr_t         parents_entry_xp;    // extended pointer on child dentry "parents" field
     2741    xptr_t         children_xhtab_xp;   // extended pointer on parent inode "children" field
     2742    xptr_t         children_entry_xp;   // extended pointer on child dentry "children" field
     2743   
     2744    // get parent inode cluster and pointer
     2745    parent_cxy       = GET_CXY( parent_inode_xp );
    20522746    parent_inode_ptr = GET_PTR( parent_inode_xp );
    20532747
     
    20582752thread_t * this = CURRENT_THREAD;
    20592753if( DEBUG_VFS_ADD_CHILD < cycle )
    2060 printk("\n[%s] thread[%x,%x] enter / child <%s> cxy %x / parent <%s> cxy %x / cycle %d\n",
    2061 __FUNCTION__, this->process->pid, this->trdid, name, child_inode_cxy,
    2062 parent_name, parent_inode_cxy, (uint32_t)hal_get_cycles() );
    2063 #endif
    2064 
    2065     // 1. create dentry
    2066     if( parent_inode_cxy == local_cxy )      // parent cluster is the local cluster
     2754printk("\n[%s] thread[%x,%x] enter / child <%s> / parent <%s> / cycle %d\n",
     2755__FUNCTION__, this->process->pid, this->trdid, name,
     2756parent_name, (uint32_t)hal_get_cycles() );
     2757#endif
     2758
     2759    // 1. create dentry in parent cluster
     2760    if( parent_cxy == local_cxy )           // parent cluster is local
    20672761    {
    20682762        error = vfs_dentry_create( fs_type,
    20692763                                   name,
    2070                                    parent_inode_ptr,
    20712764                                   &new_dentry_xp );
    20722765    }
    2073     else                               // parent cluster is remote
    2074     {
    2075         rpc_vfs_dentry_create_client( parent_inode_cxy,
     2766    else                                    // parent cluster is remote
     2767    {
     2768        rpc_vfs_dentry_create_client( parent_cxy,
    20762769                                      fs_type,
    20772770                                      name,
    2078                                       parent_inode_ptr,
    20792771                                      &new_dentry_xp,
    20802772                                      &error );
     
    20842776    {
    20852777        printk("\n[ERROR] in %s : cannot create dentry <%s> in cluster %x\n",
    2086         __FUNCTION__ , name , parent_inode_cxy );
     2778        __FUNCTION__ , name , parent_cxy );
    20872779        return -1;
    20882780    }
     
    20932785#if(DEBUG_VFS_ADD_CHILD & 1)
    20942786if( DEBUG_VFS_ADD_CHILD < cycle )
    2095 printk("\n[%s] thread[%x,%x] / dentry <%s> created in cluster %x\n",
    2096 __FUNCTION__, this->process->pid, this->trdid, name, parent_inode_cxy );
    2097 #endif
    2098 
    2099     // 2. create child inode TODO : define attr / mode / uid / gid
     2787printk("\n[%s] thread[%x,%x] / dentry <%s> created (%x,%x)\n",
     2788__FUNCTION__, this->process->pid, this->trdid, name, parent_cxy, new_dentry_ptr );
     2789#endif
     2790
     2791    // 2. create child inode in child cluster
     2792    // TODO : define attr / mode / uid / gid
    21002793    uint32_t attr = 0;
    21012794    uint32_t mode = 0;
     
    21032796    uint32_t gid  = 0;
    21042797   
    2105     if( child_inode_cxy == local_cxy )      // child cluster is the local cluster
    2106     {
    2107         error = vfs_inode_create( new_dentry_xp,
    2108                                   fs_type,
    2109                                   child_inode_type,
     2798    if( child_cxy == local_cxy )      // child cluster is local
     2799    {
     2800        error = vfs_inode_create( fs_type,
     2801                                  child_type,
    21102802                                  attr,
    21112803                                  mode,
     
    21162808    else                              // child cluster is remote
    21172809    {
    2118         rpc_vfs_inode_create_client( child_inode_cxy,
    2119                                      new_dentry_xp,
     2810        rpc_vfs_inode_create_client( child_cxy,
    21202811                                     fs_type,
    2121                                      child_inode_type,
     2812                                     child_type,
    21222813                                     attr,
    21232814                                     mode,
     
    21312822    {
    21322823        printk("\n[ERROR] in %s : cannot create inode in cluster %x\n",
    2133                __FUNCTION__ , child_inode_cxy );
     2824               __FUNCTION__ , child_cxy );
    21342825 
    2135         if( parent_inode_cxy == local_cxy ) vfs_dentry_destroy( new_dentry_ptr );
    2136         else rpc_vfs_dentry_destroy_client( parent_inode_cxy , new_dentry_ptr );
     2826        if( parent_cxy == local_cxy ) vfs_dentry_destroy( new_dentry_ptr );
     2827        else rpc_vfs_dentry_destroy_client( parent_cxy , new_dentry_ptr );
    21372828        return -1;
    21382829    }
    21392830
     2831    // get new inode local pointer
     2832    new_inode_ptr = GET_PTR( new_inode_xp );
     2833   
    21402834#if(DEBUG_VFS_ADD_CHILD & 1)
    21412835if( DEBUG_VFS_ADD_CHILD < cycle )
    2142 printk("\n[%s] thread[%x,%x] / inode <%s> created in cluster %x\n",
    2143 __FUNCTION__ , this->process->pid, this->trdid, name , child_inode_cxy );
    2144 #endif
    2145 
    2146     // 3. update "child_xp" field in dentry and increment refcounts
    2147     hal_remote_s64( XPTR( parent_inode_cxy , &new_dentry_ptr->child_xp ) , new_inode_xp );
    2148     vfs_inode_remote_up( new_inode_xp );
    2149     vfs_dentry_remote_up( new_dentry_xp );
     2836printk("\n[%s] thread[%x,%x] / inode <%s> created (%x,%x)\n",
     2837__FUNCTION__ , this->process->pid, this->trdid, name , child_cxy, new_inode_ptr );
     2838#endif
     2839
     2840    // 3. register new_dentry in new_inode xlist of parents
     2841    parents_root_xp  = XPTR( child_cxy , &new_inode_ptr->parents );
     2842    parents_entry_xp = XPTR( parent_cxy, &new_dentry_ptr->parents );
     2843    xlist_add_first( parents_root_xp , parents_entry_xp );
     2844    hal_remote_atomic_add( XPTR( child_cxy , &new_inode_ptr->links ) , 1 );
     2845
     2846#if(DEBUG_VFS_ADD_CHILD & 1)
     2847if( local_cxy == 1 )
     2848// if( DEBUG_VFS_ADD_CHILD < cycle )
     2849printk("\n[%s] thread[%x,%x] / dentry (%x,%x) registered in child inode (%x,%x)\n",
     2850__FUNCTION__, this->process->pid, this->trdid,
     2851parent_cxy, new_dentry_ptr, child_cxy, new_inode_ptr );
     2852#endif
     2853
     2854    // 4. register new_dentry in parent_inode xhtab of children
     2855    children_xhtab_xp = XPTR( parent_cxy , &parent_inode_ptr->children );
     2856    children_entry_xp = XPTR( parent_cxy , &new_dentry_ptr->children );
     2857    xhtab_insert( children_xhtab_xp , name , children_entry_xp );
     2858
     2859#if(DEBUG_VFS_ADD_CHILD & 1)
     2860if( DEBUG_VFS_ADD_CHILD < cycle )
     2861printk("\n[%s] thread[%x,%x] / dentry (%x,%x) registered in parent inode (%x,%x)\n",
     2862__FUNCTION__, this->process->pid, this->trdid,
     2863parent_cxy, new_dentry_ptr, parent_cxy, parent_inode_ptr );
     2864#endif
     2865
     2866    // 5. update "parent" and "child_xp" fields in new_dentry
     2867    hal_remote_s64( XPTR( parent_cxy , &new_dentry_ptr->child_xp ) , new_inode_xp );
     2868    hal_remote_spt( XPTR( parent_cxy , &new_dentry_ptr->parent ) , parent_inode_ptr );
    21502869
    21512870#if DEBUG_VFS_ADD_CHILD
     
    21572876
    21582877    // return extended pointer on dentry & child inode
    2159     *dentry_xp      = new_dentry_xp;
    2160     *child_inode_xp = new_inode_xp;
     2878    *child_dentry_xp = new_dentry_xp;
     2879    *child_inode_xp  = new_inode_xp;
    21612880    return 0;
    21622881
    21632882}  // end vfs_add_child_in_parent()
    21642883
    2165 ////////////////////////////////////////////////////
    2166 void vfs_remove_child_from_parent( xptr_t inode_xp )
    2167 {
    2168     cxy_t          inode_cxy;
    2169     vfs_inode_t  * inode_ptr;
    2170     xptr_t         dentry_xp;
    2171     cxy_t          dentry_cxy;
    2172     vfs_dentry_t * dentry_ptr;
     2884/////////////////////////////////////////////////////
     2885void vfs_remove_child_from_parent( xptr_t dentry_xp )
     2886{
     2887    cxy_t          parent_cxy;         // parent inode cluster identifier
     2888    cxy_t          child_cxy;          // child inode cluster identifier
     2889    vfs_dentry_t * dentry_ptr;         // local pointer on dentry
     2890    xptr_t         child_inode_xp;     // extended pointer on child inode
     2891    vfs_inode_t  * child_inode_ptr;    // local pointer on child inode
     2892    vfs_inode_t  * parent_inode_ptr;   // local pointer on parent inode
     2893    uint32_t       links;              // number of child inode parents
     2894
     2895    char dentry_name[CONFIG_VFS_MAX_NAME_LENGTH];
    21732896   
    2174     // get inode cluster and local pointer
    2175     inode_cxy = GET_CXY( inode_xp );
    2176     inode_ptr = GET_PTR( inode_xp );
    2177 
    2178     // get associated dentry cluster and pointers
    2179     dentry_xp  = hal_remote_l64( XPTR( inode_cxy , &inode_ptr->parent_xp ) );
    2180     dentry_cxy = GET_CXY( dentry_xp );
     2897    // get parent cluster and dentry local pointer
     2898    parent_cxy = GET_CXY( dentry_xp );
    21812899    dentry_ptr = GET_PTR( dentry_xp );
    21822900
    2183 // check dentry refcount
    2184 assert( ( hal_remote_l32( XPTR( dentry_cxy , &dentry_ptr->refcount ) ) == 1 ),
    2185 "dentry refcount must be 1\n" );
    2186 
    2187 // check inode refcount
    2188 assert( ( hal_remote_l32( XPTR( inode_cxy , &inode_ptr->refcount ) ) == 1 ),
    2189 "inode refcount must be 1\n" );
    2190 
    2191     // decrement refcount for inode and dentry
    2192     vfs_inode_remote_down( inode_xp );
    2193     vfs_dentry_remote_down( dentry_xp );
    2194 
    2195     // delete dentry
    2196     if( dentry_cxy == local_cxy )
     2901    // get a local copy of dentry name
     2902    hal_remote_strcpy( XPTR( local_cxy  , dentry_name ),
     2903                       XPTR( parent_cxy , &dentry_ptr->name ) );
     2904
     2905    // get parent_inode local pointer
     2906    parent_inode_ptr = hal_remote_lpt( XPTR( parent_cxy , &dentry_ptr->parent ) );
     2907 
     2908    // get child cluster and child_inode pointers
     2909    child_inode_xp   = hal_remote_l64( XPTR( parent_cxy , &dentry_ptr->child_xp ) );
     2910    child_cxy        = GET_CXY( child_inode_xp );
     2911    child_inode_ptr  = GET_PTR( child_inode_xp );
     2912
     2913    // remove dentry from parent_inode
     2914    xhtab_remove( XPTR( parent_cxy , &parent_inode_ptr->children ),
     2915                  dentry_name,
     2916                  XPTR( parent_cxy , &dentry_ptr->children ) );
     2917
     2918    // remove dentry from child_inode
     2919    xlist_unlink( XPTR( parent_cxy , &dentry_ptr->parents ) );
     2920    links = hal_remote_atomic_add( XPTR( child_cxy , &child_inode_ptr->links ) , -1 );
     2921
     2922    // delete dentry descriptor
     2923    if( parent_cxy == local_cxy )
    21972924    {
    21982925         vfs_dentry_destroy( dentry_ptr );
     
    22002927    else
    22012928    {
    2202          rpc_vfs_dentry_destroy_client( dentry_cxy,
     2929         rpc_vfs_dentry_destroy_client( parent_cxy,
    22032930                                        dentry_ptr );
    22042931    }
    22052932
    2206     // delete inode
    2207     if( inode_cxy == local_cxy )
    2208     {
    2209          vfs_inode_destroy( inode_ptr );
    2210     }
    2211     else
    2212     {
    2213          rpc_vfs_inode_destroy_client( inode_cxy,
    2214                                        inode_ptr );
     2933    // delete child_inode descriptor if last link
     2934    if( links == 1 )
     2935    {
     2936        if( child_cxy == local_cxy )
     2937        {
     2938            vfs_inode_destroy( child_inode_ptr );
     2939        }
     2940        else
     2941        {
     2942            rpc_vfs_inode_destroy_client( child_cxy , child_inode_ptr );
     2943        }
    22152944    }
    22162945
     
    23743103} // end vfs_fs_child_init()
    23753104
     3105////////////////////////////////////////////////
     3106error_t vfs_fs_sync_inode( vfs_inode_t * inode )
     3107{
     3108    error_t error = 0;
     3109
     3110// check arguments
     3111assert( (inode != NULL) , "inode pointer is NULL\n");
     3112
     3113    // get inode FS type
     3114    vfs_fs_type_t fs_type = inode->ctx->type;
     3115
     3116    // call relevant FS function
     3117    if( fs_type == FS_TYPE_FATFS )
     3118    {
     3119        error = fatfs_sync_inode( inode );
     3120    }
     3121    else if( fs_type == FS_TYPE_RAMFS )
     3122    {
     3123        assert( false , "should not be called for RAMFS\n" );
     3124    }
     3125    else if( fs_type == FS_TYPE_DEVFS )
     3126    {
     3127        assert( false , "should not be called for DEVFS\n" );
     3128    }
     3129    else
     3130    {
     3131        assert( false , "undefined file system type\n" );
     3132    }
     3133
     3134    return error;
     3135
     3136}  // end vfs_fs_sync_inode()
     3137
     3138////////////////////////////////////////////////
     3139error_t vfs_fs_sync_fat( vfs_fs_type_t fs_type )
     3140{
     3141    error_t error = 0;
     3142
     3143    // call relevant FS function
     3144    if( fs_type == FS_TYPE_FATFS )
     3145    {
     3146        error = fatfs_sync_fat();
     3147    }
     3148    else if( fs_type == FS_TYPE_RAMFS )
     3149    {
     3150        assert( false , "should not be called for RAMFS\n" );
     3151    }
     3152    else if( fs_type == FS_TYPE_DEVFS )
     3153    {
     3154        assert( false , "should not be called for DEVFS\n" );
     3155    }
     3156    else
     3157    {
     3158        assert( false , "undefined file system type\n" );
     3159    }
     3160
     3161    return error;
     3162
     3163}  // end vfs_fs_sync_fat()
     3164
     3165//////////////////////////////////////////////////////
     3166error_t vfs_fs_sync_free_info( vfs_fs_type_t fs_type )
     3167{
     3168    error_t error = 0;
     3169
     3170    // call relevant FS function
     3171    if( fs_type == FS_TYPE_FATFS )
     3172    {
     3173        error = fatfs_sync_free_info();
     3174    }
     3175    else if( fs_type == FS_TYPE_RAMFS )
     3176    {
     3177        assert( false , "should not be called for RAMFS\n" );
     3178    }
     3179    else if( fs_type == FS_TYPE_DEVFS )
     3180    {
     3181        assert( false , "should not be called for DEVFS\n" );
     3182    }
     3183    else
     3184    {
     3185        assert( false , "undefined file system type\n" );
     3186    }
     3187
     3188    return error;
     3189
     3190}  // end vfs_fs_sync_fat()
     3191
    23763192/////////////////////////////////////////////////
    23773193error_t vfs_fs_cluster_alloc( uint32_t   fs_type,
  • trunk/kernel/fs/vfs.h

    r602 r610  
    6969 *****************************************************************************************/
    7070
    71 #define VFS_LOOKUP_DIR      0x01     /* the searched inode is a directory                */
     71#define VFS_LOOKUP_DIR      0x01     /* the searched inode must be a directory           */
    7272#define VFS_LOOKUP_OPEN         0x02     /* the search is for an open/opendir                */
    7373#define VFS_LOOKUP_PARENT       0x04     /* return the parent inode (not the inode itself)   */
    7474#define VFS_LOOKUP_CREATE   0x10     /* file must be created if missing                  */
    75 #define VFS_LOOKUP_EXCL     0x20     /* file cannot previously exist                     */   
     75#define VFS_LOOKUP_EXCL     0x20     /* file cannot previously exist                     */
    7676
    7777/******************************************************************************************
     
    117117/******************************************************************************************
    118118 * This structure define a VFS inode.
    119  * It contains an extended pointer on the parent dentry, and (for directory only)
    120  * an hash table (xhtab) registering all children dentries.
    121  * The <parent> inode is unique for a directory (no hard links for directories).
    122  * For a file, the parent field points to the first dentry who created this inode.
     119 * An inode has several children dentries (if it is a directory), an can have several
     120 * parents dentries (if it hass several aliases links):
     121 * - The "parents" field is the root of the xlist of parents dentries, and the "links"
     122 *   fiels define the number of aliases parent dentries. only a FILE inode can have
     123 *   several parents (no hard links for directories).
     124 * - The "children" field is an embedded xhtab containing pointers on all local children
     125 *   dentries. This set of children is empty for a FILE inode.
    123126 * Synchronisation:
    124  * - the main_lock (remote_busylock) is used during the inode tree traversal,
    125  *   or for inode modification (add/remove children).
    126  * - the data_lock (remote_rwlock) is used during read/write accesses to the data
    127  *   stored in the mapper.
    128  * - the mapper lock (remote rwlock) is only used during the radix tree traversal
    129  *   to return the relevant page for read/write.
     127 * - the main_lock (remote_rwlock) is used during the inode tree traversal,
     128 *   or for inode modification (add/remove children in xhtab).
     129 * - the size_lock (remote_rwlock) is used during read/write accesses to the size
     130 *   field in the mapper.
     131 * - access to the data stored in the associated mapper use the mapper remote_rwlock
     132 *   protecting radix tree traversal and modifications.
    130133 *****************************************************************************************/
    131134
     
    158161{
    159162        struct vfs_ctx_s * ctx;              /*! local pointer on FS context                 */
    160     uint32_t           gc;               /*! generation counter                          */
    161163        uint32_t           inum;             /*! inode identifier (unique in file system)    */
    162164        uint32_t           attr;             /*! inode attributes (see above)                */
    163165        vfs_inode_type_t   type;             /*! inode type (see above)                      */
    164166        uint32_t           size;             /*! number of bytes                             */
    165         uint32_t           links;            /*! number of alias dentry                      */
    166167        uint32_t           uid;              /*! user owner identifier                       */
    167168        uint32_t           gid;              /*! group owner identifier                      */
    168169    uint32_t           rights;           /*! access rights                               */
    169         uint32_t               refcount;         /*! reference counter (all pointers)            */
    170         xptr_t             parent_xp;        /*! extended pointer on parent dentry           */
     170        xlist_entry_t      parents;          /*! root of list of parents dentries            */
     171        uint32_t           links;            /*! number of parent dentries (hard links)      */
    171172        xhtab_t            children;         /*! embedded xhtab of children dentries         */
    172         remote_rwlock_t    data_lock;        /*! protect read/write to data and to size      */
    173         remote_busylock_t  main_lock;        /*! protect inode tree traversal and modifs     */
    174         list_entry_t       list;             /*! member of set of inodes in same cluster     */
    175         xlist_entry_t      wait_root;        /*! root of threads waiting on this inode       */
     173        remote_rwlock_t    size_lock;        /*! protect read/write to size                  */
     174        remote_rwlock_t    main_lock;        /*! protect inode tree traversal and modifs     */
     175//  list_entry_t       list;             /*! member of set of inodes in same cluster     */
     176//  list_entry_t       wait_root;        /*! root of threads waiting on this inode       */
    176177        struct mapper_s  * mapper;           /*! associated file cache                       */
    177178        void             * extend;           /*! fs_type_specific inode extension            */
     
    183184#define VFS_ISUID          0x0004000
    184185#define VFS_ISGID          0x0002000
    185 #define VFS_ISVTX          0x0001000
     186define VFS_ISVTX           0x0001000
    186187
    187188#define VFS_IRWXU      0x0000700
     
    203204 * This structure defines a directory entry.
    204205 * A dentry contains the name of a remote file/dir, an extended pointer on the
    205  * inode representing this file/dir, and a local pointer on the inode representing
     206 * inode representing this file/dir, a local pointer on the inode representing
    206207 * the parent directory.
     208 * A dentry can be member of the set of children of a given directory inode (xhtab).
     209 * A dentry can be member of the set of parents  of a given inode (xlist).
    207210 *****************************************************************************************/
    208211
     
    212215        char                 name[CONFIG_VFS_MAX_NAME_LENGTH];
    213216        uint32_t             length;         /*! name length (bytes)                         */
    214         uint32_t             refcount;       /*! reference counter (all pointers)            */
    215217    struct vfs_inode_s * parent;         /*! local pointer on parent inode               */
    216218    xptr_t               child_xp;       /*! extended pointer on child inode             */
    217     xlist_entry_t        list;           /*! member of list of dentries with same key    */
     219    xlist_entry_t        children;       /*! member of set of children dentries          */
     220    xlist_entry_t        parents;        /*! member of set of parent dentries            */
    218221        void               * extend;         /*! FS specific extension                       */
    219222}
     
    301304
    302305
    303 
    304306/******************************************************************************************
    305307 *        These low-level functions access / modify a VFS inode descriptor
     
    314316 * This function allocates memory from local cluster for an inode descriptor and the
    315317 * associated mapper. It initialise these descriptors from arguments values.
    316  * The parent dentry must have been previously created.
    317318 * If the client thread is not running in the cluster containing this inode,
    318319 * it must use the rpc_vfs_inode_create_client() function.
    319320 ******************************************************************************************
    320  * @ dentry_xp  : extended pointer on associated dentry (in parent inode cluster).
    321321 * @ fs_type    : file system type.
    322322 * @ inode_type : inode type.
     
    328328 * @ return 0 if success / return ENOMEM or EINVAL if error.
    329329 *****************************************************************************************/
    330 error_t vfs_inode_create( xptr_t            dentry_xp,
    331                           vfs_fs_type_t     fs_type,
     330error_t vfs_inode_create( vfs_fs_type_t     fs_type,
    332331                          vfs_inode_type_t  inode_type,
    333332                          uint32_t          attr,
     
    340339 * This function releases memory allocated to an inode descriptor, including
    341340 * all memory allocated to the mapper (both mapper descriptor and radix tree).
    342  * The mapper should not contain any dirty page (shold be synchronized before deletion),
    343  * and the inode refcount must be zero.
     341 * The mapper should not contain any dirty page (should be synchronized before deletion).
    344342 * It must be executed by a thread running in the cluster containing the inode.
    345343 * Use the rpc_vfs_inode_destroy_client() function if required.
     
    348346 *****************************************************************************************/
    349347void vfs_inode_destroy( vfs_inode_t *  inode ); 
    350 
    351 /******************************************************************************************
    352  * This function atomically increment/decrement the inode refcount.
    353  * It can be called by any thread running in any cluster.
    354  *****************************************************************************************/
    355 void vfs_inode_remote_up( xptr_t  inode_xp );
    356 void vfs_inode_remote_down( xptr_t  inode_xp );
    357348
    358349/******************************************************************************************
     
    423414 * This function allocates memory from local cluster for a dentry descriptor,
    424415 * initialises it from  arguments values, and returns the extended pointer on dentry.
    425  * The inode field is not initialized, because the inode does not exist yet.
    426416 * If the client thread is not running in the target cluster for this inode,
    427417 * it must use the rpc_dentry_create_client() function.
     
    429419 * @ fs_type    : file system type.
    430420 * @ name       : directory entry file/dir name.
    431  * @ parent     : local pointer on parent inode.
    432421 * @ dentry_xp  : [out] buffer for extended pointer on created dentry.
    433422 * @ return 0 if success / return ENOMEM or EINVAL if error.
     
    435424error_t vfs_dentry_create( vfs_fs_type_t   fs_type,
    436425                           char          * name,
    437                            vfs_inode_t   * parent,
    438426                           xptr_t        * dentry_xp );
    439427 
    440428/******************************************************************************************
    441  * This function releases memory allocated to a dentry descriptor.
    442  * The dentry refcount must be zero.
     429 * This function removes the dentry from the parent inode xhtab, and releases the memory
     430 * allocated to the dentry descriptor.
    443431 * It must be executed by a thread running in the cluster containing the dentry.
    444432 * Use the rpc_vfs_dentry_destroy_client() function if required.
     
    447435 *****************************************************************************************/
    448436void vfs_dentry_destroy( vfs_dentry_t *  dentry ); 
    449 
    450 /******************************************************************************************
    451  * These functions atomically increment/decrement the dentry refcount.
    452  * It can be called by any thread running in any cluster.
    453  *****************************************************************************************/
    454 void vfs_dentry_remote_up( xptr_t dentry_xp );
    455 void vfs_dentry_remote_down( xptr_t dentry_xp );
    456437
    457438
     
    496477
    497478/******************************************************************************************
    498  *        These functions access / modify the distributed VFS Inode Treee
    499  *****************************************************************************************/
    500 
    501 /******************************************************************************************
    502  * This function returns in a kernel buffer allocated by the caller function,
    503  * the pathname of a file/dir identified by an extended pointer on the inode.
     479 *        These functions access / modify the distributed VFS Inode Tree
     480 *****************************************************************************************/
     481
     482/******************************************************************************************
     483 * This function returns in a kernel <buffer> allocated by the caller function,
     484 * the pathname of a file/dir identified by the <inode_xp> argument.
    504485 * It traverse the Inode Tree from the target node to the root.
    505486 * It can be called by any thread running in any cluster.
    506  ******************************************************************************************
    507  * @ inode_xp    : pointer on inode descriptor.
    508  * @ buffer      : kernel buffer for pathname (must be allocated by caller).
    509  * @ size        : max number of characters in buffer.
     487 * As this buffer if filled in "reverse order" (i.e. from the target inode to the root),
     488 * the pathname is stored in the higher part of the buffer.
     489 * A pointer on the first character of the pathname is returned in <first> buffer.
     490 *
     491 * WARNING : This function takes & releases the remote_rwlock protecting the Inode Tree.
     492 ******************************************************************************************
     493 * @ inode_xp    : [in]  extended pointer on target inode descriptor.
     494 * @ buffer      : [in]  kernel buffer for pathname (allocated by caller).
     495 * @ first       : [out] pointer on first character in buffer.
     496 * @ max_size    : [in]  max number of characters in buffer.
    510497 * @ return 0 if success / return EINVAL if buffer too small.
    511498 *****************************************************************************************/
    512499error_t vfs_get_path( xptr_t    inode_xp,
    513500                      char    * buffer,
     501                      char   ** first,
    514502                      uint32_t  max_size );
    515503
    516504/******************************************************************************************
    517  * This function takes a pathname (absolute or relative to cwd) and returns an extended
    518  * pointer on the associated inode.
     505 * This function traverses the the Inode Tree, from inode identified by the <root_xp>
     506 * argument, and returns in <inode_xp> the inode identified by the < pathname> argument.
     507 * It can be called by a thread running in any cluster.
     508 * It supports the following flags that define the lookup modes :
     509 * - VFS_LOOKUP_DIR    : the searched inode must be a directory
     510 * - VFS_LOOKUP_OPEN   : the search is for an open/opendir
     511 * - VFS_LOOKUP_PARENT : return the parent inode (not the inode itself)
     512 * - VFS_LOOKUP_CREATE : file/directory must be created if missing on IOC
     513 * - VFS_LOOKUP_EXCL   : file cannot previously exist
     514 * As the inode Tree is a cache, the search policy is the following :
    519515 * - If a given directory name in the path is not found in the inode tree, it try to load
    520516 *   the missing dentry/inode couple, from informations found in the parent directory.
    521  * - If this directory entry does not exist on device, it returns an error.
    522  * - If the the file identified by the pathname does not exist on device but the
    523  *   flag CREATE is set, the inode is created.
    524  * - If the the file identified by the pathname exist on device but both flags EXCL
     517 * - If this directory entry does not exist on IOC, it returns an error.
     518 * - If the the file identified by the pathname does not exist on IOC but the
     519 *   flag CREATE is set, the inode is created. It returns an error otherwise.
     520 * - If the the file identified by the pathname exist on device, but both flags EXCL
    525521 *   and CREATE are set, an error is returned.
    526  ******************************************************************************************
    527  * @ cwd_xp      : extended pointer on current directory (for relative path).
    528  * @ pathname    : path in kernel space (can be relative or absolute).
    529  * @ lookup_mode : flags defining the working mode (defined above in this file).
     522 * - If the PARENT flag is set, it returns in <inode_xp> an extended pointer on the parent
     523 *   inode, and copies in <last_name> buffer a string containing the last name in path.
     524 *
     525 * WARNING : The remote_rwlock protecting the Inode Tree must be taken by the caller.
     526 *
     527 * TODO the access rights are not checked yet.
     528 ******************************************************************************************
     529 * @ root_xp     : [in]  extended pointer on root inode (can be root of a subtree).
     530 * @ pathname    : [in]  path (can be relative or absolute).
     531 * @ lookup_mode : [in]  flags defining the searching mode.
    530532 * @ inode_xp    : [out] buffer for extended pointer on searched inode.
     533 * @ last_name   : [out] pointer on buffer for last name in path.
    531534 * @ return 0 if success / ENOENT if inode not found , EACCES if permisson denied,
    532  *                         EAGAIN if a new complete lookup must be made
    533  *****************************************************************************************/
    534 error_t vfs_lookup( xptr_t             cwd_xp,
     535 *****************************************************************************************/
     536error_t vfs_lookup( xptr_t             root_xp,
    535537                    char             * pathname,
    536538                    uint32_t           lookup_mode,
    537                                         xptr_t           * inode_xp );
     539                                        xptr_t           * inode_xp,
     540                    char             * last_name );
    538541
    539542/******************************************************************************************
    540543 * This function creates a new couple dentry/inode, and insert it in the Inode-Tree.
     544 * Only the distributed Inode Tree is modified: it does NOT modify the parent mapper,
     545 * and does NOT update the FS on IOC device.
    541546 * It can be executed by any thread running in any cluster (can be different from both
    542  * the child cluster and the parent cluster), as it uses RPCs if required.
    543  * Only the distributed Inode Tree is modified: Even for a new file, this function
    544  * does NOT modify the parent mapper, and does NOT update the FS on IOC device.
     547 * the child cluster and the parent cluster).
    545548 *
    546549 * [Implementation]
     
    563566 * @ return 0 if success / -1 if dentry or inode cannot be created.
    564567 *****************************************************************************************/
    565 error_t vfs_add_child_in_parent( cxy_t              child_inodecxy,
    566                                  vfs_inode_type_t   chilg_inode_type,
     568error_t vfs_add_child_in_parent( cxy_t              child_inode_cxy,
     569                                 vfs_inode_type_t   child_inode_type,
    567570                                 vfs_fs_type_t      fs_type,
    568571                                 xptr_t             parent_inode_xp,
     
    572575
    573576/******************************************************************************************
    574  * This function removes a couple dentry/inode from the Inode-Tree.
    575  * Both the inode and dentry references counters must be 1.
     577 * This function removes a remote dentry from the Inode-Tree.
     578 * - It removes the dentry from the parent inode xhtab ("children" field), and from the
     579 *   child inode xlist ("parents" field).
     580 * - It releases the memory allocated to the dentry descriptor.
     581 * - If the number of parents of the child inode is one, it also releases the memory
     582 *   allocated to the child inode.
     583 * Only the Inode Tree is modified: it does NOT modify the parent mapper,
     584 * and does NOT update the FS on IOC device.
    576585 * It can be executed by any thread running in any cluster (can be different from both
    577  * the inode cluster and the dentry cluster), as it uses RPCs if required.
    578  ******************************************************************************************
    579  * @ child_xp   : extended pointer on removed inode.
    580  *****************************************************************************************/
    581 void vfs_remove_child_from_parent( xptr_t inode_xp );
     586 * the inode cluster and the dentry cluster).
     587 ******************************************************************************************
     588 * @ dentry_xp   : extended pointer on removed dentry.
     589 *****************************************************************************************/
     590void vfs_remove_child_from_parent( xptr_t dentry_xp );
    582591
    583592/******************************************************************************************
     
    599608 *****************************************************************************************/
    600609error_t vfs_new_child_init( xptr_t   parent_xp,
    601                          xptr_t   dentry_xp,
    602                          xptr_t   child_xp );
     610                            xptr_t   dentry_xp,
     611                            xptr_t   child_xp );
    603612
    604613/******************************************************************************************
     
    661670/******************************************************************************************
    662671 * This function allocates a vfs_file_t structure in the cluster containing the inode
    663  * associated to the file identified by the <cwd_xp> & <path> arguments.
     672 * identified by the <root_xp> & <path> arguments.
    664673 * It initializes it, register it in the reference process fd_array identified by the
    665  * <process> argument, and returns both the extended pointer on the file descriptor,
    666  * and the allocated index in the fd_array.
     674 * <process_xp> argument, and returns both the extended pointer on the file descriptor,
     675 * and the allocated index in the <file_xp> and <file_id> buffers.
    667676 * The pathname can be relative to current directory or absolute.
    668  * If the inode does not exist in the inode cache, it try to find the file on the mounted
     677 * If the inode does not exist in the inode cache, it try to find the file on the IOC
    669678 * device, and creates an inode on a pseudo randomly selected cluster if found.
    670679 * It the requested file does not exist on device, it creates a new inode if the
    671680 * O_CREAT flag is set, and return an error otherwise.
     681 *
     682 * WARNING : this function takes & releases the remote_rwlock protecting the Inode Tree.
    672683 ******************************************************************************************
    673  * @ process     : local pointer on local process descriptor copy.
     684 * @ root_xp     : extended pointer on path root inode.
    674685 * @ path        : file pathname (absolute or relative to current directory).
     686 * @ process_xp  : extended pointer on client reference process.
    675687 * @ flags       : defined in vfs_file_t structure.
    676688 * @ mode        : access rights (as defined by chmod).
     
    679691 * @ return 0 if success / return non-zero if error.
    680692 *****************************************************************************************/
    681 error_t vfs_open( struct process_s * process,
     693error_t vfs_open( xptr_t             root_xp,
    682694                          char             * path,
     695                  xptr_t             process_xp,
    683696                          uint32_t           flags,
    684697                  uint32_t           mode,
     
    721734/******************************************************************************************
    722735 * This function is called by the kernel to create in the file system a new directory
    723  * entry identified by the <cwd_xp> & <path_1>, linked to the node identified by the
    724  * <cwd_xp> & <path_2> arguments.  It can be any type of node.
    725  * If the link is successful, the link count of the target node is incremented.
    726  * <path_1> and <path_2> share equal access rights to the underlying object.
     736 * identified by the <root_xp> & <path> arguments, with the access permission defined
     737 * by the <rights> argument. All nodes in the path - but the last -  must exist.
     738 *
     739 * WARNING : this function takes & releases the remote_rwlock protecting the Inode Tree.
     740 ******************************************************************************************
     741 * @ root_xp : extended pointer on path root inode (any inode in Inode Tree).
     742 * @ path    : pathname (absolute or relative to current directory).
     743 * @ rights  : access rights.
     744 * @ returns 0 if success / -1 if error.
     745 *****************************************************************************************/
     746error_t vfs_mkdir( xptr_t   root_xp,
     747                   char   * path,
     748                   uint32_t rights );
     749
     750/******************************************************************************************
     751 * This function is called by the kernel to create in the file system a new directory
     752 * entry identified by the <new_root_xp> & <new_path> arguments, to be linked to an
     753 * existing inode, identified by the  <old_root_xp> & <old_path> arguments.
     754 * If the link is successful, the link count of the target inode is incremented.
     755 * The <new_path> and <old_path> share equal access rights to the underlying inode.
    727756 * Both the IOC device and the Inode Tree are modified.
    728  ******************************************************************************************
    729  * @ cwd_xp   : extended pointer on current working directory file descriptor.
    730  * @ path_1   : new pathname (absolute or relative to current directory).
    731  * @ path_1   : existing pathname (absolute or relative to current directory).
     757 $
     758 * TODO This function should handle any type of node, but the current implementation
     759 * handles only the FILE and DIR types.
     760 *
     761 * WARNING : this function takes & releases the remote_rwlock protecting the Inode Tree.
     762 ******************************************************************************************
     763 * @ old_root_xp : extended pointer on old path root inode (any inode in Inode Tree).
     764 * @ old_path    : old pathname (absolute or relative to current directory).
     765 * @ nld_root_xp : extended pointer on new path root inode (any inode in Inode Tree).
     766 * @ new_path    : new pathname (absolute or relative to current directory).
    732767 * @ returns 0 if success / -1 if error.
    733768 *****************************************************************************************/
    734 error_t vfs_link( xptr_t   cwd_xp,
    735                   char   * path_1,
    736                   char   * path_2 );
     769error_t vfs_link( xptr_t   old_root_xp,
     770                  char   * old_path,
     771                  xptr_t   new_root_xp,
     772                  char   * new_path );
    737773
    738774/******************************************************************************************
    739775 * This function is called by the kernel to remove from the file system a directory entry
    740  * identified by the  <cwd_xp> & <path> arguments. The target node can be any type of node.
    741  * The link count of the target node is decremented. If the removed link is the last,
    742  * the target node is deleted.
     776 * identified by the  <root_xp> & <path> arguments.
     777 * The link count of the target node is decremented.
     778 * If the removed link is the last, the target inode is deleted.
    743779 * Both the IOC device and the Inode Tree are modified.
    744  ******************************************************************************************
    745  * @ cwd_xp   : extended pointer on the current working directory file descriptor.
     780 *
     781 * TODO This function should handle any type of node, but the current implementation
     782 * handles only only the FILE and DIR types.
     783 *
     784 * WARNING : this function takes & releases the remote_rwlock protecting the Inode Tree.
     785 ******************************************************************************************
     786 * @ root_xp  : extended pointer on root inode (can be any inode in Inode Tree).
    746787 * @ path     : pathname (absolute or relative to current directory).
    747788 * @ returns 0 if success / -1 if error.
    748789 *****************************************************************************************/
    749 error_t vfs_unlink( xptr_t   cwd_xp,
     790error_t vfs_unlink( xptr_t   root_xp,
    750791                    char   * path );
    751792
    752793/******************************************************************************************
    753  * This function returns, in the structure pointed by the <st> pointer,
    754  * various informations on the inode identified by the <inode_xp> argument.
    755  * TODO : only partially implemented yet...
    756  ******************************************************************************************
    757  * @ inode_xp   : extended pointer on the remote inode.
     794 * This function returns, in the structure pointed by the <st> pointer, various
     795 * informations on the inode identified by the <root_inode_xp> and <patname> arguments.
     796 *
     797 * TODO : only partially implemented yet (only size and inum fields).
     798 *
     799 * WARNING : this function takes & releases the remote_rwlock protecting the Inode Tree.
     800 ******************************************************************************************
     801 * @ root_xp    : extended pointer on path root inode (any inode in Inode Tree)
     802 * @ pathname   : pathname to target inode.
    758803 * @ st         : local pointer on the stat structure in kernel space.
    759804 * @ returns 0 if success / -1 if error.
    760805 *****************************************************************************************/
    761 error_t vfs_stat( xptr_t        inode_xp,
     806error_t vfs_stat( xptr_t        root_xp,
     807                  char        * pathname,
    762808                  struct stat * st );
    763809
     
    775821
    776822/******************************************************************************************
    777  * This function  creates a new inode and associated dentry  for the directory defined
    778  * by the <cwd_xp> & <path> arguments.
     823 * This function  creates a new directory as defined by the <root_xp> & <path> arguments.
    779824 * TODO not implemented yet...
    780825 ******************************************************************************************
    781  * @ cwd_xp   : extended pointer on the current working directory file descriptor.
    782  * @ path     : pathname (absolute or relative to current directory).                     
     826 * @ root_xp  : extended pointer on the path root directory.
     827 * @ path     : pathname (absolute or relative to CWD).                     
    783828 * @ mode     : access rights (as defined by chmod)
    784829 * @ returns 0 if success / -1 if error.
    785830 *****************************************************************************************/
    786 error_t vfs_mkdir( xptr_t     cwd_xp,
     831error_t vfs_mkdir( xptr_t     root_xp,
    787832                   char     * path,
    788833                   uint32_t   mode );
    789834
    790835/******************************************************************************************
    791  * This function makes the directory identified by <cwd_xp / path> arguments to become
    792  * the working directory for the calling process.
     836 * This function makes the directory identified by the <root_xp and <path> arguments
     837 * to become the working directory for the calling process.
    793838 ******************************************************************************************
    794  * @ cwd_xp      : extended pointer on current directory file descriptor (relative path).
    795  * @ path        : file pathname (absolute or relative to current directory).
     839 * @ root_xp  : extended pointer on the path root directory.
     840 * @ path     : pathname (absolute or relative to CWD).
    796841 * return 0 if success / -1 if error.
    797842 *****************************************************************************************/
    798 error_t vfs_chdir( xptr_t   cwd_xp,
     843error_t vfs_chdir( xptr_t   root_xp,
    799844                   char   * path );
    800845
    801846/******************************************************************************************
    802  * This function change the access rigths for the file identified by the <cwd_xp / path>
    803  * arguments. The new access rights are defined by the <mode> argument value.
     847 * This function change the access rigths for the file/directory identified by the
     848 * <root_xp> and <path> arguments as defined by the <mode> argument value.
    804849 ******************************************************************************************
    805  * @ cwd_xp      : extended pointer on current directory file descriptor (relative path).
    806  * @ path        : file pathname (absolute or relative to current directory).
    807  * @ mode        : access rights new value.
     850 * @ root_xp  : extended pointer on the path root directory.
     851 * @ path     : pathname (absolute or relative to CWD).
     852 * @ mode     : access rights
    808853 * return 0 if success / -1 if error.
    809854 *****************************************************************************************/
    810 error_t vfs_chmod( xptr_t        cwd_xp,
     855error_t vfs_chmod( xptr_t        root_xp,
    811856                   char        * path,
    812857                   uint32_t      mode );
     
    816861 * TODO not implemented yet                                                         
    817862 ******************************************************************************************
    818  * @ path        : FIFO pathname (absolute or relative to current directory).
    819  * @ cwd_xp      : extended pointer on the current working directory file descriptor.
    820  * @ mode        : access rights new value.
    821  *****************************************************************************************/
    822 error_t vfs_mkfifo( xptr_t       cwd_xp,
     863 * @ root_xp  : extended pointer on the path root directory.
     864 * @ path     : pathname (absolute or relative to CWD).
     865 * @ mode     : access rights new value.
     866 *****************************************************************************************/
     867error_t vfs_mkfifo( xptr_t       root_xp,
    823868                    char       * path,
    824869                    uint32_t     mode );
     
    905950
    906951/*****************************************************************************************
    907  * This function updates the FS on the IOC device for the FAT itself.
    908  * It scan all clusters registered in the FAT mapper, and copies to device
    909  * each page marked as dirty.
     952 * This function updates the FS defined by the <fs_type> argument on the IOC device
     953 * for the FAT itself. It scan all clusters registered in the FAT mapper, and copies
     954 * to device each page marked as dirty.
    910955 *
    911956 * Depending on the file system type, it calls the relevant, FS specific function.
    912957 * It can be called by a thread running in any cluster.
    913958 *****************************************************************************************
     959 * @ fs_type   : specific file system type.
    914960 * @ return 0 if success / return EIO if failure during device access.
    915961 ****************************************************************************************/
    916 error_t vfs_fs_sync_fat( void );
     962error_t vfs_fs_sync_fat( vfs_fs_type_t fs_type );
    917963
    918964/*****************************************************************************************
    919  * This function updates the free clusters info on the IOC device.
     965 * This function updates the free clusters info on the IOC device for the FS defined
     966 * by the <fs_type> argument.
    920967 *
    921968 * Depending on the file system type, it calls the relevant, FS specific function.
    922969 * It can be called by a thread running in any cluster.
    923970 *****************************************************************************************
     971 * @ fs_type   : specific file system type.
    924972 * @ return 0 if success / return EIO if failure during device access.
    925973 ****************************************************************************************/
    926 error_t vfs_fs_sync_free_info( void );
     974error_t vfs_fs_sync_free_info( vfs_fs_type_t fs_type );
    927975
    928976/******************************************************************************************
  • trunk/kernel/kern/do_syscall.c

    r583 r610  
    22 * do_syscall.c - architecture independant entry-point for system calls.
    33 *
    4  * Author    Alain Greiner (2016)
     4 * Author    Alain Greiner (2016,2017,2018)
    55 *
    66 * Copyright (c) UPMC Sorbonne Universites
     
    6161    sys_mutex,              // 9
    6262
    63     sys_exit,               // 10
     63    sys_rename,             // 10
    6464    sys_munmap,             // 11
    6565    sys_open,               // 12
     
    104104    sys_fg,                 // 48
    105105    sys_is_fg,              // 49
     106
     107    sys_exit,               // 50
    106108};
    107109
     
    122124    case SYS_MUTEX :                       return "MUTEX";            // 9
    123125
    124     case SYS_EXIT:                         return "EXIT";             // 10
     126    case SYS_RENAME:                       return "RENAME";           // 10
    125127    case SYS_MUNMAP:                       return "MUNMAP";           // 11
    126128    case SYS_OPEN:                         return "OPEN";             // 12
     
    165167    case SYS_FG:                           return "FG";               // 48
    166168    case SYS_IS_FG:                        return "IS_FG";            // 49
     169
     170    case SYS_EXIT:                         return "EXIT";             // 50
     171
    167172    default:                               return "undefined";
    168173    }
  • trunk/kernel/kern/kernel_init.c

    r601 r610  
    146146
    147147    "THREAD_JOIN",           // 10
    148     "VFS_MAIN",              // 11
     148    "XHTAB_STATE",           // 11
    149149    "CHDEV_QUEUE",           // 12
    150150    "CHDEV_TXT0",            // 13
     
    154154    "CONDVAR_STATE",         // 17
    155155    "SEM_STATE",             // 18
    156     "XHTAB_STATE",           // 19
     156    "RPOCESS_CWD",           // 19
    157157
    158158    "unused_20",             // 20
     
    171171
    172172    "MAPPER_STATE",          // 30
    173     "PROCESS_CWD",           // 31
    174     "VFS_INODE",             // 32
    175     "VFS_FILE",              // 33
    176     "VMM_VSL",               // 34
    177     "VMM_GPT",               // 35
     173    "VFS_SIZE",              // 31
     174    "VFS_FILE",              // 32
     175    "VMM_VSL",               // 33
     176    "VMM_GPT",               // 34
     177    "VFS_MAIN",              // 35
    178178};       
    179179
     
    970970#if DEBUG_KERNEL_INIT
    971971if( (core_lid ==  0) & (local_cxy == 0) )
    972 printk("\n[%s] : exit barrier 0 : TXT0 initialized / sr %x / cycle %d\n",
    973 __FUNCTION__, (uint32_t)hal_get_sr(), (uint32_t)hal_get_cycles() );
     972printk("\n[%s] : exit barrier 0 : TXT0 initialized / cycle %d\n",
     973__FUNCTION__, (uint32_t)hal_get_cycles() );
    974974#endif
    975975
     
    10121012#if DEBUG_KERNEL_INIT
    10131013if( (core_lid ==  0) & (local_cxy == 0) )
    1014 printk("\n[%s] : exit barrier 1 : clusters initialised / sr %x / cycle %d\n",
    1015 __FUNCTION__, (uint32_t)hal_get_sr(), (uint32_t)hal_get_cycles() );
     1014printk("\n[%s] : exit barrier 1 : clusters initialised / cycle %d\n",
     1015__FUNCTION__, (uint32_t)hal_get_cycles() );
    10161016#endif
    10171017
     
    10391039#if DEBUG_KERNEL_INIT
    10401040if( (core_lid ==  0) & (local_cxy == 0) )
    1041 printk("\n[%s] : exit barrier 2 : PIC initialised / sr %x / cycle %d\n",
    1042 __FUNCTION__, (uint32_t)hal_get_sr(), (uint32_t)hal_get_cycles() );
     1041printk("\n[%s] : exit barrier 2 : PIC initialised / cycle %d\n",
     1042__FUNCTION__, (uint32_t)hal_get_cycles() );
    10431043#endif
    10441044
     
    10721072#if DEBUG_KERNEL_INIT
    10731073if( (core_lid ==  0) & (local_cxy == 0) )
    1074 printk("\n[%s] : exit barrier 3 : all chdevs initialised / sr %x / cycle %d\n",
    1075 __FUNCTION__, (uint32_t)hal_get_sr(), (uint32_t)hal_get_cycles() );
     1074printk("\n[%s] : exit barrier 3 : all chdevs initialised / cycle %d\n",
     1075__FUNCTION__, (uint32_t)hal_get_cycles() );
    10761076#endif
    10771077
     
    11361136 
    11371137            // 4. create VFS root inode in cluster 0
    1138             error = vfs_inode_create( XPTR_NULL,                           // dentry_xp
    1139                                       FS_TYPE_FATFS,                       // fs_type
     1138            error = vfs_inode_create( FS_TYPE_FATFS,                       // fs_type
    11401139                                      INODE_TYPE_DIR,                      // inode_type
    11411140                                      0,                                   // attr
     
    11741173        // register VFS root inode in process_zero descriptor of cluster 0
    11751174        process_zero.vfs_root_xp = vfs_root_inode_xp;
    1176         process_zero.vfs_cwd_xp  = vfs_root_inode_xp;
     1175        process_zero.cwd_xp      = vfs_root_inode_xp;
    11771176    }
    11781177
     
    11851184#if DEBUG_KERNEL_INIT
    11861185if( (core_lid ==  0) & (local_cxy == 0) )
    1187 printk("\n[%s] : exit barrier 4 : VFS root initialized in cluster 0 / sr %x / cycle %d\n",
    1188 __FUNCTION__, (uint32_t)hal_get_sr(), (uint32_t)hal_get_cycles() );
     1186printk("\n[%s] : exit barrier 4 : VFS root (%x,%x) in cluster 0 / cycle %d\n",
     1187__FUNCTION__, GET_CXY(process_zero.vfs_root_xp),
     1188GET_PTR(process_zero.vfs_root_xp), (uint32_t)hal_get_cycles() );
    11891189#endif
    11901190
     
    12431243        // update local process_zero descriptor
    12441244        process_zero.vfs_root_xp = vfs_root_inode_xp;
    1245         process_zero.vfs_cwd_xp  = vfs_root_inode_xp;
     1245        process_zero.cwd_xp      = vfs_root_inode_xp;
    12461246    }
    12471247
     
    12541254#if DEBUG_KERNEL_INIT
    12551255if( (core_lid ==  0) & (local_cxy == 1) )
    1256 printk("\n[%s] : exit barrier 5 : VFS root initialized in cluster 1 / sr %x / cycle %d\n",
    1257 __FUNCTION__, (uint32_t)hal_get_sr(), (uint32_t)hal_get_cycles() );
     1256printk("\n[%s] : exit barrier 4 : VFS root (%x,%x) in cluster 1 / cycle %d\n",
     1257__FUNCTION__, GET_CXY(process_zero.vfs_root_xp),
     1258GET_PTR(process_zero.vfs_root_xp), (uint32_t)hal_get_cycles() );
    12581259#endif
    12591260
     
    13031304#if DEBUG_KERNEL_INIT
    13041305if( (core_lid ==  0) & (local_cxy == 0) )
    1305 printk("\n[%s] : exit barrier 6 : DEVFS root initialized in cluster 0 / sr %x / cycle %d\n",
    1306 __FUNCTION__, (uint32_t)hal_get_sr(), (uint32_t)hal_get_cycles() );
     1306printk("\n[%s] : exit barrier 6 : DEVFS root initialized in cluster 0 / cycle %d\n",
     1307__FUNCTION__, (uint32_t)hal_get_cycles() );
    13071308#endif
    13081309
     
    13401341#if DEBUG_KERNEL_INIT
    13411342if( (core_lid ==  0) & (local_cxy == 0) )
    1342 printk("\n[%s] : exit barrier 7 : DEV initialized in cluster 0 / sr %x / cycle %d\n",
    1343 __FUNCTION__, (uint32_t)hal_get_sr(), (uint32_t)hal_get_cycles() );
     1343printk("\n[%s] : exit barrier 7 : DEV initialized in cluster 0 / cycle %d\n",
     1344__FUNCTION__, (uint32_t)hal_get_cycles() );
    13441345#endif
    13451346
     
    13661367#if DEBUG_KERNEL_INIT
    13671368if( (core_lid ==  0) & (local_cxy == 0) )
    1368 printk("\n[%s] : exit barrier 8 : process init created / sr %x / cycle %d\n",
    1369 __FUNCTION__, (uint32_t)hal_get_sr(), (uint32_t)hal_get_cycles() );
     1369printk("\n[%s] : exit barrier 8 : process init created / cycle %d\n",
     1370__FUNCTION__, (uint32_t)hal_get_cycles() );
    13701371#endif
    13711372
     
    14361437    dev_pic_enable_timer( CONFIG_SCHED_TICK_MS_PERIOD );
    14371438
     1439    /////////////////////////////////////////////////////////////////////////////////
     1440    if( core_lid == 0 ) xbarrier_wait( XPTR( 0 , &global_barrier ),
     1441                                        (info->x_size * info->y_size) );
     1442    barrier_wait( &local_barrier , info->cores_nr );
     1443    /////////////////////////////////////////////////////////////////////////////////
     1444
    14381445#if DEBUG_KERNEL_INIT
    1439 printk("\n[%s] : thread %x on core[%x,%d] jumps to thread_idle_func() / cycle %d\n",
    1440 __FUNCTION__ , CURRENT_THREAD , local_cxy , core_lid , (uint32_t)hal_get_cycles() );
     1446thread_t * this = CURRENT_THREAD;
     1447printk("\n[%s] : thread[%x,%x] on core[%x,%d] jumps to thread_idle_func() / cycle %d\n",
     1448__FUNCTION__ , this->process->pid, this->trdid,
     1449local_cxy, core_lid, (uint32_t)hal_get_cycles() );
    14411450#endif
    14421451
    14431452    // each core jump to thread_idle_func
    14441453    thread_idle_func();
    1445 }
    1446 
     1454
     1455}  // end kernel_init()
     1456
  • trunk/kernel/kern/process.c

    r593 r610  
    9595                             xptr_t      parent_xp )
    9696{
     97    xptr_t      process_xp;
    9798    cxy_t       parent_cxy;
    9899    process_t * parent_ptr;
     
    113114    pid_t       parent_pid;
    114115
     116    // build extended pointer on this reference process
     117    process_xp = XPTR( local_cxy , process );
     118
    115119    // get parent process cluster and local pointer
    116120    parent_cxy = GET_CXY( parent_xp );
     
    121125
    122126#if DEBUG_PROCESS_REFERENCE_INIT
     127thread_t * this = CURRENT_THREAD;
    123128uint32_t cycle = (uint32_t)hal_get_cycles();
    124 if( DEBUG_PROCESS_REFERENCE_INIT )
    125 printk("\n[%s] thread %x in process %x enter to initalialize process %x / cycle %d\n",
    126 __FUNCTION__, CURRENT_THREAD->trdid, parent_pid , pid , cycle );
    127 #endif
    128 
    129     // initialize PID, REF_XP, PARENT_XP, and STATE
     129if( DEBUG_PROCESS_REFERENCE_INIT < cycle )
     130printk("\n[%s] thread[%x,%x] enter to initalialize process %x / cycle %d\n",
     131__FUNCTION__, parent_pid, this->trdid, pid, cycle );
     132#endif
     133
     134    // initialize pid, ref_xp, parent_xp, owner_xp, term_state fields
    130135        process->pid        = pid;
    131136    process->ref_xp     = XPTR( local_cxy , process );
     
    134139    process->term_state = 0;
    135140
     141    // initialize VFS root inode and CWD inode
     142    process->vfs_root_xp = hal_remote_l64( XPTR( parent_cxy, &parent_ptr->vfs_root_xp ) );
     143    process->cwd_xp      = hal_remote_l64( XPTR( parent_cxy, &parent_ptr->cwd_xp ) );
     144
    136145    // initialize vmm as empty
    137146    error = vmm_init( process );
     
    141150#if (DEBUG_PROCESS_REFERENCE_INIT & 1)
    142151cycle = (uint32_t)hal_get_cycles();
    143 if( DEBUG_PROCESS_REFERENCE_INIT )
    144 printk("\n[%s] thread %x in process %x / vmm empty for process %x / cycle %d\n",
    145 __FUNCTION__, CURRENT_THREAD->trdid, parent_pid , pid, cycle );
     152if( DEBUG_PROCESS_REFERENCE_INIT < cycle )
     153printk("\n[%s] thread[%x,%x] / vmm empty for process %x / cycle %d\n",
     154__FUNCTION__, parent_pid, this->trdid, pid, cycle );
    146155#endif
    147156
     
    161170#if (DEBUG_PROCESS_REFERENCE_INIT & 1)
    162171cycle = (uint32_t)hal_get_cycles();
    163 if( DEBUG_PROCESS_REFERENCE_INIT )
    164 printk("\n[%s] thread %x in process %x / process %x attached to TXT%d / cycle %d\n",
    165 __FUNCTION__, CURRENT_THREAD->trdid, parent_pid, pid, txt_id, cycle );
     172if( DEBUG_PROCESS_REFERENCE_INIT < cycle )
     173printk("\n[%s] thread[%x,%x] / process %x attached to TXT%d / cycle %d\n",
     174__FUNCTION__, parent_pid, this->trdid, pid, txt_id, cycle );
    166175#endif
    167176        // build path to TXT_RX[i] and TXT_TX[i] chdevs
     
    170179
    171180        // create stdin pseudo file         
    172         error = vfs_open( process,
     181        error = vfs_open(  process->vfs_root_xp,
    173182                           rx_path,
     183                           process_xp,
    174184                           O_RDONLY,
    175185                           0,                // FIXME chmod
     
    182192#if (DEBUG_PROCESS_REFERENCE_INIT & 1)
    183193cycle = (uint32_t)hal_get_cycles();
    184 if( DEBUG_PROCESS_REFERENCE_INIT )
    185 printk("\n[%s] thread %x in process %x / stdin open for process %x / cycle %d\n",
    186 __FUNCTION__, CURRENT_THREAD->trdid, parent_pid, pid, cycle );
     194if( DEBUG_PROCESS_REFERENCE_INIT < cycle )
     195printk("\n[%s] thread[%x,%x] / stdin open for process %x / cycle %d\n",
     196__FUNCTION__, parent_pid, this->trdid, pid, cycle );
    187197#endif
    188198
    189199        // create stdout pseudo file         
    190         error = vfs_open( process,
     200        error = vfs_open(  process->vfs_root_xp,
    191201                           tx_path,
     202                           process_xp,
    192203                           O_WRONLY,
    193204                           0,                // FIXME chmod
     
    200211#if (DEBUG_PROCESS_REFERENCE_INIT & 1)
    201212cycle = (uint32_t)hal_get_cycles();
    202 if( DEBUG_PROCESS_REFERENCE_INIT )
    203 printk("\n[%s] thread %x in process %x / stdout open for process %x / cycle %d\n",
    204 __FUNCTION__, CURRENT_THREAD->trdid, parent_pid, pid, cycle );
     213if( DEBUG_PROCESS_REFERENCE_INIT < cycle )
     214printk("\n[%s] thread[%x,%x] / stdout open for process %x / cycle %d\n",
     215__FUNCTION__, parent_pid, this->trdid, pid, cycle );
    205216#endif
    206217
    207218        // create stderr pseudo file         
    208         error = vfs_open( process,
     219        error = vfs_open(  process->vfs_root_xp,
    209220                           tx_path,
     221                           process_xp,
    210222                           O_WRONLY,
    211223                           0,                // FIXME chmod
     
    218230#if (DEBUG_PROCESS_REFERENCE_INIT & 1)
    219231cycle = (uint32_t)hal_get_cycles();
    220 if( DEBUG_PROCESS_REFERENCE_INIT )
    221 printk("\n[%s] thread %x in process %x / stderr open for process %x / cycle %d\n",
    222 __FUNCTION__, CURRENT_THREAD->trdid, parent_pid, pid, cycle );
     232if( DEBUG_PROCESS_REFERENCE_INIT < cycle )
     233printk("\n[%s] thread[%x,%x] / stderr open for process %x / cycle %d\n",
     234__FUNCTION__, parent_pid, this->trdid, pid, cycle );
    223235#endif
    224236
     
    247259    }
    248260
    249     // initialize specific inodes root and cwd
    250     process->vfs_root_xp = (xptr_t)hal_remote_l64( XPTR( parent_cxy,
    251                                                          &parent_ptr->vfs_root_xp ) );
    252     process->vfs_cwd_xp  = (xptr_t)hal_remote_l64( XPTR( parent_cxy,
    253                                                          &parent_ptr->vfs_cwd_xp ) );
    254     vfs_inode_remote_up( process->vfs_root_xp );
    255     vfs_inode_remote_up( process->vfs_cwd_xp );
    256 
    257     remote_rwlock_init( XPTR( local_cxy , &process->cwd_lock ), LOCK_PROCESS_CWD );
     261    // initialize lock protecting CWD changes
     262    remote_busylock_init( XPTR( local_cxy , &process->cwd_lock ), LOCK_PROCESS_CWD );
    258263
    259264#if (DEBUG_PROCESS_REFERENCE_INIT & 1)
    260265cycle = (uint32_t)hal_get_cycles();
    261 if( DEBUG_PROCESS_REFERENCE_INIT )
    262 printk("\n[%s] thread %x in process %x / set fd_array for process %x / cycle %d\n",
    263 __FUNCTION__, CURRENT_THREAD->trdid, parent_pid, pid , cycle );
     266if( DEBUG_PROCESS_REFERENCE_INIT < cycle )
     267printk("\n[%s] thread[%x,%x] / set fd_array for process %x / cycle %d\n",
     268__FUNCTION__, parent_pid, this->trdid, pid , cycle );
    264269#endif
    265270
     
    300305#if (DEBUG_PROCESS_REFERENCE_INIT & 1)
    301306cycle = (uint32_t)hal_get_cycles();
    302 if( DEBUG_PROCESS_REFERENCE_INIT )
    303 printk("\n[%s] thread %x in process %x exit for process %x / cycle %d\n",
    304 __FUNCTION__, CURRENT_THREAD->trdid, parent_pid, pid, cycle );
     307if( DEBUG_PROCESS_REFERENCE_INIT < cycle )
     308printk("\n[%s] thread[%x,%x] exit for process %x / cycle %d\n",
     309__FUNCTION__, parent_pid, this->trdid, pid, cycle );
    305310#endif
    306311
     
    325330
    326331#if DEBUG_PROCESS_COPY_INIT
    327 thread_t * this = CURRET_THREAD; 
     332thread_t * this = CURRENT_THREAD; 
    328333uint32_t cycle = (uint32_t)hal_get_cycles();
    329 if( DEBUG_PROCESS_COPY_INIT )
    330 printk("\n[%s] thread %x in process %x enter for process %x / cycle %d\n",
    331 __FUNCTION__, this->trdid, this->process->pid, local_process->pid, cycle );
     334if( DEBUG_PROCESS_COPY_INIT < cycle )
     335printk("\n[%s] thread[%x,%x] enter for process %x / cycle %d\n",
     336__FUNCTION__, this->process->pid, this->trdid, local_process->pid, cycle );
    332337#endif
    333338
     
    342347        process_fd_init( local_process );
    343348
    344     // reset vfs_root_xp / vfs_bin_xp / vfs_cwd_xp fields
     349    // reset vfs_root_xp / vfs_bin_xp / cwd_xp fields
    345350    local_process->vfs_root_xp = hal_remote_l64( XPTR( ref_cxy , &ref_ptr->vfs_root_xp ) );
    346351    local_process->vfs_bin_xp  = hal_remote_l64( XPTR( ref_cxy , &ref_ptr->vfs_bin_xp ) );
    347     local_process->vfs_cwd_xp  = XPTR_NULL;
     352    local_process->cwd_xp      = XPTR_NULL;
    348353
    349354    // reset children list root (not used in a process descriptor copy)
     
    382387#if DEBUG_PROCESS_COPY_INIT
    383388cycle = (uint32_t)hal_get_cycles();
    384 if( DEBUG_PROCESS_COPY_INIT )
    385 printk("\n[%s] thread %x in process %x exit for process %x / cycle %d\n",
    386 __FUNCTION__, this->trdid, this->process->pid, local_process->pid, cycle );
     389if( DEBUG_PROCESS_COPY_INIT < cycle )
     390printk("\n[%s] thread[%x,%x] exit for process %x / cycle %d\n",
     391__FUNCTION__, this->process->pid, this->trdid, local_process->pid, cycle );
    387392#endif
    388393
     
    406411
    407412#if DEBUG_PROCESS_DESTROY
     413thread_t * this = CURRENT_THREAD;
    408414uint32_t cycle = (uint32_t)hal_get_cycles();
    409 if( DEBUG_PROCESS_DESTROY )
    410 printk("\n[%s] thread %x in process %x enter for process %x in cluster %x / cycle %d\n",
    411 __FUNCTION__, CURRENT_THREAD->trdid, CURRENT_THREAD->process->pid, pid, local_cxy, cycle );
     415if( DEBUG_PROCESS_DESTROY < cycle )
     416printk("\n[%s] thread[%x,%x] enter for process %x in cluster %x / cycle %d\n",
     417__FUNCTION__, this->process->pid, this->trdid, pid, local_cxy, cycle );
    412418#endif
    413419
     
    446452        if( process->vfs_bin_xp  != XPTR_NULL ) vfs_file_count_down( process->vfs_bin_xp );
    447453        if( process->vfs_root_xp != XPTR_NULL ) vfs_file_count_down( process->vfs_root_xp );
    448         if( process->vfs_cwd_xp  != XPTR_NULL ) vfs_file_count_down( process->vfs_cwd_xp );
     454        if( process->cwd_xp      != XPTR_NULL ) vfs_file_count_down( process->cwd_xp );
    449455
    450456    // Destroy VMM
     
    456462#if DEBUG_PROCESS_DESTROY
    457463cycle = (uint32_t)hal_get_cycles();
    458 if( DEBUG_PROCESS_DESTROY )
    459 printk("\n[%s] thread %x in process %x exit / process %x in cluster %x / cycle %d\n",
    460 __FUNCTION__, CURRENT_THREAD->trdid, CURRENT_THREAD->process->pid, pid, local_cxy, cycle );
     464if( DEBUG_PROCESS_DESTROY < cycle )
     465printk("\n[%s] thread[%x,%x] exit / process %x in cluster %x / cycle %d\n",
     466__FUNCTION__, this->process->pid, this->trdid, pid, local_cxy, cycle );
    461467#endif
    462468
     
    561567        process_ptr = GET_PTR( process_xp );
    562568
    563 // printk("\n@@@ in %s : process_cxy %x / process_ptr %x / pid %x\n",
    564 // __FUNCTION__, process_cxy, process_ptr, hal_remote_l32( XPTR( process_cxy , &process_ptr->pid ) ) );
    565 
    566569        if( process_cxy == local_cxy )    // process copy is local
    567570        {
     
    652655assert( (LPID_FROM_PID( process->pid ) != 0 ), "target process must be an user process" );
    653656
    654     // get target process cluster
     657    // get target process owner cluster
    655658    owner_cxy = CXY_FROM_PID( process->pid );
    656659
     
    697700    while( 1 )
    698701    {
    699         // exit when all scheduler acknoledges received
     702        // exit when all scheduler acknowledges received
    700703        if ( ack_count == 0 ) break;
    701704   
     
    927930    uint32_t fd;
    928931
     932    // initialize lock
    929933    remote_queuelock_init( XPTR( local_cxy , &process->fd_array.lock ), LOCK_PROCESS_FDARRAY );
    930934
     935    // initialize number of open files
    931936    process->fd_array.current = 0;
    932937
     
    937942    }
    938943}
    939 /////////////////////////////////////////////////
    940 error_t process_fd_register( process_t * process,
     944////////////////////////////////////////////////////
     945error_t process_fd_register( xptr_t      process_xp,
    941946                             xptr_t      file_xp,
    942947                             uint32_t  * fdid )
     
    944949    bool_t    found;
    945950    uint32_t  id;
    946     uint32_t  count;
    947951    xptr_t    xp;
    948952
    949953    // get reference process cluster and local pointer
    950     xptr_t ref_xp = process->ref_xp;
    951     process_t * ref_ptr = GET_PTR( ref_xp );
    952     cxy_t       ref_cxy = GET_CXY( ref_xp );
     954    process_t * process_ptr = GET_PTR( process_xp );
     955    cxy_t       process_cxy = GET_CXY( process_xp );
     956
     957// check client process is reference process
     958assert( (process_xp == hal_remote_l64( XPTR( process_cxy , &process_ptr->ref_xp ) ) ),
     959"client process must be reference process\n" );
     960
     961#if DEBUG_PROCESS_FD_REGISTER
     962thread_t * this  = CURRENT_THREAD;
     963uint32_t   cycle = (uint32_t)hal_get_cycles();
     964pid_t      pid   = hal_remote_l32( XPTR( process_cxy , &process_ptr->pid) );
     965if( DEBUG_PROCESS_FD_REGISTER < cycle )
     966printk("\n[%s] thread[%x,%x] enter for process %x / cycle %d\n",
     967__FUNCTION__, this->process->pid, this->trdid, pid, cycle );
     968#endif
     969
     970    // build extended pointer on lock protecting reference fd_array
     971    xptr_t lock_xp = XPTR( process_cxy , &process_ptr->fd_array.lock );
    953972
    954973    // take lock protecting reference fd_array
    955         remote_queuelock_acquire( XPTR( ref_cxy , &ref_ptr->fd_array.lock ) );
     974        remote_queuelock_acquire( lock_xp );
    956975
    957976    found   = false;
     
    959978    for ( id = 0; id < CONFIG_PROCESS_FILE_MAX_NR ; id++ )
    960979    {
    961         xp = hal_remote_l64( XPTR( ref_cxy , &ref_ptr->fd_array.array[id] ) );
     980        xp = hal_remote_l64( XPTR( process_cxy , &process_ptr->fd_array.array[id] ) );
    962981        if ( xp == XPTR_NULL )
    963982        {
    964983            // update reference fd_array
    965             hal_remote_s64( XPTR( ref_cxy , &ref_ptr->fd_array.array[id] ) , file_xp );
    966                 count = hal_remote_l32( XPTR( ref_cxy , &ref_ptr->fd_array.current ) ) + 1;
    967             hal_remote_s32( XPTR( ref_cxy , &ref_ptr->fd_array.current ) , count );
    968 
    969             // update local fd_array copy if required
    970             if( ref_cxy != local_cxy )
    971             {
    972                 process->fd_array.array[id] = file_xp;
    973                 process->fd_array.current   = count;
    974             }
     984            hal_remote_s64( XPTR( process_cxy , &process_ptr->fd_array.array[id] ) , file_xp );
     985                hal_remote_atomic_add( XPTR( process_cxy , &process_ptr->fd_array.current ) , 1 );
    975986
    976987            // exit
     
    981992    }
    982993
    983     // release lock protecting reference fd_array
    984         remote_queuelock_release( XPTR( ref_cxy , &ref_ptr->fd_array.lock ) );
     994    // release lock protecting fd_array
     995        remote_queuelock_release( lock_xp );
     996
     997#if DEBUG_PROCESS_FD_REGISTER
     998cycle = (uint32_t)hal_get_cycles();
     999if( DEBUG_PROCESS_FD_REGISTER < cycle )
     1000printk("\n[%s] thread[%x,%x] exit for process %x / fdid %d / cycle %d\n",
     1001__FUNCTION__, this->process->pid, this->trdid, pid, id, cycle );
     1002#endif
    9851003
    9861004    if ( !found ) return -1;
    9871005    else          return 0;
    988 }
     1006
     1007}  // end process_fd_register()
    9891008
    9901009////////////////////////////////////////////////
     
    11191138        // returns trdid
    11201139        *trdid = TRDID( local_cxy , ltid );
    1121 
    1122 // if( LPID_FROM_PID( process->pid ) == 0 )
    1123 // printk("\n@@@ %s : allocate ltid %d for a thread %s in cluster %x\n",
    1124 // __FUNCTION__, ltid, thread_type_str( thread->type), local_cxy );
    1125 
    11261140    }
    11271141
     
    11581172    process->th_tbl[ltid] = NULL;
    11591173    process->th_nr = count-1;
    1160 
    1161 // if( LPID_FROM_PID( process->pid ) == 0 )
    1162 // printk("\n@@@ %s : release ltid %d for a thread %s in cluster %x\n",
    1163 // __FUNCTION__, ltid, thread_type_str( thread->type), local_cxy );
    11641174
    11651175    // release lock protecting th_tbl
     
    13631373    process_t      * process;                 // local pointer on this process
    13641374    pid_t            pid;                     // this process identifier
     1375    xptr_t           ref_xp;                  // reference process for this process
    13651376        error_t          error;                   // value returned by called functions
    13661377    char           * path;                    // path to .elf file
     
    13701381    char          ** args_pointers;           // array of pointers on main thread arguments
    13711382
    1372     // get thread, process & PID
     1383    // get thread, process, pid and ref_xp
    13731384    thread  = CURRENT_THREAD;
    13741385    process = thread->process;
    13751386    pid     = process->pid;
     1387    ref_xp  = process->ref_xp;
    13761388
    13771389        // get relevant infos from exec_info
     
    13901402    file_xp = XPTR_NULL;
    13911403    file_id = 0xFFFFFFFF;
    1392         error   = vfs_open( process,
     1404        error   = vfs_open( process->vfs_root_xp,
    13931405                            path,
     1406                        ref_xp,
    13941407                            O_RDONLY,
    13951408                            0,
     
    15431556#endif
    15441557
    1545 }  // end process_zero_init()
     1558}  // end process_zero_create()
    15461559
    15471560////////////////////////////////
     
    15581571
    15591572#if DEBUG_PROCESS_INIT_CREATE
     1573thread_t * this = CURRENT_THREAD;
    15601574uint32_t cycle = (uint32_t)hal_get_cycles();
    15611575if( DEBUG_PROCESS_INIT_CREATE < cycle )
    1562 printk("\n[%s] thread %x in process %x enter / cycle %d\n",
    1563 __FUNCTION__, CURRENT_THREAD->trdid, CURRENT_THREAD->process->pid, cycle );
     1576printk("\n[%s] thread[%x,%x] enter / cycle %d\n",
     1577__FUNCTION__, this->process->pid, this->trdid, cycle );
    15641578#endif
    15651579
     
    15711585"no memory for process descriptor in cluster %x\n", local_cxy  );
    15721586
     1587    // set the CWD and VFS_ROOT fields in process descriptor
     1588    process->cwd_xp      = process_zero.vfs_root_xp;
     1589    process->vfs_root_xp = process_zero.vfs_root_xp;
     1590
    15731591    // get PID from local cluster
    15741592    error = cluster_pid_alloc( process , &pid );
     
    15891607#if(DEBUG_PROCESS_INIT_CREATE & 1)
    15901608if( DEBUG_PROCESS_INIT_CREATE < cycle )
    1591 printk("\n[%s] thread %x in process %x initialized process descriptor\n",
    1592 __FUNCTION__, CURRENT_THREAD->trdid, CURRENT_THREAD->process->pid );
     1609printk("\n[%s] thread[%x,%x] initialized process descriptor\n",
     1610__FUNCTION__, this->process->pid, this->trdid );
    15931611#endif
    15941612
     
    15961614    file_xp = XPTR_NULL;
    15971615    file_id = -1;
    1598         error   = vfs_open( process,
     1616        error   = vfs_open( process->vfs_root_xp,
    15991617                            CONFIG_PROCESS_INIT_PATH,
     1618                        XPTR( local_cxy , process ),
    16001619                            O_RDONLY,
    16011620                            0,
     
    16081627#if(DEBUG_PROCESS_INIT_CREATE & 1)
    16091628if( DEBUG_PROCESS_INIT_CREATE < cycle )
    1610 printk("\n[%s] thread %x in process %x open .elf file decriptor\n",
    1611 __FUNCTION__, CURRENT_THREAD->trdid, CURRENT_THREAD->process->pid );
     1629printk("\n[%s] thread[%x,%x] open .elf file decriptor\n",
     1630__FUNCTION__, this->process->pid, this->trdid );
    16121631#endif
    16131632
     
    16211640#if(DEBUG_PROCESS_INIT_CREATE & 1)
    16221641if( DEBUG_PROCESS_INIT_CREATE < cycle )
    1623 printk("\n[%s] thread %x in process %x registered code/data vsegs in VMM\n",
    1624 __FUNCTION__, CURRENT_THREAD->trdid, CURRENT_THREAD->process->pid );
     1642printk("\n[%s] thread[%x,%x] registered code/data vsegs in VMM\n",
     1643__FUNCTION__, this->process->pid, this->trdid );
    16251644#endif
    16261645
     
    16411660#if(DEBUG_PROCESS_INIT_CREATE & 1)
    16421661if( DEBUG_PROCESS_INIT_CREATE < cycle )
    1643 printk("\n[%s] thread %x in process %x registered init process in parent\n",
    1644 __FUNCTION__, CURRENT_THREAD->trdid, CURRENT_THREAD->process->pid );
     1662printk("\n[%s] thread[%x,%x] registered init process in parent\n",
     1663__FUNCTION__, this->process->pid, this->trdid );
    16451664#endif
    16461665
     
    16681687#if(DEBUG_PROCESS_INIT_CREATE & 1)
    16691688if( DEBUG_PROCESS_INIT_CREATE < cycle )
    1670 printk("\n[%s] thread %x in process %x created main thread\n",
    1671 __FUNCTION__, CURRENT_THREAD->trdid, CURRENT_THREAD->process->pid );
     1689printk("\n[%s] thread[%x,%x] created main thread\n",
     1690__FUNCTION__, this->process->pid, this->trdid );
    16721691#endif
    16731692
     
    16801699cycle = (uint32_t)hal_get_cycles();
    16811700if( DEBUG_PROCESS_INIT_CREATE < cycle )
    1682 printk("\n[%s] thread %x in process %x exit / cycle %d\n",
    1683 __FUNCTION__, CURRENT_THREAD->trdid, CURRENT_THREAD->process->pid, cycle );
     1701printk("\n[%s] thread[%x,%x] exit / cycle %d\n",
     1702__FUNCTION__, this->process->pid, this->trdid, cycle );
    16841703#endif
    16851704
     
    18651884
    18661885#if DEBUG_PROCESS_TXT
     1886thread_t * this = CURRENT_THREAD;
    18671887uint32_t cycle = (uint32_t)hal_get_cycles();
    18681888if( DEBUG_PROCESS_TXT < cycle )
    1869 printk("\n[%s] thread %x in process %x attached process %x to TXT %d / cycle %d\n",
    1870 __FUNCTION__, CURRENT_THREAD->trdid, CURRENT_THREAD->process->pid,
    1871 process->pid, txt_id , cycle );
     1889printk("\n[%s] thread[%x,%x] attached process %x to TXT %d / cycle %d\n",
     1890__FUNCTION__, this->process->pid, this->trdid, process->pid, txt_id , cycle );
    18721891#endif
    18731892
     
    19191938
    19201939#if DEBUG_PROCESS_TXT
     1940thread_t * this = CURRENT_THREAD;
    19211941uint32_t cycle  = (uint32_t)hal_get_cycles();
    19221942uint32_t txt_id = hal_remote_l32( XPTR( chdev_cxy , &chdev_ptr->channel ) );
    19231943if( DEBUG_PROCESS_TXT < cycle )
    1924 printk("\n[%s] thread %x in process %x detached process %x from TXT %d / cycle %d\n",
    1925 __FUNCTION__, CURRENT_THREAD->trdid, CURRENT_THREAD->process->pid,
    1926 process_pid, txt_id, cycle );
     1944printk("\n[%s] thread[%x,%x] detached process %x from TXT %d / cycle %d\n",
     1945__FUNCTION__, this->process->pid, this->trdid, process_pid, txt_id, cycle );
    19271946#endif
    19281947
     
    19611980
    19621981#if DEBUG_PROCESS_TXT
     1982thread_t * this = CURRENT_THREAD;
    19631983uint32_t cycle  = (uint32_t)hal_get_cycles();
    19641984uint32_t txt_id = hal_remote_l32( XPTR( txt_cxy , &txt_ptr->channel ) );
    19651985if( DEBUG_PROCESS_TXT < cycle )
    1966 printk("\n[%s] thread %x in process %x give TXT %d to process %x / cycle %d\n",
    1967 __FUNCTION__, CURRENT_THREAD->trdid, CURRENT_THREAD->process->pid, txt_id, process_pid, cycle );
     1986printk("\n[%s] thread[%x,%x] give TXT %d to process %x / cycle %d\n",
     1987__FUNCTION__, this->process->pid, this->trdid, txt_id, process_pid, cycle );
    19681988#endif
    19691989
     
    19902010
    19912011#if DEBUG_PROCESS_TXT
    1992 uint32_t cycle;
     2012thread_t * this  = CURRENT_THREAD;
     2013uint32_t   cycle;
    19932014#endif
    19942015
     
    20422063
    20432064#if DEBUG_PROCESS_TXT
    2044 cycle   = (uint32_t)hal_get_cycles();
     2065cycle = (uint32_t)hal_get_cycles();
    20452066uint32_t ksh_pid = hal_remote_l32( XPTR( current_cxy , &current_ptr->pid ) );
    20462067if( DEBUG_PROCESS_TXT < cycle )
    2047 printk("\n[%s] thread %x in process %x release TXT %d to KSH %x / cycle %d\n",
    2048 __FUNCTION__, CURRENT_THREAD->trdid, CURRENT_THREAD->process->pid, txt_id, ksh_pid, cycle );
     2068printk("\n[%s] thread[%x,%x] release TXT %d to KSH %x / cycle %d\n",
     2069__FUNCTION__, this->process->pid, this->trdid, txt_id, ksh_pid, cycle );
    20492070process_txt_display( txt_id );
    20502071#endif
     
    20792100
    20802101#if DEBUG_PROCESS_TXT
    2081 cycle   = (uint32_t)hal_get_cycles();
     2102cycle  = (uint32_t)hal_get_cycles();
    20822103uint32_t new_pid = hal_remote_l32( XPTR( current_cxy , &current_ptr->pid ) );
    20832104if( DEBUG_PROCESS_TXT < cycle )
    2084 printk("\n[%s] thread %x in process %x release TXT %d to process %x / cycle %d\n",
    2085 __FUNCTION__, CURRENT_THREAD->trdid, CURRENT_THREAD->process->pid, txt_id, new_pid, cycle );
     2105printk("\n[%s] thread[%x,%x] release TXT %d to process %x / cycle %d\n",
     2106__FUNCTION__,this->process->pid, this->trdid, txt_id, new_pid, cycle );
    20862107process_txt_display( txt_id );
    20872108#endif
     
    20992120cycle = (uint32_t)hal_get_cycles();
    21002121if( DEBUG_PROCESS_TXT < cycle )
    2101 printk("\n[%s] thread %x in process %x release TXT %d to nobody / cycle %d\n",
    2102 __FUNCTION__, CURRENT_THREAD->trdid, CURRENT_THREAD->process->pid, txt_id, cycle );
     2122printk("\n[%s] thread[%x,%x] release TXT %d to nobody / cycle %d\n",
     2123__FUNCTION__, this->process->pid, this->trdid, txt_id, cycle );
    21032124process_txt_display( txt_id );
    21042125#endif
     
    21132134if( DEBUG_PROCESS_TXT < cycle )
    21142135printk("\n[%s] thread %x in process %d does nothing (not TXT owner) / cycle %d\n",
    2115 __FUNCTION__, CURRENT_THREAD->trdid, process_pid, cycle );
     2136__FUNCTION__, this->trdid, process_pid, cycle );
    21162137process_txt_display( txt_id );
    21172138#endif
  • trunk/kernel/kern/process.h

    r601 r610  
    125125        fd_array_t         fd_array;         /*! embedded open file descriptors array            */
    126126
    127         xptr_t             vfs_root_xp;      /*! extended pointer on current VFS root inode      */
     127        xptr_t             vfs_root_xp;      /*! extended pointer on VFS root inode              */
    128128        xptr_t             vfs_bin_xp;       /*! extended pointer on .elf file descriptor        */
    129129        pid_t              pid;              /*! process identifier                              */
     
    132132    xptr_t             parent_xp;        /*! extended pointer on parent process              */
    133133
    134         xptr_t             vfs_cwd_xp;       /*! extended pointer on current working dir inode   */
    135         remote_rwlock_t    cwd_lock;         /*! lock protecting working directory changes       */
     134        xptr_t             cwd_xp;           /*! extended pointer on current working dir inode   */
     135        remote_busylock_t  cwd_lock;         /*! lock protecting working directory changes       */
    136136
    137137        xlist_entry_t      children_root;    /*! root of the children process xlist              */
     
    338338 * It scan the list of local thread, and sets the THREAD_BLOCKED_GLOBAL bit for all threads.
    339339 * It request the relevant schedulers to acknowledge the blocking, using IPI if required,
    340  * and returns only when all threads in cluster, but the calling thread, are actually blocked.
     340 * when the target thread is running on another core than the calling thread.
     341 * It returns only when all threads in cluster, including the caller are actually blocked.
    341342 * The threads are not detached from the scheduler, and not detached from the local process.
    342343 *********************************************************************************************
     
    425426
    426427/*********************************************************************************************
    427  * This function allocates a free slot in the fd_array of the reference process,
    428  * register the <file_xp> argument in the allocated slot, and return the slot index.
     428 * This function allocates a free slot in the fd_array of the reference process
     429 * identified by the <process_xp> argument, register the <file_xp> argument in the
     430 * allocated slot, and return the slot index in the <fdid> buffer.
    429431 * It can be called by any thread in any cluster, because it uses portable remote access
    430432 * primitives to access the reference process descriptor.
    431433 * It takes the lock protecting the reference fd_array against concurrent accesses.
    432434 *********************************************************************************************
    433  * @ file_xp  : extended pointer on the file descriptor to be registered.
    434  * @ fdid     : [out] buffer for fd_array slot index.
     435 * @ process_xp : [in]  extended pointer on client reference process.
     436 * @ file_xp    : [in]  extended pointer on the file descriptor to be registered.
     437 * @ fdid       : [out] buffer for fd_array slot index.
    435438 * @ return 0 if success / return EMFILE if array full.
    436439 ********************************************************************************************/
    437 error_t process_fd_register( process_t * process,
     440error_t process_fd_register( xptr_t      process_xp,
    438441                             xptr_t      file_xp,
    439442                             uint32_t  * fdid );
     
    447450 * TODO this function is not implemented yet.
    448451 *********************************************************************************************
    449  * @ process  : pointer on the local process descriptor.
    450  * @ fdid     : file descriptor index in the fd_array.
     452 * @ process  : [in] pointer on the local process descriptor.
     453 * @ fdid     : [in] file descriptor index in the fd_array.
    451454 ********************************************************************************************/
    452455void process_fd_remove( process_t * process,
  • trunk/kernel/kern/rpc.c

    r601 r610  
    7575    &rpc_kcm_alloc_server,                 // 22
    7676    &rpc_kcm_free_server,                  // 23
    77     &rpc_mapper_move_user_server,          // 24
     77    &rpc_undefined,                        // 24   unused slot
    7878    &rpc_mapper_handle_miss_server,        // 25
    7979    &rpc_undefined,                        // 26   unused slot
     
    111111    "KCM_ALLOC",                 // 22
    112112    "KCM_FREE",                  // 23
    113     "MAPPER_MOVE_USER",          // 24
     113    "undefined",                 // 24
    114114    "MAPPER_HANDLE_MISS",        // 25
    115115    "undefined",                 // 26
     
    302302uint32_t cycle = (uint32_t)hal_get_cycles();
    303303if( DEBUG_RPC_SERVER_GENERIC < cycle )
    304 printk("\n[DBG] %s : RPC thread %x on core[%d] takes RPC_FIFO ownership / cycle %d\n",
     304printk("\n[%s] RPC thread %x on core[%d] takes RPC_FIFO ownership / cycle %d\n",
    305305__FUNCTION__, server_ptr->trdid, server_core_lid, cycle );
    306306#endif
     
    318318                desc_ptr = GET_PTR( desc_xp );
    319319
    320                     index    = hal_remote_l32( XPTR( desc_cxy , &desc_ptr->index ) );
    321                 blocking = hal_remote_l32( XPTR( desc_cxy , &desc_ptr->blocking ) );
     320                    index      = hal_remote_l32( XPTR( desc_cxy , &desc_ptr->index ) );
     321                blocking   = hal_remote_l32( XPTR( desc_cxy , &desc_ptr->blocking ) );
     322                client_ptr = hal_remote_lpt( XPTR( desc_cxy , &desc_ptr->thread ) );
    322323
    323324#if DEBUG_RPC_SERVER_GENERIC
     
    325326uint32_t items = remote_fifo_items( XPTR( local_cxy , rpc_fifo ) );
    326327if( DEBUG_RPC_SERVER_GENERIC < cycle )
    327 printk("\n[DBG] %s : RPC thread %x got rpc %s / client_cxy %x / items %d / cycle %d\n",
     328printk("\n[%s] RPC thread %x got rpc %s / client_cxy %x / items %d / cycle %d\n",
    328329__FUNCTION__, server_ptr->trdid, rpc_str[index], desc_cxy, items, cycle );
    329330#endif
     331                // register client thread in RPC thread descriptor
     332                server_ptr->rpc_client_xp = XPTR( desc_cxy , client_ptr );
     333 
    330334                // call the relevant server function
    331335                rpc_server[index]( desc_xp );
     
    334338cycle = (uint32_t)hal_get_cycles();
    335339if( DEBUG_RPC_SERVER_GENERIC < cycle )
    336 printk("\n[DBG] %s : RPC thread %x completes rpc %s / client_cxy %x / cycle %d\n",
     340printk("\n[%s] RPC thread %x completes rpc %s / client_cxy %x / cycle %d\n",
    337341__FUNCTION__, server_ptr->trdid, rpc_str[index], desc_cxy, cycle );
    338342#endif
     
    355359cycle = (uint32_t)hal_get_cycles();
    356360if( DEBUG_RPC_SERVER_GENERIC < cycle )
    357 printk("\n[DBG] %s : RPC thread %x unblocked client thread %x / cycle %d\n",
     361printk("\n[%s] RPC thread %x unblocked client thread %x / cycle %d\n",
    358362__FUNCTION__, server_ptr->trdid, client_ptr->trdid, cycle );
    359363#endif
     
    372376uint32_t cycle = (uint32_t)hal_get_cycles();
    373377if( DEBUG_RPC_SERVER_GENERIC < cycle )
    374 printk("\n[DBG] %s : RPC thread %x suicides / cycle %d\n",
     378printk("\n[%s] RPC thread %x suicides / cycle %d\n",
    375379__FUNCTION__, server_ptr->trdid, cycle );
    376380#endif
     
    391395uint32_t cycle = (uint32_t)hal_get_cycles();
    392396if( DEBUG_RPC_SERVER_GENERIC < cycle )
    393 printk("\n[DBG] %s : RPC thread %x block IDLE & deschedules / cycle %d\n",
     397printk("\n[%s] RPC thread %x block IDLE & deschedules / cycle %d\n",
    394398__FUNCTION__, server_ptr->trdid, cycle );
    395399#endif
     
    870874uint32_t  action = rpc->args[0];
    871875pid_t     pid    = rpc->args[1];
     876thread_t * this = CURRENT_THREAD;
    872877if( DEBUG_RPC_PROCESS_SIGACTION < cycle )
    873 printk("\n[DBG] %s : enter to request %s of process %x in cluster %x / cycle %d\n",
    874 __FUNCTION__ , process_action_str( action ) , pid , cxy , cycle );
     878printk("\n[%s] thread[%x,%x] enter to request %s of process %x in cluster %x / cycle %d\n",
     879__FUNCTION__, this->process->pid, this->trdid, process_action_str(action), pid, cxy, cycle );
    875880#endif
    876881
     
    885890cycle = (uint32_t)hal_get_cycles();
    886891if( DEBUG_RPC_PROCESS_SIGACTION < cycle )
    887 printk("\n[DBG] %s : exit after requesting to %s process %x in cluster %x / cycle %d\n",
    888 __FUNCTION__ , process_action_str( action ) , pid , cxy , cycle );
     892printk("\n[%s] thread[%x,%x] requested %s of process %x in cluster %x / cycle %d\n",
     893__FUNCTION__, this->process->pid, this->trdid, process_action_str(action), pid, cxy, cycle );
    889894#endif
    890895
     
    915920#if DEBUG_RPC_PROCESS_SIGACTION
    916921uint32_t cycle = (uint32_t)hal_get_cycles();
     922thread_t * this = CURRENT_THREAD;
    917923if( DEBUG_RPC_PROCESS_SIGACTION < cycle )
    918 printk("\n[DBG] %s : enter to %s process %x in cluster %x / cycle %d\n",
    919 __FUNCTION__ , process_action_str( action ) , pid , local_cxy , cycle );
     924printk("\n[%s] thread[%x,%x] enter to %s process %x in cluster %x / cycle %d\n",
     925__FUNCTION__, this->process->pid, this->trdid,
     926process_action_str( action ), pid, local_cxy, cycle );
    920927#endif
    921928
     
    954961cycle = (uint32_t)hal_get_cycles();
    955962if( DEBUG_RPC_PROCESS_SIGACTION < cycle )
    956 printk("\n[DBG] %s : exit after %s process %x in cluster %x / cycle %d\n",
    957 __FUNCTION__ , process_action_str( action ) , pid , local_cxy , cycle );
     963printk("\n[%s] thread[%x,%x] exit after %s process %x in cluster %x / cycle %d\n",
     964__FUNCTION__, this->process->pid, this->trdid,
     965process_action_str( action ), pid, local_cxy, cycle );
    958966#endif
    959967
     
    966974/////////////////////////////////////////////////////
    967975void rpc_vfs_inode_create_client( cxy_t          cxy,     
    968                                   xptr_t         dentry_xp,  // in
    969976                                  uint32_t       fs_type,    // in
    970977                                  uint32_t       inode_type, // in
     
    9931000
    9941001    // set input arguments in RPC descriptor
    995     rpc.args[0] = (uint64_t)dentry_xp;
    996     rpc.args[1] = (uint64_t)fs_type;
    997     rpc.args[2] = (uint64_t)inode_type;
    998     rpc.args[3] = (uint64_t)attr;
    999     rpc.args[4] = (uint64_t)rights;
    1000     rpc.args[5] = (uint64_t)uid;
    1001     rpc.args[6] = (uint64_t)gid;
     1002    rpc.args[0] = (uint64_t)fs_type;
     1003    rpc.args[1] = (uint64_t)inode_type;
     1004    rpc.args[2] = (uint64_t)attr;
     1005    rpc.args[3] = (uint64_t)rights;
     1006    rpc.args[4] = (uint64_t)uid;
     1007    rpc.args[5] = (uint64_t)gid;
    10021008
    10031009    // register RPC request in remote RPC fifo
     
    10051011
    10061012    // get output values from RPC descriptor
    1007     *inode_xp = (xptr_t)rpc.args[7];
    1008     *error    = (error_t)rpc.args[8];
     1013    *inode_xp = (xptr_t)rpc.args[6];
     1014    *error    = (error_t)rpc.args[7];
    10091015
    10101016#if DEBUG_RPC_VFS_INODE_CREATE
     
    10271033#endif
    10281034
    1029     xptr_t           dentry_xp;
    10301035    uint32_t         fs_type;
    10311036    uint32_t         inode_type;
     
    10421047
    10431048    // get input arguments from client rpc descriptor
    1044     dentry_xp  = (xptr_t)    hal_remote_l64( XPTR( client_cxy , &desc->args[0] ) );
    1045     fs_type    = (uint32_t)  hal_remote_l64( XPTR( client_cxy , &desc->args[1] ) );
    1046     inode_type = (uint32_t)  hal_remote_l64( XPTR( client_cxy , &desc->args[2] ) );
    1047     attr       = (uint32_t)  hal_remote_l64( XPTR( client_cxy , &desc->args[3] ) );
    1048     rights     = (uint32_t)  hal_remote_l64( XPTR( client_cxy , &desc->args[4] ) );
    1049     uid        = (uid_t)     hal_remote_l64( XPTR( client_cxy , &desc->args[5] ) );
    1050     gid        = (gid_t)     hal_remote_l64( XPTR( client_cxy , &desc->args[6] ) );
     1049    fs_type    = (uint32_t)  hal_remote_l64( XPTR( client_cxy , &desc->args[0] ) );
     1050    inode_type = (uint32_t)  hal_remote_l64( XPTR( client_cxy , &desc->args[1] ) );
     1051    attr       = (uint32_t)  hal_remote_l64( XPTR( client_cxy , &desc->args[2] ) );
     1052    rights     = (uint32_t)  hal_remote_l64( XPTR( client_cxy , &desc->args[3] ) );
     1053    uid        = (uid_t)     hal_remote_l64( XPTR( client_cxy , &desc->args[4] ) );
     1054    gid        = (gid_t)     hal_remote_l64( XPTR( client_cxy , &desc->args[5] ) );
    10511055
    10521056    // call local kernel function
    1053     error = vfs_inode_create( dentry_xp,
    1054                               fs_type,
     1057    error = vfs_inode_create( fs_type,
    10551058                              inode_type,
    10561059                              attr,
     
    10611064
    10621065    // set output arguments
    1063     hal_remote_s64( XPTR( client_cxy , &desc->args[7] ) , (uint64_t)inode_xp );
    1064     hal_remote_s64( XPTR( client_cxy , &desc->args[8] ) , (uint64_t)error );
     1066    hal_remote_s64( XPTR( client_cxy , &desc->args[6] ) , (uint64_t)inode_xp );
     1067    hal_remote_s64( XPTR( client_cxy , &desc->args[7] ) , (uint64_t)error );
    10651068
    10661069#if DEBUG_RPC_VFS_INODE_CREATE
     
    11491152                                   uint32_t               type,         // in
    11501153                                   char                 * name,         // in
    1151                                    struct vfs_inode_s   * parent,       // in
    11521154                                   xptr_t               * dentry_xp,    // out
    11531155                                   error_t              * error )       // out
     
    11721174    rpc.args[0] = (uint64_t)type;
    11731175    rpc.args[1] = (uint64_t)(intptr_t)name;
    1174     rpc.args[2] = (uint64_t)(intptr_t)parent;
    11751176
    11761177    // register RPC request in remote RPC fifo
     
    11781179
    11791180    // get output values from RPC descriptor
    1180     *dentry_xp = (xptr_t)rpc.args[3];
    1181     *error     = (error_t)rpc.args[4];
     1181    *dentry_xp = (xptr_t)rpc.args[2];
     1182    *error     = (error_t)rpc.args[3];
    11821183
    11831184#if DEBUG_RPC_VFS_DENTRY_CREATE
     
    12021203    uint32_t      type;
    12031204    char        * name;
    1204     vfs_inode_t * parent;
    12051205    xptr_t        dentry_xp;
    12061206    error_t       error;
     
    12121212
    12131213    // get arguments "name", "type", and "parent" from client RPC descriptor
    1214     type   = (uint32_t)               hal_remote_l64( XPTR( client_cxy , &desc->args[0] ) );
    1215     name   = (char *)(intptr_t)       hal_remote_l64( XPTR( client_cxy , &desc->args[1] ) );
    1216     parent = (vfs_inode_t *)(intptr_t)hal_remote_l64( XPTR( client_cxy , &desc->args[2] ) );
     1214    type   = (uint32_t)         hal_remote_l64( XPTR( client_cxy , &desc->args[0] ) );
     1215    name   = (char *)(intptr_t) hal_remote_l64( XPTR( client_cxy , &desc->args[1] ) );
    12171216
    12181217    // makes a local copy of  name
     
    12231222    error = vfs_dentry_create( type,
    12241223                               name_copy,
    1225                                parent,
    12261224                               &dentry_xp );
    12271225    // set output arguments
    1228     hal_remote_s64( XPTR( client_cxy , &desc->args[3] ) , (uint64_t)dentry_xp );
    1229     hal_remote_s64( XPTR( client_cxy , &desc->args[4] ) , (uint64_t)error );
     1226    hal_remote_s64( XPTR( client_cxy , &desc->args[2] ) , (uint64_t)dentry_xp );
     1227    hal_remote_s64( XPTR( client_cxy , &desc->args[3] ) , (uint64_t)error );
    12301228
    12311229#if DEBUG_RPC_VFS_DENTRY_CREATE
     
    21122110
    21132111/////////////////////////////////////////////////////////////////////////////////////////
    2114 // [24]          Marshaling functions attached to RPC_MAPPER_MOVE_USER 
    2115 /////////////////////////////////////////////////////////////////////////////////////////
    2116 
    2117 /////////////////////////////////////////////////
    2118 void rpc_mapper_move_user_client( cxy_t      cxy,
    2119                                   mapper_t * mapper,        // in
    2120                                   bool_t     to_buffer,     // in
    2121                                   uint32_t   file_offset,   // in
    2122                                   void     * buffer,        // in
    2123                                   uint32_t   size,          // in
    2124                                   error_t  * error )        // out
    2125 {
    2126 #if DEBUG_RPC_MAPPER_MOVE_USER
    2127 uint32_t cycle = (uint32_t)hal_get_cycles();
    2128 if( cycle > DEBUG_RPC_MAPPER_MOVE_USER )
    2129 printk("\n[%s] thread[%x,%x] on core %d enter / cycle %d\n",
    2130 __FUNCTION__, this->process->pid, this->trdid, this->core->lid , cycle );
    2131 #endif
    2132 
    2133     assert( (cxy != local_cxy) , "target cluster is not remote\n");
    2134 
    2135     // initialise RPC descriptor header
    2136     rpc_desc_t  rpc;
    2137     rpc.index    = RPC_MAPPER_MOVE_USER;
    2138     rpc.blocking = true;
    2139     rpc.responses = 1;
    2140 
    2141     // set input arguments in RPC descriptor
    2142     rpc.args[0] = (uint64_t)(intptr_t)mapper;
    2143     rpc.args[1] = (uint64_t)to_buffer;
    2144     rpc.args[2] = (uint64_t)file_offset;
    2145     rpc.args[3] = (uint64_t)(intptr_t)buffer;
    2146     rpc.args[4] = (uint64_t)size;
    2147 
    2148     // register RPC request in remote RPC fifo
    2149     rpc_send( cxy , &rpc );
    2150 
    2151     // get output values from RPC descriptor
    2152     *error     = (error_t)rpc.args[5];
    2153 
    2154 #if DEBUG_RPC_MAPPER_MOVE_USER
    2155 cycle = (uint32_t)hal_get_cycles();
    2156 if( cycle > DEBUG_RPC_MAPPER_MOVE_USER )
    2157 printk("\n[%s] thread[%x,%x] on core %d exit / cycle %d\n",
    2158 __FUNCTION__, this->process->pid, this->trdid, this->core->lid , cycle );
    2159 #endif
    2160 }
    2161 
    2162 /////////////////////////////////////////////
    2163 void rpc_mapper_move_user_server( xptr_t xp )
    2164 {
    2165 #if DEBUG_RPC_MAPPER_MOVE_USER
    2166 uint32_t cycle = (uint32_t)hal_get_cycles();
    2167 if( cycle > DEBUG_RPC_MAPPER_MOVE_USER )
    2168 printk("\n[%s] thread[%x,%x] on core %d enter / cycle %d\n",
    2169 __FUNCTION__, this->process->pid, this->trdid, this->core->lid , cycle );
    2170 #endif
    2171 
    2172     mapper_t * mapper;
    2173     bool_t     to_buffer;
    2174     uint32_t   file_offset;
    2175     void     * buffer;
    2176     uint32_t   size;
    2177     error_t    error;
    2178 
    2179     // get client cluster identifier and pointer on RPC descriptor
    2180     cxy_t        client_cxy  = GET_CXY( xp );
    2181     rpc_desc_t * desc        = GET_PTR( xp );
    2182 
    2183     // get arguments from client RPC descriptor
    2184     mapper      = (mapper_t *)(intptr_t)hal_remote_l64( XPTR( client_cxy , &desc->args[0] ) );
    2185     to_buffer   =                       hal_remote_l64( XPTR( client_cxy , &desc->args[1] ) );
    2186     file_offset =                       hal_remote_l64( XPTR( client_cxy , &desc->args[2] ) );
    2187     buffer      = (void *)(intptr_t)    hal_remote_l64( XPTR( client_cxy , &desc->args[3] ) );
    2188     size        =                       hal_remote_l64( XPTR( client_cxy , &desc->args[4] ) );
    2189 
    2190     // call local kernel function
    2191     error = mapper_move_user( mapper,
    2192                               to_buffer,
    2193                               file_offset,
    2194                               buffer,
    2195                               size );
    2196 
    2197     // set output argument to client RPC descriptor
    2198     hal_remote_s64( XPTR( client_cxy , &desc->args[6] ) , (uint64_t)error );
    2199 
    2200 #if DEBUG_RPC_MAPPER_MOVE_USER
    2201 cycle = (uint32_t)hal_get_cycles();
    2202 if( cycle > DEBUG_RPC_MAPPER_MOVE_USER )
    2203 printk("\n[%s] thread[%x,%x] on core %d exit / cycle %d\n",
    2204 __FUNCTION__, this->process->pid, this->trdid, this->core->lid , cycle );
    2205 #endif
    2206 }
     2112// [24]          undefined slot
     2113/////////////////////////////////////////////////////////////////////////////////////////
    22072114
    22082115/////////////////////////////////////////////////////////////////////////////////////////
     
    22802187
    22812188    // set output argument to client RPC descriptor
    2282     hal_remote_s64( XPTR( client_cxy , &desc->args[2] ) , (uint64_t)error );
    2283     hal_remote_s64( XPTR( client_cxy , &desc->args[3] ) , (uint64_t)page_xp );
     2189    hal_remote_s64( XPTR( client_cxy , &desc->args[2] ) , (uint64_t)page_xp );
     2190    hal_remote_s64( XPTR( client_cxy , &desc->args[3] ) , (uint64_t)error );
    22842191
    22852192#if DEBUG_RPC_MAPPER_HANDLE_MISS
  • trunk/kernel/kern/rpc.h

    r601 r610  
    7777    RPC_VFS_FILE_DESTROY          = 15,
    7878    RPC_VFS_FS_CHILD_INIT         = 16,
    79     RPC_VFS_FS_REMOVE_DENTRY      = 17,
    80     RPC_VFS_FS_ADD_DENTRY         = 18,
     79    RPC_VFS_FS_ADD_DENTRY         = 17,
     80    RPC_VFS_FS_REMOVE_DENTRY      = 18,
    8181    RPC_VFS_INODE_LOAD_ALL_PAGES  = 19,
    8282
     
    8585    RPC_KCM_ALLOC                 = 22,
    8686    RPC_KCM_FREE                  = 23,
    87     RPC_MAPPER_MOVE_USER          = 24,
     87    RPC_UNDEFINED_24              = 24,
    8888    RPC_MAPPER_HANDLE_MISS        = 25,
    8989    RPC_UNDEFINED_26              = 26,
     
    307307 ***********************************************************************************
    308308 * @ cxy        :  server cluster identifier.
    309  * @ dentry_xp  : [in]  extended pointer on parent dentry.
    310309 * @ fs_type    : [in]  file system type.
    311310 * @ inode_type : [in]  file system type.
     
    318317 **********************************************************************************/
    319318void rpc_vfs_inode_create_client( cxy_t      cxy,
    320                                   xptr_t     dentry_xp,
    321319                                  uint32_t   fs_type,
    322320                                  uint32_t   inode_type,
     
    349347 * @ type       : [in]  file system type.
    350348 * @ name       : [in]  directory entry name.
    351  * @ parent     : [in]  local pointer on parent inode.
    352349 * @ dentry_xp  : [out] buffer for extended pointer on created dentry.
    353350 * @ error      : [out] error status (0 if success).
     
    356353                                   uint32_t               type,
    357354                                   char                 * name,   
    358                                    struct vfs_inode_s   * parent,
    359355                                   xptr_t               * dentry_xp,
    360356                                   error_t              * error );
     
    546542
    547543/***********************************************************************************
    548  * [24] The RPC_MAPPER_MOVE_USER allows a client thread to require a remote
    549  * mapper to move data to/from a distributed user buffer.
    550  * It is used by the vfs_move_user() function to move data between a mapper
    551  * and an user buffer required by a sys_read() or a sys_write().
    552  ***********************************************************************************
    553  * @ cxy         : server cluster identifier.
    554  * @ mapper      : [in]  local pointer on mapper.
    555  * @ to_buffer   : [in]  move data from mapper to buffer if non zero.
    556  * @ file_offset : [in]  first byte to move in mapper.
    557  * @ buffer      : [in]  user space buffer pointer.
    558  * @ size        : [in]  number of bytes to move.
    559  * @ error       : [out] error status (0 if success).
    560  **********************************************************************************/
    561 void rpc_mapper_move_user_client( cxy_t             cxy,
    562                                   struct mapper_s * mapper,
    563                                   bool_t            to_buffer,
    564                                   uint32_t          file_offset,
    565                                   void            * buffer,
    566                                   uint32_t          size,
    567                                   error_t         * error );
    568 
    569 void rpc_mapper_move_user_server( xptr_t xp );
     544 * [24] undefined slot
     545 **********************************************************************************/
    570546
    571547/***********************************************************************************
  • trunk/kernel/kern/scheduler.c

    r593 r610  
    254254uint32_t cycle = (uint32_t)hal_get_cycles();
    255255if( DEBUG_SCHED_HANDLE_SIGNALS < cycle )
    256 printk("\n[DBG] %s : thread[%x,%x] on core[%x,%d] deleted / cycle %d\n",
     256printk("\n[%s] thread[%x,%x] on core[%x,%d] deleted / cycle %d\n",
    257257__FUNCTION__ , process->pid , thread->trdid , local_cxy , thread->core->lid , cycle );
    258258#endif
     
    266266cycle = (uint32_t)hal_get_cycles();
    267267if( DEBUG_SCHED_HANDLE_SIGNALS < cycle )
    268 printk("\n[DBG] %s : process %x in cluster %x deleted / cycle %d\n",
     268printk("\n[%s] process %x in cluster %x deleted / cycle %d\n",
    269269__FUNCTION__ , process->pid , local_cxy , cycle );
    270270#endif
     
    336336uint32_t cycle = (uint32_t)hal_get_cycles();
    337337if( DEBUG_SCHED_HANDLE_SIGNALS < cycle )
    338 printk("\n[DBG] %s : thread[%x,%x] on core[%x,%d] deleted / cycle %d\n",
     338printk("\n[%s] thread[%x,%x] on core[%x,%d] deleted / cycle %d\n",
    339339__FUNCTION__ , process_zero.pid , thread->trdid , local_cxy , thread->core->lid , cycle );
    340340#endif
     
    396396uint32_t cycle = (uint32_t)hal_get_cycles();
    397397if( DEBUG_SCHED_RPC_ACTIVATE < cycle )
    398 printk("\n[DBG] %s : new RPC thread %x created for core[%x,%d] / total %d / cycle %d\n",
     398printk("\n[%s] new RPC thread %x created for core[%x,%d] / total %d / cycle %d\n",
    399399__FUNCTION__, thread->trdid, local_cxy, lid, LOCAL_CLUSTER->rpc_threads[lid], cycle );
    400400#endif
     
    409409uint32_t cycle = (uint32_t)hal_get_cycles();
    410410if( DEBUG_SCHED_RPC_ACTIVATE < cycle )
    411 printk("\n[DBG] %s : idle RPC thread %x unblocked for core[%x,%d] / cycle %d\n",
     411printk("\n[%s] idle RPC thread %x unblocked for core[%x,%d] / cycle %d\n",
    412412__FUNCTION__, thread->trdid, local_cxy, lid, cycle );
    413413#endif
     
    540540#if DEBUG_SCHED_YIELD
    541541if( sched->trace )
    542 printk("\n[DBG] %s : core[%x,%d] / cause = %s\n"
     542printk("\n[%s] core[%x,%d] / cause = %s\n"
    543543"      thread %x (%s) (%x,%x) => thread %x (%s) (%x,%x) / cycle %d\n",
    544544__FUNCTION__, local_cxy, lid, cause,
     
    557557#if (DEBUG_SCHED_YIELD & 1)
    558558if( sched->trace )
    559 printk("\n[DBG] %s : core[%x,%d] / cause = %s\n"
     559printk("\n[%s] core[%x,%d] / cause = %s\n"
    560560"      thread %x (%s) (%x,%x) continue / cycle %d\n",
    561561__FUNCTION__, local_cxy, lid, cause, current, thread_type_str(current->type),
     
    687687        uint32_t      blocked = hal_remote_l32 ( XPTR( cxy , &thread->blocked ) );
    688688        uint32_t      flags   = hal_remote_l32 ( XPTR( cxy , &thread->flags ) );
    689         process_t *   process = hal_remote_lpt( XPTR( cxy , &thread->process ) );
     689        process_t *   process = hal_remote_lpt ( XPTR( cxy , &thread->process ) );
    690690        pid_t         pid     = hal_remote_l32 ( XPTR( cxy , &process->pid ) );
    691691
     
    695695            char      name[16];
    696696            chdev_t * chdev = hal_remote_lpt( XPTR( cxy , &thread->chdev ) );
    697             hal_remote_strcpy( XPTR( local_cxy , name ), XPTR( cxy , &chdev->name ) );
     697            hal_remote_strcpy( XPTR( local_cxy , name ), XPTR( cxy , chdev->name ) );
    698698
    699699            nolock_printk(" - %s / pid %X / trdid %X / desc %X / block %X / flags %X / %s\n",
     
    721721        uint32_t      blocked = hal_remote_l32 ( XPTR( cxy , &thread->blocked ) );
    722722        uint32_t      flags   = hal_remote_l32 ( XPTR( cxy , &thread->flags ) );
    723         process_t *   process = hal_remote_lpt( XPTR( cxy , &thread->process ) );
     723        process_t *   process = hal_remote_lpt ( XPTR( cxy , &thread->process ) );
    724724        pid_t         pid     = hal_remote_l32 ( XPTR( cxy , &process->pid ) );
    725725
  • trunk/kernel/kern/thread.h

    r583 r610  
    194194    dma_command_t       dma_cmd;         /*! DMA device generic command               */
    195195
    196         cxy_t               rpc_client_cxy;  /*! client cluster index (for a RPC thread)  */
     196        xptr_t              rpc_client_xp;   /*! client thread (for a RPC thread only)    */
    197197
    198198    list_entry_t        wait_list;       /*! member of a local waiting queue          */
  • trunk/kernel/kernel_config.h

    r607 r610  
    3737#define DEBUG_BARRIER                     0
    3838
    39 #define DEBUG_BUSYLOCK                    1
     39#define DEBUG_BUSYLOCK                    0
    4040#define DEBUG_BUSYLOCK_THREAD_XP          0x0000000000ULL  // selected thread xptr
    4141                 
     
    8181#define DEBUG_FATFS_MOVE_PAGE             0
    8282#define DEBUG_FATFS_RELEASE_INODE         0
    83 #define DEBUG_FATFS_REMOVE_DENTRY         1
     83#define DEBUG_FATFS_REMOVE_DENTRY         0
    8484#define DEBUG_FATFS_SYNC_FAT              0
    8585#define DEBUG_FATFS_SYNC_FSINFO           0
     
    9090#define DEBUG_HAL_GPT_CREATE              0
    9191#define DEBUG_HAL_GPT_DESTROY             0
    92 
     92#define DEBUG_HAL_USPACE                  0
    9393#define DEBUG_HAL_KENTRY                  0
    9494#define DEBUG_HAL_EXCEPTIONS              0
     
    102102#define DEBUG_KMEM                        0
    103103
    104 #define DEBUG_KERNEL_INIT                 0
    105 
    106 #define DEBUG_MAPPER_GET_PAGE             1
     104#define DEBUG_KERNEL_INIT                 2
     105
     106#define DEBUG_MAPPER_GET_PAGE             0
    107107#define DEBUG_MAPPER_HANDLE_MISS          0
    108108#define DEBUG_MAPPER_MOVE_USER            0
     
    116116#define DEBUG_PROCESS_COPY_INIT           0
    117117#define DEBUG_PROCESS_DESTROY             0
     118#define DEBUG_PROCESS_FD_REGISTER         0
    118119#define DEBUG_PROCESS_GET_LOCAL_COPY      0
    119120#define DEBUG_PROCESS_INIT_CREATE         0
     
    125126#define DEBUG_PROCESS_ZERO_CREATE         0
    126127
    127 #define DEBUG_QUEUELOCK                   0
     128#define DEBUG_QUEUELOCK_TYPE              0    // lock type (0 is undefined)
    128129
    129130#define DEBUG_RPC_CLIENT_GENERIC          0
     
    132133#define DEBUG_RPC_KCM_ALLOC               0
    133134#define DEBUG_RPC_KCM_FREE                0
    134 #define DEBUG_RPC_MAPPER_rGT_PAGE         0
     135#define DEBUG_RPC_MAPPER_HANDLE_MISS      0
    135136#define DEBUG_RPC_MAPPER_MOVE_USER        0
    136137#define DEBUG_RPC_PMEM_GET_PAGES          0
     
    150151#define DEBUG_RPC_VMM_GET_VSEG            0
    151152
    152 #define DEBUG_RWLOCK                      0
     153#define DEBUG_RWLOCK_TYPE                 0    // lock type (0 is undefined)
    153154
    154155#define DEBUG_SCHED_HANDLE_SIGNALS        2
     
    169170#define DEBUG_SYS_FORK                    0
    170171#define DEBUG_SYS_GET_CONFIG              0
     172#define DEBUG_SYS_GETCWD                  0
    171173#define DEBUG_SYS_GETPID                  0
    172174#define DEBUG_SYS_ISATTY                  0
     
    174176#define DEBUG_SYS_KILL                    0
    175177#define DEBUG_SYS_OPEN                    0
     178#define DEBUG_SYS_MKDIR                   2
    176179#define DEBUG_SYS_MMAP                    0
    177180#define DEBUG_SYS_MUNMAP                  0
     
    205208#define DEBUG_VFS_ADD_CHILD               0
    206209#define DEBUG_VFS_CLOSE                   0
     210#define DEBUG_VFS_CHDIR                   0
    207211#define DEBUG_VFS_DENTRY_CREATE           0
     212#define DEBUG_VFS_FILE_CREATE             0
     213#define DEBUG_VFS_GET_PATH                0
    208214#define DEBUG_VFS_INODE_CREATE            0
    209215#define DEBUG_VFS_INODE_LOAD_ALL          0
    210 #define DEBUG_VFS_LOOKUP                  0
     216#define DEBUG_VFS_LINK                    0
     217#define DEBUG_VFS_LOOKUP                  1
    211218#define DEBUG_VFS_LSEEK                   0
     219#define DEBUG_VFS_MKDIR                   1
    212220#define DEBUG_VFS_NEW_CHILD_INIT          0
    213221#define DEBUG_VFS_OPEN                    0
    214222#define DEBUG_VFS_STAT                    0
    215 #define DEBUG_VFS_UNLINK                  1
     223#define DEBUG_VFS_UNLINK                  0
    216224
    217225#define DEBUG_VMM_CREATE_VSEG             0
     
    247255
    248256#define LOCK_THREAD_JOIN      10   // remote (B)  protect join/exit between two threads
    249 #define LOCK_VFS_MAIN         11   // remote (B)  protect vfs traversal (one per inode)
     257#define LOCK_XHTAB_STATE      11   // remote (B)  protect  a distributed xhtab state
    250258#define LOCK_CHDEV_QUEUE      12   // remote (B)  protect chdev threads waiting queue
    251259#define LOCK_CHDEV_TXT0       13   // remote (B)  protect access to kernel terminal TXT0
     
    255263#define LOCK_CONDVAR_STATE    17   // remote (B)  protect user condvar state
    256264#define LOCK_SEM_STATE        18   // remote (B)  protect user semaphore state
    257 #define LOCK_XHTAB_STATE      19   // remote (B)  protect a distributed xhatb state
     265#define LOCK_PROCESS_CWD      19   // remote (B)  protect current working directory in process
    258266
    259267#define BUSYLOCK_TYPE_MAX     20
     
    272280
    273281#define LOCK_MAPPER_STATE     30   // remote (RW) protect mapper state
    274 #define LOCK_PROCESS_CWD      31   // remote (RW) protect current working directory in process
    275 #define LOCK_VFS_INODE        32   // remote (RW) protect inode state and associated mapper
    276 #define LOCK_VFS_FILE         33   // remote (RW) protect file descriptor state
    277 #define LOCK_VMM_VSL          34   // remote (RW) protect VSL (local list of vsegs)
    278 #define LOCK_VMM_GPT          35   // remote (RW) protect GPT (local page table)
     282#define LOCK_VFS_SIZE         31   // remote (RW) protect inode state and associated mapper
     283#define LOCK_VFS_FILE         32   // remote (RW) protect file descriptor state
     284#define LOCK_VMM_VSL          33   // remote (RW) protect VSL (local list of vsegs)
     285#define LOCK_VMM_GPT          34   // remote (RW) protect GPT (local page table)
     286#define LOCK_VFS_MAIN         35   // remote (RW) protect vfs traversal (in root inode)
    279287
    280288
  • trunk/kernel/libk/grdxt.c

    r603 r610  
    133133    void ** ptr1 = hal_remote_lpt( XPTR( rt_cxy , &rt_ptr->root ) );
    134134
    135         printk("\n***** Generic Radix Tree for <%s> : %d / %d / %d\n",
    136     name, 1<<w1 , 1<<w2 , 1<<w3 );
     135        printk("\n***** Generic Radix Tree for <%s>\n", name );
    137136
    138137        for( ix1=0 ; ix1 < (uint32_t)(1<<w1) ; ix1++ )
     
    327326
    328327    // get ptr1
    329     void         ** ptr1 = hal_remote_lpt( XPTR( rt_cxy , &rt_ptr->root ) );
     328    void ** ptr1 = hal_remote_lpt( XPTR( rt_cxy , &rt_ptr->root ) );
    330329
    331330    // get ptr2
    332         void         ** ptr2 = hal_remote_lpt( XPTR( rt_cxy , &ptr1[ix1] ) );
     331        void ** ptr2 = hal_remote_lpt( XPTR( rt_cxy , &ptr1[ix1] ) );
    333332        if( ptr2 == NULL ) return XPTR_NULL;
    334333
    335334    // get ptr3
    336         void         ** ptr3 = hal_remote_lpt( XPTR( rt_cxy , &ptr2[ix2] ) );
     335        void ** ptr3 = hal_remote_lpt( XPTR( rt_cxy , &ptr2[ix2] ) );
    337336        if( ptr3 == NULL ) return XPTR_NULL;
    338337
    339     // get value
    340         xptr_t      value = XPTR( rt_cxy , ptr3[ix3] );
    341 
    342         return value;
     338    // get pointer on registered item
     339    void  * item_ptr = hal_remote_lpt( XPTR( rt_cxy , &ptr3[ix3] ) );
     340
     341    // return extended pointer on registered item
     342    if ( item_ptr == NULL )  return XPTR_NULL;
     343        else                     return XPTR( rt_cxy , item_ptr );
    343344
    344345}  // end grdxt_remote_lookup()
  • trunk/kernel/libk/grdxt.h

    r603 r610  
    4040 * - Lookup can be done by a thread running in any cluster (local or remote).
    4141 ******************************************************************************************
    42  * It is used by the mapper implementing the file cache:
     42 * When it is used by the mapper implementing the file cache:
    4343 * - the key is the page index in file.
    4444 * - the registered value is a local pointer on the page descriptor.
  • trunk/kernel/libk/htab.c

    r563 r610  
    3434///////////////////////////////////////////////////////////////////////////////////////////
    3535//    Item type specific (static) functions (two functions for each item type).
    36 // Example below if for <vhs_inode_t>, where the identifier is the inum field.
    37 ///////////////////////////////////////////////////////////////////////////////////////////
    38 
    39 ///////////////////////////////////////////////////////////////////////////////////////////
    40 // These static functions compute the hash index from the key.
     36// Example below if for <bloup_t> type, where the identifier is an uint32_t field.
     37///////////////////////////////////////////////////////////////////////////////////////////
     38
     39typedef struct bloup_s
     40{
     41    uint32_t       key;
     42    list_entry_t   list;
     43}
     44bloup_t;
     45
     46///////////////////////////////////////////////////////////////////////////////////////////
     47// This static function computes the hash index from the key.
    4148///////////////////////////////////////////////////////////////////////////////////////////
    4249// @ key      : local pointer on key.
    4350// @ return the index value, from 0 to (HASHTAB_SIZE - 1)
    4451///////////////////////////////////////////////////////////////////////////////////////////
    45 static uint32_t htab_inode_index( void * key )
    46 {
    47         uint32_t * inum = key;
    48         return (((*inum) >> 16) ^ ((*inum) & 0xFFFF)) % HASHTAB_SIZE;
     52static uint32_t htab_bloup_index( void * key )
     53{
     54        return (*(uint32_t *)key) % HASHTAB_SIZE;
    4955}
    5056
    5157///////////////////////////////////////////////////////////////////////////////////////
    52 // These static functions are used by htab_lookup(), htab_insert(), and htab_remove().
     58// This static function is used by htab_lookup(), htab_insert(), and htab_remove().
    5359// They scan one sub-list identified by  <index> to find an item  identified by <key>.
    5460// The sub-list is not modified, but the lock must have been taken by the caller.
     
    5965// @ return pointer on item if found / return NULL if not found.
    6066///////////////////////////////////////////////////////////////////////////////////////
    61 static void * htab_inode_scan( htab_t  * htab,
     67static void * htab_bloup_scan( htab_t  * htab,
    6268                               uint32_t  index,
    6369                               void    * key )
    6470{
    6571    list_entry_t * list_entry;   // pointer on list_entry_t (iterator)
    66     vfs_inode_t  * inode;        // pointer on item
     72    bloup_t      * bloup;        // pointer on item
    6773   
    6874        LIST_FOREACH( &htab->roots[index] , list_entry )
    6975        {
    70         inode = (vfs_inode_t *)LIST_ELEMENT( list_entry , vfs_inode_t , list );
    71         if( inode->inum == *(uint32_t *)key ) return inode;
     76        bloup = (bloup_t *)LIST_ELEMENT( list_entry , bloup_t , list );
     77        if( bloup->key == *(uint32_t *)key ) return bloup;
    7278    }
    7379
     
    9197    htab->items = 0;
    9298
    93     if( type == HTAB_INODE_TYPE )
    94     {
    95         htab->scan    = &htab_inode_scan;
    96         htab->index   = &htab_inode_index;
     99    if( type == HTAB_BLOUP_TYPE )
     100    {
     101        htab->scan    = &htab_bloup_scan;
     102        htab->index   = &htab_bloup_index;
    97103    }
    98104    else
  • trunk/kernel/libk/htab.h

    r563 r610  
    3131
    3232/////////////////////////////////////////////////////////////////////////////////////////
    33 // This file define a generic, embedded, hash table.
     33// This file define a generic, embedded, local hash table.
    3434//
    3535// It can only be accessed by threads running in the local cluster.
     
    7070typedef enum
    7171{
    72     HTAB_INODE_TYPE = 1,                     /*! item is a vfs_inode_t                 */
     72    HTAB_BLOUP_TYPE = 1,                     /*! item is a bloup_t                     */
    7373}
    7474htab_item_type_t;
  • trunk/kernel/libk/list.h

    r457 r610  
    33 *
    44 * Authors Ghassan Almaless  (2008,2009,2010,2011,2012)
    5  *         Alain Greiner     (2016)
     5 *         Alain Greiner     (2016,2017,2018)
    66 *
    77 * Copyright (c) UPMC Sorbonne Universites
     
    2323 */
    2424
    25 #ifndef _ALMOS_LIST_H_
    26 #define _ALMOS_LIST_H_
     25#ifndef _LIST_H_
     26#define _LIST_H_
    2727
    2828#include <kernel_config.h>
    2929#include <hal_kernel_types.h>
     30#include <printk.h>
    3031
    3132#ifndef NULL
     
    240241}
    241242
    242 
    243 #endif  /* _ALMOS_LIST_H_ */
     243/***************************************************************************
     244 * This debug function displays all entries of a list.
     245 * @ root    : local pointer on the root list_entry_t.
     246 * @ string  : list identifier displayed in header.
     247 * @ max     : max number of éléments to display.
     248 **************************************************************************/
     249static inline void list_display( list_entry_t * root,
     250                                 char         * string,
     251                                 uint32_t       max )
     252{
     253    list_entry_t * iter;
     254    list_entry_t * next;
     255    list_entry_t * pred;
     256    uint32_t       index;
     257
     258    next = root->next;
     259    pred = root->pred;
     260
     261    printk("\n***** root (%x) / next (%x) / pred (%x) / %s *****\n",
     262    root, next, pred, string );
     263
     264    if( list_is_empty( root ) == false )
     265    {
     266        for( iter = next , index = 0 ;
     267             (iter != root) && (index < max) ;
     268             iter = next , index++ )
     269        {
     270            next = iter->next;
     271                        pred = iter->pred;
     272
     273            printk(" - %d : iter (%x) / next (%x) / pred (%x)\n",
     274            index, iter, next, pred );
     275        }
     276    }
     277}  // end list_display()
     278
     279
     280#endif  /* _LIST_H_ */
  • trunk/kernel/libk/queuelock.c

    r603 r610  
    4545    busylock_init( &lock->lock , type );
    4646
    47 #if DEBUG_QUEUELOCK
     47#if DEBUG_QUEUELOCK_TYPE
    4848thread_t * this = CURRENT_THREAD;
    49 if( DEBUG_QUEUELOCK < (uint32_t)hal_get_cycles() )
     49if( DEBUG_QUEUELOCK_TYPE == type )
    5050printk("\n[%s] thread[%x,%x] initialise lock %s [%x,%x]\n",
    5151__FUNCTION__, this->process->pid, this->trdid,
     
    7070    {
    7171
    72 #if DEBUG_QUEUELOCK
    73 if( DEBUG_QUEUELOCK < (uint32_t)hal_get_cycles() )
     72#if DEBUG_QUEUELOCK_TYPE
     73uint32_t   lock_type = lock->lock.type;
     74if( DEBUG_QUEUELOCK_TYPE == lock_type )
    7475printk("\n[%s ] thread[%x,%x] BLOCK on q_lock %s [%x,%x]\n",
    7576__FUNCTION__, this->process->pid, this->trdid,
    76 lock_type_str[lock->lock.type], local_cxy, lock );
     77lock_type_str[lock_type], local_cxy, lock );
    7778#endif
    7879        // get pointer on calling thread
     
    9596    }
    9697
    97 #if DEBUG_QUEUELOCK
    98 if( DEBUG_QUEUELOCK < (uint32_t)hal_get_cycles() )
     98#if DEBUG_QUEUELOCK_TYPE
     99if( DEBUG_QUEUELOCK_TYPE == lock_type )
    99100printk("\n[%s] thread[%x,%x] ACQUIRE q_lock %s [%x,%x]\n",
    100101__FUNCTION__, this->process->pid, this->trdid,
    101 lock_type_str[lock->lock.type], local_cxy, lock );
     102lock_type_str[lock_type], local_cxy, lock );
    102103#endif
    103104
     
    119120    busylock_acquire( &lock->lock );
    120121
    121 #if DEBUG_QUEUELOCK
    122 thread_t * this = CURRENT_THREAD;
    123 if( DEBUG_QUEUELOCK < (uint32_t)hal_get_cycles() )
     122#if DEBUG_QUEUELOCK_TYPE
     123uint32_t   lock_type = lock->lock.type;
     124thread_t * this      = CURRENT_THREAD;
     125if( DEBUG_QUEUELOCK_TYPE == lock_type )
    124126printk("\n[%s] thread[%x,%x] RELEASE q_lock %s [%x,%x]\n",
    125127__FUNCTION__, this->process->pid, this->trdid,
    126 lock_type_str[lock->lock.type], local_cxy, lock );
     128lock_type_str[lock_type], local_cxy, lock );
    127129#endif
    128130
     
    136138        thread_t * thread = LIST_FIRST( &lock->root , thread_t , wait_list );
    137139
    138 #if DEBUG_QUEUELOCK
    139 if( DEBUG_QUEUELOCK < (uint32_t)hal_get_cycles() )
     140#if DEBUG_QUEUELOCK_TYPE
     141if( DEBUG_QUEUELOCK_TYPE == lock_type )
    140142printk("\n[%s] thread[%x,%x] UNBLOCK thread [%x,%x] / q_lock %s [%x,%x]\n",
    141143__FUNCTION__, this->process->pid, this->trdid, thread->process->pid, thread->trdid,
    142 lock_type_str[lock->lock.type], local_cxy, lock );
     144lock_type_str[lock_type], local_cxy, lock );
    143145#endif
    144146        // remove this waiting thread from waiting list
  • trunk/kernel/libk/remote_queuelock.c

    r603 r610  
    5454    remote_busylock_init( XPTR( lock_cxy , &lock_ptr->lock ) , type );
    5555
    56 #if DEBUG_QUEUELOCK
     56#if DEBUG_QUEUELOCK_TYPE
    5757thread_t * this = CURRENT_THREAD;
    58 if( DEBUG_QUEUELOCK < (uint32_t)hal_get_cycles() )
     58if( DEBUG_QUEUELOCK_TYPE == type )
    5959printk("\n[%s] thread[%x,%x] initialise lock %s [%x,%x]\n",
    6060__FUNCTION__, this->process->pid, this->trdid,
     
    7676    remote_queuelock_t * lock_ptr = GET_PTR( lock_xp );
    7777
    78 #if DEBUG_QUEUELOCK
     78#if DEBUG_QUEUELOCK_TYPE
    7979uint32_t lock_type = hal_remote_l32( XPTR( lock_cxy , &lock_ptr->lock.type ) );
    8080#endif
     
    9090    {
    9191
    92 #if DEBUG_QUEUELOCK
    93 if( DEBUG_QUEUELOCK < (uint32_t)hal_get_cycles() )
     92#if DEBUG_QUEUELOCK_TYPE
     93if( DEBUG_QUEUELOCK_TYPE == lock_type )
    9494printk("\n[%s] thread[%x,%x] BLOCK on q_lock %s [%x,%x]\n",
    9595__FUNCTION__, this->process->pid, this->trdid,
     
    116116    }
    117117
    118 #if DEBUG_QUEUELOCK
    119 if( DEBUG_QUEUELOCK < (uint32_t)hal_get_cycles() )
     118#if DEBUG_QUEUELOCK_TYPE
     119if( DEBUG_QUEUELOCK_TYPE == lock_type )
    120120printk("\n[%s] thread[%x,%x] ACQUIRE q_lock %s [%x,%x]\n",
    121121__FUNCTION__, this->process->pid, this->trdid,
     
    128128    // release busylock
    129129    remote_busylock_release( busylock_xp );
     130
     131    hal_fence();
    130132
    131133}  // end remote_queuelock_acquire()
     
    147149    remote_busylock_acquire( busylock_xp );
    148150
    149 #if DEBUG_QUEUELOCK
     151#if DEBUG_QUEUELOCK_TYPE
    150152thread_t * this      = CURRENT_THREAD;
    151153uint32_t   lock_type = hal_remote_l32( XPTR( lock_cxy , &lock_ptr->lock.type ) );
    152 if( DEBUG_QUEUELOCK < (uint32_t)hal_get_cycles() )
     154if( DEBUG_QUEUELOCK_TYPE == lock_type )
    153155printk("\n[%s] thread[%x,%x] RELEASE q_lock %s (%x,%x)\n",
    154156__FUNCTION__, this->process->pid, this->trdid,
     
    168170        thread_t * thread_ptr = GET_PTR( thread_xp );
    169171
    170 #if DEBUG_QUEUELOCK
    171 if( DEBUG_QUEUELOCK < (uint32_t)hal_get_cycles() )
     172#if DEBUG_QUEUELOCK_TYPE
     173if( DEBUG_QUEUELOCK_TYPE == lock_type )
    172174{
    173175    trdid_t     trdid   = hal_remote_l32( XPTR( thread_cxy , &thread_ptr->trdid ) );
  • trunk/kernel/libk/remote_rwlock.c

    r603 r610  
    5353    remote_busylock_init( XPTR( lock_cxy , &lock_ptr->lock ) , type );
    5454
    55 #if DEBUG_RWLOCK
     55#if DEBUG_RWLOCK_TYPE
    5656thread_t * this = CURRENT_THREAD;
    57 if( DEBUG_RWLOCK < (uint32_t)hal_get_cycles() )
     57if( type == DEBUG_RWLOCK_TYPE )
    5858printk("\n[%s] thread[%x,%x] initialise lock %s [%x,%x]\n",
    5959__FUNCTION__, this->process->pid, this->trdid,
     
    7575    cxy_t             lock_cxy = GET_CXY( lock_xp );
    7676
    77 #if DEBUG_RWLOCK
     77#if DEBUG_RWLOCK_TYPE
    7878uint32_t lock_type = hal_remote_l32( XPTR( lock_cxy , &lock_ptr->lock.type ) );
    7979#endif
     
    9292    {
    9393
    94 #if DEBUG_RWLOCK
    95 if( DEBUG_RWLOCK < (uint32_t)hal_get_cycles() )
     94#if DEBUG_RWLOCK_TYPE
     95if( lock_type == DEBUG_RWLOCK_TYPE )
    9696printk("\n[%s] thread[%x,%x] READ BLOCK on rwlock %s [%x,%x] / taken %d / count %d\n",
    9797__FUNCTION__, this->process->pid, this->trdid,
     
    123123    hal_fence();
    124124
    125 #if DEBUG_RWLOCK
    126 if( DEBUG_RWLOCK < (uint32_t)hal_get_cycles() )
     125#if DEBUG_RWLOCK_TYPE
     126if( lock_type == DEBUG_RWLOCK_TYPE )
    127127printk("\n[%s] thread[%x,%x] READ ACQUIRE rwlock %s [%x,%x] / taken = %d / count = %d\n",
    128128__FUNCTION__, this->process->pid, this->trdid,
     
    148148    cxy_t             lock_cxy = GET_CXY( lock_xp );
    149149
    150 #if DEBUG_RWLOCK
     150#if DEBUG_RWLOCK_TYPE
    151151uint32_t lock_type = hal_remote_l32( XPTR( lock_cxy , &lock_ptr->lock.type ) );
    152152#endif
     
    165165    {
    166166
    167 #if DEBUG_RWLOCK
    168 if( DEBUG_RWLOCK < (uint32_t)hal_get_cycles() )
     167#if DEBUG_RWLOCK_TYPE
     168if( lock_type == DEBUG_RWLOCK_TYPE )
    169169printk("\n[%s] thread[%x,%x] WRITE BLOCK on rwlock %s [%x,%x] / taken %d / count %d\n",
    170170__FUNCTION__, this->process->pid, this->trdid,
     
    195195    hal_remote_s32( taken_xp , 1 );
    196196
    197 #if DEBUG_RWLOCK
    198 if( DEBUG_RWLOCK < (uint32_t)hal_get_cycles() )
     197#if DEBUG_RWLOCK_TYPE
     198if( lock_type == DEBUG_RWLOCK_TYPE )
    199199printk("\n[%s] thread[%x,%x] WRITE ACQUIRE rwlock %s [%x,%x] / taken %d / count %d\n",
    200200__FUNCTION__, this->process->pid, this->trdid,
     
    231231    hal_remote_atomic_add( count_xp , -1 );
    232232
    233 #if DEBUG_RWLOCK
     233#if DEBUG_RWLOCK_TYPE
    234234thread_t * this      = CURRENT_THREAD;
    235235uint32_t   lock_type = hal_remote_l32( XPTR( lock_cxy , &lock_ptr->lock.type ) );
    236236xptr_t     taken_xp  = XPTR( lock_cxy , &lock_ptr->taken );
    237 if( DEBUG_RWLOCK < (uint32_t)hal_get_cycles() )
     237if( lock_type == DEBUG_RWLOCK_TYPE )
    238238printk("\n[%s] thread[%x,%x] READ RELEASE rwlock %s [%x,%x] / taken %d / count %d\n",
    239239__FUNCTION__, this->process->pid, this->trdid,
     
    257257        thread_unblock( thread_xp , THREAD_BLOCKED_LOCK );
    258258
    259 #if DEBUG_RWLOCK
    260 if( (uint32_t)hal_get_cycles() > DEBUG_RWLOCK )
     259#if DEBUG_RWLOCK_TYPE
     260if( lock_type == DEBUG_RWLOCK_TYPE )
    261261{
    262262    trdid_t     trdid     = hal_remote_l32( XPTR( thread_cxy , &thread_ptr->trdid ) );
     
    288288            thread_unblock( thread_xp , THREAD_BLOCKED_LOCK );
    289289
    290 #if DEBUG_RWLOCK
    291 if( (uint32_t)hal_get_cycles() > DEBUG_RWLOCK )
     290#if DEBUG_RWLOCK_TYPE
     291if( lock_type == DEBUG_RWLOCK_TYPE )
    292292{
    293293    trdid_t     trdid     = hal_remote_l32( XPTR( thread_cxy , &thread_ptr->trdid ) );
     
    330330    hal_remote_s32( taken_xp , 0 );
    331331
    332 #if DEBUG_RWLOCK
     332#if DEBUG_RWLOCK_TYPE
    333333thread_t * this      = CURRENT_THREAD;
    334334uint32_t   lock_type = hal_remote_l32( XPTR( lock_cxy , &lock_ptr->lock.type ) );
    335335xptr_t     count_xp  = XPTR( lock_cxy , &lock_ptr->count );
    336 if( DEBUG_RWLOCK < (uint32_t)hal_get_cycles() )
     336if( lock_type == DEBUG_RWLOCK_TYPE )
    337337printk("\n[%s] thread[%x,%x] WRITE RELEASE rwlock %s [%x,%x] / taken %d / count %d\n",
    338338__FUNCTION__, this->process->pid, this->trdid,
     
    355355        thread_unblock( thread_xp , THREAD_BLOCKED_LOCK );
    356356
    357 #if DEBUG_RWLOCK
    358 if( (uint32_t)hal_get_cycles() > DEBUG_RWLOCK )
     357#if DEBUG_RWLOCK_TYPE
     358if( lock_type == DEBUG_RWLOCK_TYPE )
    359359{
    360360    trdid_t     trdid     = hal_remote_l32( XPTR( thread_cxy , &thread_ptr->trdid ) );
     
    385385            thread_unblock( thread_xp , THREAD_BLOCKED_LOCK );
    386386
    387 #if DEBUG_RWLOCK
    388 if( (uint32_t)hal_get_cycles() > DEBUG_RWLOCK )
     387#if DEBUG_RWLOCK_TYPE
     388if( lock_type == DEBUG_RWLOCK_TYPE )
    389389{
    390390    trdid_t     trdid     = hal_remote_l32( XPTR( thread_cxy , &thread_ptr->trdid ) );
  • trunk/kernel/libk/rwlock.c

    r603 r610  
    5050    busylock_init( &lock->lock , type );
    5151
    52 #if DEBUG_RWLOCK
     52#if DEBUG_RWLOCK_TYPE
    5353thread_t * this = CURRENT_THREAD;
    54 if( DEBUG_RWLOCK < (uint32_t)hal_get_cycles() )
     54if( DEBUG_RWLOCK_TYPE == type )
    5555printk("\n[%s] thread[%x,%x] initialise lock %s [%x,%x]\n",
    5656__FUNCTION__, this->process->pid, this->trdid,
     
    7575    {
    7676
    77 #if DEBUG_RWLOCK
    78 if( DEBUG_RWLOCK < (uint32_t)hal_get_cycles() )
     77#if DEBUG_RWLOCK_TYPE
     78uint32_t lock_type = lock->lock.type;
     79if( DEBUG_RWLOCK_TYPE == lock_type )
    7980printk("\n[%s] thread[%x,%x] READ BLOCK on rwlock %s [%x,%x] / taken %d / count %d\n",
    8081__FUNCTION__, this->process->pid, this->trdid,
    81 lock_type_str[lock->lock.type], local_cxy, lock, lock->taken, lock->count );
     82lock_type_str[lock_type], local_cxy, lock, lock->taken, lock->count );
    8283#endif
    8384        // register reader thread in waiting queue
     
    100101    lock->count++;
    101102
    102 #if DEBUG_RWLOCK
    103 if( DEBUG_RWLOCK < (uint32_t)hal_get_cycles() )
     103#if DEBUG_RWLOCK_TYPE
     104if( DEBUG_RWLOCK_TYPE == lock_type )
    104105printk("\n[%s] thread[%x,%x] READ ACQUIRE rwlock %s [%x,%x] / taken %d / count %d\n",
    105106__FUNCTION__, this->process->pid, this->trdid,
    106 lock_type_str[lock->lock.type], local_cxy, lock, lock->taken, lock->count );
     107lock_type_str[lock_type], local_cxy, lock, lock->taken, lock->count );
    107108#endif
    108109
     
    127128    {
    128129
    129 #if DEBUG_RWLOCK
    130 if( DEBUG_RWLOCK < (uint32_t)hal_get_cycles() )
     130#if DEBUG_RWLOCK_TYPE
     131uint32_t lock_type = lock->lock.type;
     132if( DEBUG_RWLOCK_TYPE == lock_type )
    131133printk("\n[%s] thread[%x,%x] WRITE BLOCK on rwlock %s [%x,%x] / taken %d / count %d\n",
    132134__FUNCTION__, this->process->pid, this->trdid,
    133 lock_type_str[lock->lock.type], local_cxy, lock, lock->taken, lock->count );
     135lock_type_str[lock_type], local_cxy, lock, lock->taken, lock->count );
    134136#endif
    135137        // register writer in waiting queue
     
    152154    lock->taken = 1;
    153155
    154 #if DEBUG_RWLOCK
    155 if( DEBUG_RWLOCK < (uint32_t)hal_get_cycles() )
     156#if DEBUG_RWLOCK_TYPE
     157if( DEBUG_RWLOCK_TYPE == lock_type )
    156158printk("\n[%s] thread[%x,%x] WRITE ACQUIRE rwlock %s [%x,%x] / taken %d / count %d\n",
    157159__FUNCTION__, this->process->pid, this->trdid,
    158 lock_type_str[lock->lock.type], local_cxy, lock, lock->taken, lock->count );
     160lock_type_str[lock_type], local_cxy, lock, lock->taken, lock->count );
    159161#endif
    160162
     
    176178    lock->count--;
    177179
    178 #if DEBUG_RWLOCK
     180#if DEBUG_RWLOCK_TYPE
    179181thread_t * this = CURRENT_THREAD;
    180 if( DEBUG_RWLOCK < (uint32_t)hal_get_cycles() )
     182uint32_t lock_type = lock->lock.type;
     183if( DEBUG_RWLOCK_TYPE == lock_type )
    181184printk("\n[%s] thread[%x,%x] READ RELEASE rwlock %s [%x,%x] / taken %d / count %d\n",
    182185__FUNCTION__, this->process->pid, this->trdid,
    183 lock_type_str[lock->lock.type], local_cxy, lock, lock->taken, lock->count );
     186lock_type_str[lock_type], local_cxy, lock, lock->taken, lock->count );
    184187#endif
    185188
     
    191194        thread_t * thread = LIST_FIRST( &lock->wr_root , thread_t , wait_list );
    192195
    193 #if DEBUG_RWLOCK
    194 if( DEBUG_RWLOCK < (uint32_t)hal_get_cycles() )
     196#if DEBUG_RWLOCK_TYPE
     197if( DEBUG_RWLOCK_TYPE == lock_type )
    195198printk("\n[%s] thread[%x,%x] UNBLOCK thread[%x,%x] / rwlock %s [%x,%x]\n",
    196199__FUNCTION__, this->process->pid, this->trdid, thread->process->pid, thread->trdid,
    197 lock_type_str[lock->lock.type], local_cxy, lock );
     200lock_type_str[lock_type], local_cxy, lock );
    198201#endif
    199202
     
    213216            thread_t * thread = LIST_FIRST( &lock->wr_root , thread_t , wait_list );
    214217
    215 #if DEBUG_RWLOCK
    216 if( DEBUG_RWLOCK < (uint32_t)hal_get_cycles() )
     218#if DEBUG_RWLOCK_TYPE
     219if( DEBUG_RWLOCK_TYPE == lock_type )
    217220printk("\n[%s] thread[%x,%x] UNBLOCK thread[%x,%x] / rwlock %s [%x,%x]\n",
    218221__FUNCTION__, this->process->pid, this->trdid, thread->process->pid, thread->trdid,
    219 lock_type_str[lock->lock.type], local_cxy, lock );
     222lock_type_str[lock_type], local_cxy, lock );
    220223#endif
    221224   
     
    245248    lock->taken = 0;
    246249
    247 #if DEBUG_RWLOCK
     250#if DEBUG_RWLOCK_TYPE
    248251thread_t * this = CURRENT_THREAD;
    249 if( DEBUG_RWLOCK < (uint32_t)hal_get_cycles() )
     252uint32_t lock_type = lock->lock.type;
     253if( DEBUG_RWLOCK_TYPE == lock_type )
    250254printk("\n[%s] thread[%x,%x] WRITE RELEASE rwlock %s [%x,%x] / taken %d / count %d\n",
    251255__FUNCTION__, this->process->pid, this->trdid,
    252 lock_type_str[lock->lock.type], local_cxy, lock, lock->taken, lock->count );
     256lock_type_str[lock_type], local_cxy, lock, lock->taken, lock->count );
    253257#endif
    254258
     
    259263        thread_t * thread = LIST_FIRST( &lock->wr_root , thread_t , wait_list );
    260264
    261 #if DEBUG_RWLOCK
    262 if( DEBUG_RWLOCK < (uint32_t)hal_get_cycles() )
     265#if DEBUG_RWLOCK_TYPE
     266if( DEBUG_RWLOCK_TYPE == lock_type )
    263267printk("\n[%s] thread[%x,%x] UNBLOCK thread[%x,%x] / rwlock %s [%x,%x]\n",
    264268__FUNCTION__, this->process->pid, this->trdid, thread->process->pid, thread->trdid,
    265 lock_type_str[lock->lock.type], local_cxy, lock );
     269lock_type_str[lock_type], local_cxy, lock );
    266270#endif
    267271        // remove this waiting thread from waiting list
     
    280284            thread_t * thread = LIST_FIRST( &lock->rd_root , thread_t , wait_list );
    281285
    282 #if DEBUG_RWLOCK
    283 if( DEBUG_RWLOCK < (uint32_t)hal_get_cycles() )
     286#if DEBUG_RWLOCK_TYPE
     287if( DEBUG_RWLOCK_TYPE == lock_type )
    284288printk("\n[%s] thread[%x,%x] UNBLOCK thread[%x,%x] / rwlock %s [%x,%x]\n",
    285289__FUNCTION__, this->process->pid, this->trdid, thread->process->pid, thread->trdid,
    286 lock_type_str[lock->lock.type], local_cxy, lock );
     290lock_type_str[lock_type], local_cxy, lock );
    287291#endif
    288292            // remove this waiting thread from waiting list
  • trunk/kernel/libk/xhtab.c

    r603 r610  
    4040
    4141///////////////////////////////////////////////////////////////////////////////////////////
    42 // vfs_dentry_t
     42// XHTAB_DENTRY_TYPE
    4343// This functions compute the hash index from the key, that is the directory entry name.
    4444///////////////////////////////////////////////////////////////////////////////////////////
     
    5858
    5959///////////////////////////////////////////////////////////////////////////////////////////
    60 // vfs_dentry_t
     60// XHTAB_DENTRY_TYPE
    6161// This functions returns the extended pointer on the item, from the extended pointer
    6262// on xlist contained in the item.
     
    6767static xptr_t xhtab_dentry_item_from_xlist( xptr_t xlist_xp )
    6868{
    69     return XLIST_ELEMENT( xlist_xp , vfs_dentry_t , list );
     69    return XLIST_ELEMENT( xlist_xp , vfs_dentry_t , children );
    7070}
    7171
    7272////////////////////////////////////////////////////////////////////////////////////////////
    73 // vfs_dentry_t
     73// XHTAB_DENTRY_TYPE
    7474// This function compares the identifier of an item to a given <key>.
    7575// it returns true when the directory name matches the name pointed by the <key> argument.
     
    9696
    9797////////////////////////////////////////////////////////////////////////////////////////////
    98 // vfs_dentry_t
     98// XHTAB_DENTRY_TYPE
    9999// This function print the item key, that is the name for a vfs_dentry_t.
    100100////////////////////////////////////////////////////////////////////////////////////////////
     
    150150                xlist_root_init( XPTR( local_cxy , &xhtab->roots[i] ) );
    151151    } 
     152
     153#if DEBUG_XHTAB
     154printk("\n@@@ %s for xhtab (%x,%x)\n"
     155" - index_from_key  = %x (@ %x)\n"
     156" - item_match_key  = %x (@ %x)\n"
     157" - item_from_xlist = %x (@ %x)\n",
     158__FUNCTION__, local_cxy, xhtab,
     159xhtab->index_from_key , &xhtab->index_from_key,
     160xhtab->item_match_key , &xhtab->item_match_key,
     161xhtab->item_from_xlist, &xhtab->item_from_xlist );
     162#endif
    152163
    153164}  // end xhtab_init()
  • trunk/kernel/libk/xhtab.h

    r603 r610  
    7373/******************************************************************************************
    7474 * This define the supported item types.
     75 * - The XHTAB_DENTRY_TYPE is used to implement the set of directory entries for a
     76 *   directory inode : the "children" inode field is an embedded xhtab.
    7577 *****************************************************************************************/
    7678
  • trunk/kernel/libk/xlist.h

    r603 r610  
    55 * xlist.h - Double Circular Linked lists, using extended pointers.
    66 *
    7  * Author : Alain Greiner (2016)
     7 * Author : Alain Greiner (2016,2017,2018)
    88 *
    99 * Copyright (c) UPMC Sorbonne Universites
     
    3131#include <hal_kernel_types.h>
    3232#include <hal_remote.h>
     33#include <printk.h>
    3334
    3435/**** global variables ***/
     
    190191 * double linked list. Four extended pointers must be modified.
    191192 * The lock protecting the list should have been previously taken.
    192  * @ root   : extended pointer on the root xlist_entry_t
    193  * @ entry  : extended pointer on the xlist_entry_t to be inserted
    194  **************************************************************************/
    195 static inline void xlist_add_first( xptr_t root,
    196                                     xptr_t entry )
     193 * @ root_xp   : extended pointer on the root xlist_entry_t
     194 * @ entry_xp  : extended pointer on the xlist_entry_t to be inserted
     195 **************************************************************************/
     196static inline void xlist_add_first( xptr_t root_xp,
     197                                    xptr_t entry_xp )
    197198{
    198199    // get the extended pointer on the first element in list
    199     xptr_t first = (xptr_t)hal_remote_l64( root );
    200 
    201     // update root.next <= entry
    202     hal_remote_s64( root , (uint64_t)entry );
    203 
    204     // update entry.next <= first
    205     hal_remote_s64( entry , (uint64_t)first );
    206 
    207     // entry.pred <= root
    208     hal_remote_s64( entry + sizeof(xptr_t) , (uint64_t)root );
     200    xptr_t first_xp = hal_remote_l64( root_xp );
     201
     202    // update root_xp->next <= entry_xp
     203    hal_remote_s64( root_xp , entry_xp );
     204
     205    // update entry_xp->next <= first_xp
     206    hal_remote_s64( entry_xp , first_xp );
     207
     208    // update entry_xp->pred <= root_xp
     209    hal_remote_s64( entry_xp + sizeof(xptr_t) , root_xp );
    209210   
    210     // first.pred <= new
    211     hal_remote_s64( first + sizeof(xptr_t) , (uint64_t)entry );
     211    // update first_xp->pred <= entry_xp
     212    hal_remote_s64( first_xp + sizeof(xptr_t) , entry_xp );
    212213}
    213214
     
    216217 * double linked list.  Four extended pointers must be modified.
    217218 * The lock protecting the list should have been previously taken.
    218  * @ root   : extended pointer on the root xlist_entry_t
    219  * @ entry  : extended pointer on the xlist_entry_t to be inserted
    220  **************************************************************************/
    221 static inline void xlist_add_last( xptr_t root,
    222                                    xptr_t entry )
     219 * @ root_xp   : extended pointer on the root xlist_entry_t
     220 * @ entry_xp  : extended pointer on the xlist_entry_t to be inserted
     221 **************************************************************************/
     222static inline void xlist_add_last( xptr_t root_xp,
     223                                   xptr_t entry_xp )
    223224{
    224225    // get the extended pointer on the last element in list
    225     xptr_t last = (xptr_t)hal_remote_l64( root + sizeof(xptr_t) );
    226 
    227     // update root.pred <= entry
    228     hal_remote_s64( root + sizeof(xptr_t) , (uint64_t)entry );
    229 
    230     // update entry.pred <= last
    231     hal_remote_s64( entry + sizeof(xptr_t) , (uint64_t)last );
    232 
    233     // entry.next <= root
    234     hal_remote_s64( entry , (uint64_t)root );
     226    xptr_t last_xp = hal_remote_l64( root_xp + sizeof(xptr_t) );
     227
     228    // update root_xp->pred <= entry_xp
     229    hal_remote_s64( root_xp + sizeof(xptr_t) , entry_xp );
     230
     231    // update entry_xp->pred <= last_xp
     232    hal_remote_s64( entry_xp + sizeof(xptr_t) , last_xp );
     233
     234    // update entry_xp->next <= root_xp
     235    hal_remote_s64( entry_xp , root_xp );
    235236   
    236     // last.next <= entry
    237     hal_remote_s64( last , (uint64_t)entry );
     237    // update last_xp->next <= entry_xp
     238    hal_remote_s64( last_xp , entry_xp );
    238239}
    239240
     
    241242/***************************************************************************
    242243 * This function returns true if the list is empty.
    243  * @ root  : extended pointer on the root xlist_entry_t
    244  **************************************************************************/
    245 static inline bool_t xlist_is_empty( xptr_t root )
     244 * @ root_xp  : extended pointer on the root xlist_entry_t.
     245 **************************************************************************/
     246static inline bool_t xlist_is_empty( xptr_t root_xp )
    246247{
    247248    // get the extended pointer root.next value
    248     xptr_t next = (xptr_t)hal_remote_l64( root );
    249 
    250     return ( root == next );
     249    xptr_t next = (xptr_t)hal_remote_l64( root_xp );
     250
     251    return ( root_xp == next );
    251252}
    252253
     
    279280 * Four extended pointers must be modified.
    280281 * The memory allocated to the removed entry is not released.
    281  * @old      : extended pointer on the xlist_entry_t to be removed.
    282  * @new      : extended pointer on the xlist_entry_t to be inserted.
     282 * @ old      : extended pointer on the xlist_entry_t to be removed.
     283 * @ new      : extended pointer on the xlist_entry_t to be inserted.
    283284 **************************************************************************/
    284285static inline void xlist_replace( xptr_t old,
     
    307308}
    308309
     310/***************************************************************************
     311 * This debug function displays all entries of an xlist.
     312 * @ root_xp : extended pointer on the root xlist_entry_t.
     313 * @ string  : list identifier displayed in header.
     314 * @ max     : max number of éléments to display.
     315 **************************************************************************/
     316static inline void xlist_display( xptr_t  root_xp,
     317                                  char  * string,
     318                                  uint32_t max )
     319{
     320    cxy_t           root_cxy;
     321    xlist_entry_t * root_ptr;
     322
     323    xptr_t          iter_xp;
     324    cxy_t           iter_cxy;
     325    xlist_entry_t * iter_ptr;
     326
     327    xptr_t          next_xp;
     328    cxy_t           next_cxy;
     329    xlist_entry_t * next_ptr;
     330
     331    xptr_t          pred_xp;
     332    cxy_t           pred_cxy;
     333    xlist_entry_t * pred_ptr;
     334
     335    uint32_t        index;
     336
     337    root_cxy = GET_CXY( root_xp );
     338    root_ptr = GET_PTR( root_xp );
     339
     340    next_xp  = hal_remote_l64( XPTR( root_cxy , &root_ptr->next ) );
     341    next_cxy = GET_CXY( next_xp );
     342    next_ptr = GET_PTR( next_xp );
     343
     344    pred_xp  = hal_remote_l64( XPTR( root_cxy , &root_ptr->pred ) );
     345    pred_cxy = GET_CXY( pred_xp );
     346    pred_ptr = GET_PTR( pred_xp );
     347
     348    printk("\n***** root (%x,%x) / next (%x,%x) / pred (%x,%x) / %s *****\n",
     349    root_cxy, root_ptr, next_cxy, next_ptr, pred_cxy, pred_ptr, string );
     350
     351    if( xlist_is_empty( root_xp ) == false )
     352    {
     353        for( iter_xp = hal_remote_l64( XPTR( root_cxy , &root_ptr->next) ) , index = 0 ;
     354             (iter_xp != root_xp) && (index < max) ;
     355             iter_xp = next_xp , index++ )
     356        {
     357            iter_cxy = GET_CXY( iter_xp );
     358            iter_ptr = GET_PTR( iter_xp );
     359
     360            next_xp  = hal_remote_l64( XPTR( iter_cxy , &iter_ptr->next ) );
     361            next_cxy = GET_CXY( next_xp );
     362            next_ptr = GET_PTR( next_xp );
     363
     364            pred_xp  = hal_remote_l64( XPTR( iter_cxy , &iter_ptr->pred ) );
     365            pred_cxy = GET_CXY( pred_xp );
     366            pred_ptr = GET_PTR( pred_xp );
     367
     368            printk(" - %d : iter (%x,%x) / next (%x,%x) / pred (%x,%x)\n",
     369            index, iter_cxy, iter_ptr, next_cxy, next_ptr, pred_cxy, pred_ptr );
     370        }
     371    }
     372}  // end xlist_display()
     373
    309374#endif  /* _XLIST_H_ */
  • trunk/kernel/mm/mapper.c

    r606 r610  
    188188        {
    189189
     190            if( mapper_cxy == local_cxy )   // mapper is local
     191            {
     192
    190193#if (DEBUG_MAPPER_GET_PAGE & 1)
    191194if( DEBUG_MAPPER_GET_PAGE < cycle )
    192 printk("\n[%s] missing page => load it from IOC device\n", __FUNCTION__ );
    193 #endif
    194             if( mapper_cxy == local_cxy )   // mapper is local
    195             {
     195printk("\n[%s] missing page => load it from FS / local access \n", __FUNCTION__ );
     196#endif
    196197                 error = mapper_handle_miss( mapper_ptr,
    197198                                             page_id,
     
    200201            else
    201202            {
     203
     204#if (DEBUG_MAPPER_GET_PAGE & 1)
     205if( DEBUG_MAPPER_GET_PAGE < cycle )
     206printk("\n[%s] missing page => load it from FS / RPC access \n", __FUNCTION__ );
     207#endif
    202208                 rpc_mapper_handle_miss_client( mapper_cxy,
    203209                                                mapper_ptr,
     
    253259vfs_inode_t * inode = mapper->inode;
    254260vfs_inode_get_name( XPTR( local_cxy , inode ) , name );
    255 if( DEBUG_MAPPER_HANDLE_MISS < cycle )
    256 printk("\n[%s] enter for page %d in <%s> / cycle %d\n",
     261// if( DEBUG_MAPPER_HANDLE_MISS < cycle )
     262// if( (page_id == 1) && (cycle > 10000000) )
     263printk("\n[%s] enter for page %d in <%s> / cycle %d",
    257264__FUNCTION__, page_id, name, cycle );
    258265if( DEBUG_MAPPER_HANDLE_MISS & 1 )
    259 grdxt_display( &mapper->rt , name );
    260 #endif
    261 
    262     // allocate one page from the mapper cluster
     266grdxt_display( XPTR( local_cxy , &mapper->rt ) , name );
     267#endif
     268
     269    // allocate one page from the local cluster
    263270    req.type  = KMEM_PAGE;
    264271    req.size  = 0;
     
    313320#if DEBUG_MAPPER_HANDLE_MISS
    314321cycle = (uint32_t)hal_get_cycles();
    315 if( DEBUG_MAPPER_HANDLE_MISS < cycle )
    316 printk("\n[%s] exit for page %d in <%s> / ppn %x / cycle %d\n",
     322// if( DEBUG_MAPPER_HANDLE_MISS < cycle )
     323// if( (page_id == 1) && (cycle > 10000000) )
     324printk("\n[%s] exit for page %d in <%s> / ppn %x / cycle %d",
    317325__FUNCTION__, page_id, name, ppm_page2ppn( *page_xp ), cycle );
    318326if( DEBUG_MAPPER_HANDLE_MISS & 1 )
    319 grdxt_display( &mapper->rt , name );
     327grdxt_display( XPTR( local_cxy , &mapper->rt ) , name );
    320328#endif
    321329
     
    348356}  // end mapper_release_page()
    349357
    350 ////////////////////////////////////////////
    351 error_t mapper_move_user( mapper_t * mapper,
     358///////////////////////////////////////////////
     359error_t mapper_move_user( xptr_t     mapper_xp,
    352360                          bool_t     to_buffer,
    353361                          uint32_t   file_offset,
     
    355363                          uint32_t   size )
    356364{
    357     xptr_t     mapper_xp;      // extended pointer on local mapper
    358365    uint32_t   page_offset;    // first byte to move to/from a mapper page
    359366    uint32_t   page_count;     // number of bytes to move to/from a mapper page
     
    371378#endif
    372379
    373     // build extended pointer on mapper
    374     mapper_xp = XPTR( local_cxy , mapper );
    375 
    376380    // compute offsets of first and last bytes in file
    377381    uint32_t min_byte = file_offset;
     
    384388#if (DEBUG_MAPPER_MOVE_USER & 1)
    385389if( DEBUG_MAPPER_MOVE_USER < cycle )
    386 printk("\n[%s] first_page %d / last_page %d\n", __FUNCTION__, first, last );
     390printk("\n[%s] thread[%x,%x] : first_page %d / last_page %d\n",
     391__FUNCTION__, this->process->pid, this->trdid, first, last );
    387392#endif
    388393
     
    404409#if (DEBUG_MAPPER_MOVE_USER & 1)
    405410if( DEBUG_MAPPER_MOVE_USER < cycle )
    406 printk("\n[%s] page_id = %d / page_offset = %d / page_count = %d\n",
    407 __FUNCTION__ , page_id , page_offset , page_count );
     411printk("\n[%s] thread[%x,%x] : page_id = %d / page_offset = %d / page_count = %d\n",
     412__FUNCTION__, this->process->pid, this->trdid, page_id , page_offset , page_count );
    408413#endif
    409414
     
    412417
    413418        if ( page_xp == XPTR_NULL ) return -1;
     419
     420#if (DEBUG_MAPPER_MOVE_USER & 1)
     421if( DEBUG_MAPPER_MOVE_USER < cycle )
     422printk("\n[%s] thread[%x,%x] : get page (%x,%x) from mapper\n",
     423__FUNCTION__, this->process->pid, this->trdid, GET_CXY(page_xp), GET_PTR(page_xp) );
     424#endif
    414425
    415426        // compute pointer in mapper
     
    547558        }
    548559
     560#if (DEBUG_MAPPER_MOVE_KERNEL & 1)
     561if( DEBUG_MAPPER_MOVE_KERNEL < cycle )
     562printk("\n[%s] src_cxy %x / src_ptr %x / dst_cxy %x / dst_ptr %x\n",
     563__FUNCTION__, src_cxy, src_ptr, dst_cxy, dst_ptr );
     564#endif
     565
    549566        // move fragment
    550567        hal_remote_memcpy( XPTR( dst_cxy , dst_ptr ), XPTR( src_cxy , src_ptr ), page_count );
  • trunk/kernel/mm/mapper.h

    r606 r610  
    4545 * - The leaves are pointers on physical page descriptors, dynamically allocated
    4646 *   in the local cluster.
    47  * - In a given cluster, a mapper is a "private" structure: a thread accessing the mapper
    48  *   must be running in the cluster containing it (can be a local thread or a RPC thread).
    49  * - The mapper is protected by a blocking "rwlock", to support several simultaneous
    50  *   readers, and only one writer. This lock implement a busy waiting policy.
    51  * - The mapper_get_page() function that return a page descriptor pointer from a page
    52  *   index in file is in charge of handling the miss on the mapper cache.
     47 * - The mapper is protected by a "remote_rwlock", to support several simultaneous
     48 *   "readers", and only one "writer".
     49 * - A "reader" thread, calling the mapper_remote_get_page() function to get a page
     50 *   descriptor pointer from the page index in file, can be remote (running in any cluster).
     51 * - A "writer" thread, calling the mapper_handle_miss() function to handle a page miss
     52 *   must be local (running in the mapper cluster).
    5353 * - The vfs_mapper_move_page() function access the file system to handle a mapper miss,
    5454 *   or update a dirty page on device.
    55  * - The vfs_mapper_load_all() functions is used to load all pages of a given file
    56  *   or directory into the mapper.
     55 * - The vfs_mapper_load_all() functions is used to load all pages of a directory
     56 *   into the mapper (prefetch).
    5757 * - the mapper_move_user() function is used to move data to or from an user buffer.
    5858 *   This user space buffer can be physically distributed in several clusters.
     
    137137
    138138/*******************************************************************************************
    139  * This function move data between a local mapper, and a distributed user buffer.
    140  * It must be called by a thread running in cluster containing the mapper.
     139 * This function move data between a remote mapper, dentified by the <mapper_xp> argument,
     140 * and a distributed user buffer. It can be called by a thread running in any cluster.
    141141 * It is called by the vfs_user_move() to implement sys_read() and sys_write() syscalls.
    142142 * If required, the data transfer is split in "fragments", where one fragment contains
     
    144144 * It uses "hal_uspace" accesses to move a fragment to/from the user buffer.
    145145 * In case of write, the dirty bit is set for all pages written in the mapper.
    146  * The mapper being an extendable cache, it is automatically extended when required
    147  * for both read and write accesses.
     146 * The mapper being an extendable cache, it is automatically extended when required.
    148147 * The "offset" field in the file descriptor, and the "size" field in inode descriptor
    149148 * are not modified by this function.
    150149 *******************************************************************************************
    151  * @ mapper       : local pointer on mapper.
     150 * @ mapper_xp    : extended pointer on mapper.
    152151 * @ to_buffer    : mapper -> buffer if true / buffer -> mapper if false.
    153152 * @ file_offset  : first byte to move in file.
     
    156155 * returns O if success / returns -1 if error.
    157156 ******************************************************************************************/
    158 error_t mapper_move_user( mapper_t * mapper,
     157error_t mapper_move_user( xptr_t     mappe_xp,
    159158                          bool_t     to_buffer,
    160159                          uint32_t   file_offset,
  • trunk/kernel/mm/ppm.c

    r606 r610  
    413413    xptr_t dirty_lock_xp = XPTR( page_cxy , &ppm->dirty_lock );
    414414           
     415// printk("\n@@@ %s : before dirty_list lock aquire\n", __FUNCTION__ );
     416
    415417        // lock the remote PPM dirty_list
    416418        remote_queuelock_acquire( dirty_lock_xp );
    417419
     420// printk("\n@@@ %s : after dirty_list lock aquire\n", __FUNCTION__ );
     421
    418422    // lock the remote page
    419423    remote_busylock_acquire( page_lock_xp );
     424
     425// printk("\n@@@ %s : after page lock aquire\n", __FUNCTION__ );
    420426
    421427    // get remote page flags
     
    460466        }
    461467
     468// printk("\n@@@ %s : before page lock release\n", __FUNCTION__ );
     469
    462470    // unlock the remote page
    463471    remote_busylock_release( page_lock_xp );
    464472
     473// printk("\n@@@ %s : after page lock release\n", __FUNCTION__ );
     474
    465475        // unlock the remote PPM dirty_list
    466476        remote_queuelock_release( dirty_lock_xp );
     477
     478// printk("\n@@@ %s : after page lock aquire\n", __FUNCTION__ );
    467479
    468480        return done;
  • trunk/kernel/mm/ppm.h

    r606 r610  
    6262 * also rooted in the PPM, in order to be able to save all dirty pages on disk.
    6363 * This dirty list is protected by a specific remote_queuelock, because it can be
    64  * modified by a remote thread, but it is implemented as a local list, because it
    65  * contains only local pages.
     64 * modified by a remote thread, but it contains only local pages.
    6665 ****************************************************************************************/
    6766
     
    193192 * It can be called by a thread running in any cluster.
    194193 * - it takes the queuelock protecting the PPM dirty_list.
     194 * - it takes the busylock protecting the page flags.
    195195 * - it test the PG_DIRTY flag in the page descriptor.
    196196 *   . if page already dirty => do nothing
    197197 *   . it page not dirty => set the PG_DIRTY flag and register page in PPM dirty list.
     198 * - it releases the busylock protcting the page flags.
    198199 * - it releases the queuelock protecting the PPM dirty_list.
    199200 *****************************************************************************************
     
    207208 * It can be called by a thread running in any cluster.
    208209 * - it takes the queuelock protecting the PPM dirty_list.
     210 * - it takes the busylock protecting the page flags.
    209211 * - it test the PG_DIRTY flag in the page descriptor.
    210212 *   . if page not dirty => do nothing
    211213 *   . it page dirty => reset the PG_DIRTY flag and remove page from PPM dirty list.
     214 * - it releases the busylock protcting the page flags.
    212215 * - it releases the queuelock protecting the PPM dirty_list.
    213216 *****************************************************************************************
  • trunk/kernel/mm/vmm.c

    r606 r610  
    14441444#endif
    14451445
    1446     // compute target cluster
    14471446    page_t     * page_ptr;
    14481447    cxy_t        page_cxy;
     
    16111610#if (DEBUG_VMM_GET_ONE_PPN & 0x1)
    16121611if( DEBUG_VMM_GET_ONE_PPN < (uint32_t)hal_get_cycles() )
    1613 printk("\n[%s] thread[%x,%x] for vpn  %x / both mapper & BSS\n",
     1612printk("\n[%s] thread[%x,%x] for vpn  %x / both mapper & BSS\n"
    16141613"      %d bytes from mapper / %d bytes from BSS\n",
    16151614__FUNCTION__, this->process->pid, this->trdid, vpn,
     
    16741673                          (intptr_t)vpn<<CONFIG_PPM_PAGE_SHIFT,
    16751674                          &vseg );
    1676 
    16771675    if( error )
    16781676    {
     
    19331931#endif
    19341932
     1933    // access local GPT to get GPT_COW flag
     1934    bool_t cow = hal_gpt_pte_is_cow( &(process->vmm.gpt), vpn );
     1935
     1936    if( cow == false ) return EXCP_USER_ERROR;
     1937
    19351938    // get local vseg
    19361939    error = vmm_get_vseg( process,
    19371940                          (intptr_t)vpn<<CONFIG_PPM_PAGE_SHIFT,
    19381941                          &vseg );
    1939 
    19401942    if( error )
    19411943    {
     
    19501952    ref_ptr = GET_PTR( process->ref_xp );
    19511953
    1952     // build relevant extended pointers on  GPT and  GPT lock
     1954    // build relevant extended pointers on  relevant GPT and  GPT lock
    19531955    // - access local GPT for a private vseg 
    19541956    // - access reference GPT for a public vseg
  • trunk/kernel/mm/vmm.h

    r595 r610  
    158158                  bool_t             mapping );
    159159
    160 /*******************************************************************************************
     160/*********************************************************************************************
    161161 * This function adds a vseg descriptor in the VSL of a given VMM,
    162162 * and updates the vmm field in the vseg descriptor.
    163163 * It takes the lock protecting VSL.
    164  *******************************************************************************************
     164 *********************************************************************************************
    165165 * @ vmm       : pointer on the VMM
    166166 * @ vseg      : pointer on the vseg descriptor
    167  ******************************************************************************************/
     167 ********************************************************************************************/
    168168void vmm_vseg_attach( struct vmm_s  * vmm,
    169169                      vseg_t        * vseg );
    170170
    171 /*******************************************************************************************
     171/*********************************************************************************************
    172172 * This function removes a vseg descriptor from the set of vsegs controlled by a given VMM,
    173173 * and updates the vmm field in the vseg descriptor. No memory is released.
    174174 * It takes the lock protecting VSL.
    175  *******************************************************************************************
     175 *********************************************************************************************
    176176 * @ vmm       : pointer on the VMM
    177177 * @ vseg      : pointer on the vseg descriptor
    178  ******************************************************************************************/
     178 ********************************************************************************************/
    179179void vmm_vseg_detach( struct vmm_s  * vmm,
    180180                      vseg_t        * vseg );
     
    326326 * (d) if the removed region cut the vseg in three parts, it is modified, and a new
    327327 *     vseg is created with same type.
    328  * FIXME [AG] this function must be called by a thread running in the reference cluster,
    329  * and the VMM must be updated in all process descriptors copies.
     328 * FIXME [AG] this function should be called by a thread running in the reference cluster,
     329 *       and the VMM should be updated in all process descriptors copies.
    330330 *********************************************************************************************
    331331 * @ process   : pointer on process descriptor
     
    357357/*********************************************************************************************
    358358 * This function is called by the generic exception handler in case of page-fault event,
    359  * detected for a given <vpn> in a given <process> in any cluster.
     359 * detected for a given <vpn>. The <process> argument is used to access the relevant VMM.
    360360 * It checks the missing VPN and returns an user error if it is not in a registered vseg.
    361361 * For a legal VPN, there is actually 3 cases:
     
    370370 *    on vseg type, and updates directly (without RPC) the local GPT and the reference GPT.
    371371 *    Other GPT copies  will updated on demand.
    372  * In the three cases, concurrent accesses to the GPT are handled, thanks to the
     372 * Concurrent accesses to the GPT are handled, thanks to the
    373373 * remote_rwlock protecting each GPT copy.
    374374 *********************************************************************************************
    375  * @ process   : pointer on local process descriptor copy.
    376  * @ vpn       : VPN of the missing PTE.
     375 * @ process  : local pointer on local process.
     376 * @ vpn      : VPN of the missing PTE.
    377377 * @ returns EXCP_NON_FATAL / EXCP_USER_ERROR / EXCP_KERNEL_PANIC after analysis
    378378 ********************************************************************************************/
     
    381381
    382382/*********************************************************************************************
    383  * This function is called by the generic exception handler in case of copy-on-write event,
    384  * detected for a given <vpn> in a given <process> in any cluster.
     383 * This function is called by the generic exception handler in case of WRITE violation event,
     384 * detected for a given <vpn>. The <process> argument is used to access the relevant VMM.
    385385 * It returns a kernel panic if VPN is not in a registered vseg or is not mapped.
    386386 * For a legal mapped vseg there is two cases:
     
    399399 *    Finally it calls the vmm_global_update_pte() function to reset the COW flag and set
    400400 *    the WRITE flag in all the GPT copies, using a RPC if the reference cluster is remote.
    401  * In both cases, concurrent accesses to the GPT are handled, thanks to the
    402  * remote_rwlock protecting each GPT copy.
     401 * In both cases, concurrent accesses to the GPT are protected by the remote_rwlock
     402 * atached to the GPT copy in VMM.
    403403 *********************************************************************************************
    404404 * @ process   : pointer on local process descriptor copy.
  • trunk/kernel/syscalls/shared_include/syscalls_numbers.h

    r584 r610  
    4141    SYS_MUTEX          = 9,
    4242
    43     SYS_EXIT           = 10,
     43    SYS_RENAME         = 10,
    4444    SYS_MUNMAP         = 11,
    4545    SYS_OPEN           = 12,
     
    8585    SYS_IS_FG          = 49,
    8686
    87     SYSCALLS_NR        = 50,
     87    SYS_EXIT           = 50,
     88
     89    SYSCALLS_NR        = 51,
     90
    8891} syscalls_t;
    8992
  • trunk/kernel/syscalls/sys_chdir.c

    r566 r610  
    11/*
    2  * sys_chdir: change process current working directory
     2 * sys_chdir.c - kernel function implementing the "chdir" syscall.
    33 *
    4  * Author    Alain Greiner (2016,2017)
     4 * Author    Alain Greiner (2016,2017,2018)
    55 *
    6  * Copyright (c) 2011,2012 UPMC Sorbonne Universites
     6 * Copyright (c) UPMC Sorbonne Universites
    77 *
    88 * This file is part of ALMOS-MKH.
     
    3838{
    3939    error_t   error;
     40    vseg_t  * vseg;
     41    xptr_t    root_inode_xp;
     42
    4043    char      kbuf[CONFIG_VFS_MAX_PATH_LENGTH];
    4144
    4245    thread_t  * this    = CURRENT_THREAD;
    4346    process_t * process = this->process;
     47
     48#if (DEBUG_SYS_CHDIR || CONFIG_INSTRUMENTATION_SYSCALLS)
     49uint64_t     tm_start = hal_get_cycles();
     50#endif
    4451
    4552    // check pathname length
     
    4855
    4956#if DEBUG_SYSCALLS_ERROR
    50 printk("\n[ERROR] in %s : pathname too long / thread %x in process %x\n",
    51 __FUNCTION__, this->trdid, process->pid );
     57printk("\n[ERROR] in %s : pathname too long / thread[%x,%x]\n",
     58__FUNCTION__, process->pid, this->trdid );
    5259#endif
    53         this->errno = ENFILE;
     60        this->errno = EINVAL;
    5461        return -1;
    5562    }
     63
     64    // check pathname in user space
     65    if( vmm_get_vseg( process, (intptr_t)pathname , &vseg ) )
     66        {
     67
     68#if DEBUG_SYSCALLS_ERROR
     69printk("\n[ERROR] in %s : user buffer unmapped %x for thread[%x,%x]\n",
     70__FUNCTION__ , (intptr_t)pathname , process->pid, this->trdid );
     71#endif
     72                this->errno = EINVAL;
     73        return -1;
     74        }
    5675
    5776    // copy pathname in kernel space
    5877    hal_strcpy_from_uspace( kbuf , pathname , CONFIG_VFS_MAX_PATH_LENGTH );
    5978
    60     printk("\n[ERROR] in %s : not implemented yet\n", __FUNCTION__ );
    61     return -1;
     79#if DEBUG_SYS_CHDIR
     80if( DEBUG_SYS_CHDIR < tm_start )
     81printk("\n[%s] thread[%x,%x] enter for <%s> / cycle %d\n",
     82__FUNCTION__, process->pid, this->trdid, kbuf, (uint32_t)tm_start );
     83#endif
    6284
    63     // get cluster and local pointer on reference process
    64     // xptr_t      ref_xp  = process->ref_xp;
    65     // process_t * ref_ptr = (process_t *)GET_PTR( ref_xp );
    66     // cxy_t       ref_cxy = GET_CXY( ref_xp );
     85    // compute root inode for path
     86    if( kbuf[0] == '/' )                        // absolute path
     87    {
     88        // use extended pointer on VFS root inode
     89        root_inode_xp = process->vfs_root_xp;
     90    }
     91    else                                        // relative path
     92    {
     93        // get cluster and local pointer on reference process
     94        xptr_t      ref_xp  = process->ref_xp;
     95        process_t * ref_ptr = (process_t *)GET_PTR( ref_xp );
     96        cxy_t       ref_cxy = GET_CXY( ref_xp );
    6797
    68     // get extended pointer on cwd lock in reference process
    69     // xptr_t lock_xp = hal_remote_l64( XPTR( ref_cxy , &ref_ptr->cwd_lock ) );
     98        // use extended pointer on CWD inode
     99        root_inode_xp = hal_remote_l64( XPTR( ref_cxy , &ref_ptr->cwd_xp ) );
     100    }
    70101
    71     // get cwd lock in read mode
    72     // remote_rwlock_rd_acquire( lock_xp );
    73 
    74     // TODO ce n'et pas au VFS de le faire [AG]
    75     // error = vfs_chdir( process->vfs_cwd_xp , kbuf );
    76 
    77     // release cwd lock
    78     // remote_rwlock_rd_release( lock_xp );
     102    // call the relevant VFS function
     103    error = vfs_chdir( root_inode_xp , kbuf );
    79104
    80105    if( error )
    81106    {
    82         printk("\n[ERROR] in %s : cannot change current directory\n", __FUNCTION__ );
     107
     108#if DEBUG_SYSCALLS_ERROR
     109printk("\n[ERROR] in %s / thread[%x,%x] : cannot change CWD\n",
     110__FUNCTION__ , process->pid , this->trdid );
     111#endif
    83112        this->errno = error;
    84113        return -1;
    85114    }
    86115
     116    hal_fence();
     117
     118#if (DEBUG_SYS_CHDIR || CONFIG_INSTRUMENTATION_SYSCALLS)
     119uint64_t     tm_end = hal_get_cycles();
     120#endif
     121
     122#if DEBUG_SYS_CHDIR
     123if( DEBUG_SYS_CHDIR < tm_end )
     124printk("\n[%s] thread[%x,%x] exit  / cycle %d\n",
     125__FUNCTION__, process->pid, this->trdid, (uint32_t)tm_end );
     126#endif
     127 
     128#if CONFIG_INSTRUMENTATION_SYSCALLS
     129hal_atomic_add( &syscalls_cumul_cost[SYS_CHDIR] , tm_end - tm_start );
     130hal_atomic_add( &syscalls_occurences[SYS_CHDIR] , 1 );
     131#endif
     132
    87133    return 0;
    88134}
  • trunk/kernel/syscalls/sys_getcwd.c

    r566 r610  
    11/*
    2  * sys_getcwd.c - get process current work directory
     2 * sys_getcwd.c - kernel function implementing the "getcwd" syscall.
    33 *
    44 * Author    Alain Greiner (2016,2017,2018)
     
    3535#include <syscalls.h>
    3636
    37 /* TODO: user page(s) need to be locked  [AG] */
    38 
    39 ////////////////////////////////
    40 int sys_getcwd ( char     * buf,
     37///////////////////////////////////
     38int sys_getcwd ( char     * buffer,
    4139                 uint32_t   nbytes )
    4240{
    43         error_t    error;
    44     vseg_t   * vseg;
    45     char       kbuf[CONFIG_VFS_MAX_PATH_LENGTH];
    46  
     41        error_t       error;
     42    vseg_t      * vseg;
     43    char        * first;                   // first character valid in buffer
     44
     45    char          kbuf[CONFIG_VFS_MAX_PATH_LENGTH];
     46
    4747        thread_t  * this    = CURRENT_THREAD;
    4848    process_t * process = this->process;
     49
     50#if (DEBUG_SYS_GETCWD || CONFIG_INSTRUMENTATION_SYSCALLS)
     51uint64_t     tm_start = hal_get_cycles();
     52#endif
    4953
    5054    // check buffer size
     
    5357
    5458#if DEBUG_SYSCALLS_ERROR
    55 printk("\n[ERROR] in %s : buffer too small / thread %x / process %x\n",
    56 __FUNCTION__ , this->trdid , process->pid );
     59printk("\n[ERROR] in %s : buffer too small for thread %x,%x]\n",
     60__FUNCTION__ , process->pid, this->trdid );
    5761#endif
    5862                this->errno = EINVAL;
     
    6165
    6266    // check buffer in user space
    63     error = vmm_get_vseg( process, (intptr_t)buf , &vseg );
     67    error = vmm_get_vseg( process, (intptr_t)buffer , &vseg );
    6468
    6569        if( error )
     
    6771
    6872#if DEBUG_SYSCALLS_ERROR
    69 printk("\n[ERROR] in %s : user buffer unmapped %x / thread %x / process %x\n",
    70 __FUNCTION__ , (intptr_t)buf , this->trdid , process->pid );
     73printk("\n[ERROR] in %s : user buffer unmapped %x for thread[%x,%x]\n",
     74__FUNCTION__ , (intptr_t)buffer , process->pid, this->trdid );
    7175#endif
    7276                this->errno = EINVAL;
     
    7478        }
    7579
    76     // get reference process cluster and local pointer
     80#if DEBUG_SYS_GETCWD
     81if( DEBUG_SYS_GETCWD < tm_start )
     82printk("\n[%s] thread[%x,%x] enter / cycle %d\n",
     83__FUNCTION__, process->pid, this->trdid, (uint32_t)tm_start );
     84#endif
     85
     86    // get extended pointer on CWD inode from the reference process
    7787    xptr_t      ref_xp  = process->ref_xp;
     88    process_t * ref_ptr = GET_PTR( ref_xp );
    7889    cxy_t       ref_cxy = GET_CXY( ref_xp );
    79     process_t * ref_ptr = (process_t *)GET_PTR( ref_xp );
    80 
    81     // get CWD lock in read mode
    82         remote_rwlock_rd_acquire( XPTR( ref_cxy , &ref_ptr->cwd_lock ) );
     90    xptr_t      cwd_xp  = hal_remote_l64( XPTR( ref_cxy , &ref_ptr->cwd_xp ) );
    8391
    8492    // call relevant VFS function
    85         error = vfs_get_path( XPTR( ref_cxy , &ref_ptr->vfs_cwd_xp ) ,
    86                           kbuf , CONFIG_VFS_MAX_PATH_LENGTH );
    87 
    88     // release CWD lock in read mode
    89         remote_rwlock_rd_release( XPTR( ref_cxy , &ref_ptr->cwd_lock ) );
     93        error = vfs_get_path( cwd_xp,
     94                          kbuf,
     95                          &first,
     96                          CONFIG_VFS_MAX_PATH_LENGTH );
    9097
    9198    // copy kernel buffer to user space
    92     hal_copy_to_uspace( buf , kbuf , CONFIG_VFS_MAX_PATH_LENGTH );
     99    hal_strcpy_to_uspace( buffer , first , CONFIG_VFS_MAX_PATH_LENGTH );
    93100
    94101    hal_fence();
     102
     103#if (DEBUG_SYS_GETCWD || CONFIG_INSTRUMENTATION_SYSCALLS)
     104uint64_t     tm_end = hal_get_cycles();
     105#endif
     106
     107#if DEBUG_SYS_GETCWD
     108if( DEBUG_SYS_GETCWD < tm_end )
     109printk("\n[%s] thread[%x,%x] exit / cycle %d\n",
     110__FUNCTION__, process->pid, this->trdid, (uint32_t)tm_end );
     111#endif
     112 
     113#if CONFIG_INSTRUMENTATION_SYSCALLS
     114hal_atomic_add( &syscalls_cumul_cost[SYS_GETCWD] , tm_end - tm_start );
     115hal_atomic_add( &syscalls_occurences[SYS_GETCWD] , 1 );
     116#endif
    95117
    96118        return 0;
  • trunk/kernel/syscalls/sys_mkdir.c

    r566 r610  
    11/*
    2  * sys_mkdir.c - Create a new directory in file system.
     2 * sys_mkdir.c - creates a new directory in VFS
    33 *
    4  * Author    Alain Greiner (2016,2017)
     4 * Author     Alain Greiner (2016,2017,2018)
    55 *
    6  * Copyright (c) UPMC Sorbonne Universites
     6 * Copyright (c)  UPMC Sorbonne Universites
    77 *
    8  * This file is part of ALMOS-MKH.
     8 * This file is part of ALMOS-kernel.
    99 *
    1010 * ALMOS-MKH is free software; you can redistribute it and/or modify it
     
    2222 */
    2323
     24#include <kernel_config.h>
    2425#include <hal_kernel_types.h>
    2526#include <hal_uspace.h>
     27#include <errno.h>
    2628#include <vfs.h>
    27 #include <vmm.h>
    28 #include <errno.h>
    2929#include <process.h>
    3030#include <thread.h>
    3131#include <printk.h>
    3232
    33 ///////////////////////////////////
    34 int sys_mkdir( char     * pathname,
    35                uint32_t   mode __attribute__((unused)) )
     33#include <syscalls.h>
     34
     35////////////////////////////////////
     36int sys_mkdir ( char     * pathname,
     37                uint32_t   rights __attribute__((unused)) )
    3638{
    37     error_t        error;
    38     char           kbuf[CONFIG_VFS_MAX_PATH_LENGTH];
     39    error_t   error;
     40    xptr_t    root_inode_xp;                     // extended pointer on root inode
     41    char      kbuf[CONFIG_VFS_MAX_PATH_LENGTH];
    3942
    4043    thread_t     * this     = CURRENT_THREAD;
    4144    process_t    * process  = this->process;
    4245
    43     // check fd_array not full
    44     if( process_fd_array_full() )
     46#if (DEBUG_SYS_MKDIR || CONFIG_INSTRUMENTATION_SYSCALLS)
     47uint64_t     tm_start = hal_get_cycles();
     48#endif
     49
     50    // check pathname length
     51    if( hal_strlen_from_uspace( pathname ) >= CONFIG_VFS_MAX_PATH_LENGTH )
    4552    {
    46         printk("\n[ERROR] in %s : file descriptor array full for process %x\n",
    47                __FUNCTION__ , process->pid );
     53
     54#if DEBUG_SYSCALLS_ERROR
     55printk("\n[ERROR] in %s : pathname too long\n", __FUNCTION__ );
     56#endif
    4857        this->errno = ENFILE;
    4958        return -1;
    5059    }
    5160
    52     // check pathname length
    53     if( hal_strlen_from_uspace( pathname ) >= CONFIG_VFS_MAX_PATH_LENGTH )
     61    // copy pathname in kernel space
     62    hal_strcpy_from_uspace( kbuf , pathname , CONFIG_VFS_MAX_PATH_LENGTH );
     63
     64#if DEBUG_SYS_MKDIR
     65if( DEBUG_SYS_MKDIR < tm_start )
     66printk("\n[%s] thread[%x,%x] enter for <%s> / cycle %d\n",
     67__FUNCTION__, process->pid, this->trdid, kbuf, (uint32_t)tm_start );
     68#endif
     69 
     70    // compute root inode for path
     71    if( kbuf[0] == '/' )                        // absolute path
    5472    {
    55         printk("\n[ERROR] in %s : pathname too long\n", __FUNCTION__ );
     73        // use extended pointer on VFS root inode
     74        root_inode_xp = process->vfs_root_xp;
     75    }
     76    else                                        // relative path
     77    {
     78        // get cluster and local pointer on reference process
     79        xptr_t      ref_xp  = process->ref_xp;
     80        process_t * ref_ptr = (process_t *)GET_PTR( ref_xp );
     81        cxy_t       ref_cxy = GET_CXY( ref_xp );
     82
     83        // use extended pointer on CWD inode
     84        root_inode_xp = hal_remote_l64( XPTR( ref_cxy , &ref_ptr->cwd_xp ) );
     85    }
     86
     87    // call relevant VFS function
     88    error  = vfs_mkdir( root_inode_xp , kbuf , rights );
     89
     90    if( error )
     91    {
     92
     93#if DEBUG_SYSCALLS_ERROR
     94printk("\n[ERROR] in %s : cannot create directory <%s>\n", __FUNCTION__, kbuf );
     95#endif
    5696        this->errno = ENFILE;
    5797        return -1;
    5898    }
    5999
    60     printk("\n[ERROR] in %s : not implemented yet\n", __FUNCTION__ );
    61     return -1;
    62    
    63     // copy pathname in kernel space
    64     hal_strcpy_from_uspace( kbuf , pathname , CONFIG_VFS_MAX_PATH_LENGTH );
     100#if (DEBUG_SYS_MKDIR || CONFIG_INSTRUMENTATION_SYSCALLS)
     101uint64_t     tm_end = hal_get_cycles();
     102#endif
    65103
    66     // get cluster and local pointer on reference process
    67     // xptr_t      ref_xp  = process->ref_xp;
    68     // process_t * ref_ptr = (process_t *)GET_PTR( ref_xp );
    69     // cxy_t       ref_cxy = GET_CXY( ref_xp );
    70 
    71     // get extended pointer on cwd inode
    72     // xptr_t cwd_xp = hal_remote_l64( XPTR( ref_cxy , &ref_ptr->vfs_cwd_xp ) );
    73 
    74     // get the cwd lock in read mode from reference process
    75     // remote_rwlock_rd_lock( XPTR( ref_cxy , &ref_ptr->cwd_lock ) );
    76 
    77     // call the relevant VFS function
    78     // error = vfs_mkdir( cwd_xp,
    79     //                   kbuf,
    80     //                   mode );
    81 
    82     // release the cwd lock
    83     // remote_rwlock_rd_unlock( XPTR( ref_cxy , &ref_ptr->cwd_lock ) );
    84 
    85     if( error )
    86     {
    87         printk("\n[ERROR] in %s : cannot create directory %s\n",
    88                __FUNCTION__ , kbuf );
    89         this->errno = error;
    90         return -1;
    91     }
     104#if DEBUG_SYS_MKDIR
     105if( DEBUG_SYS_MKDIR < tm_end )
     106printk("\n[%s] thread[%x,%x] exit for <%s> / cycle %d\n",
     107__FUNCTION__, process->pid, this->trdid, kbuf, (uint32_t)tm_end );
     108#endif
     109 
     110#if CONFIG_INSTRUMENTATION_SYSCALLS
     111hal_atomic_add( &syscalls_cumul_cost[SYS_MKDIR] , tm_end - tm_start );
     112hal_atomic_add( &syscalls_occurences[SYS_MKDIR] , 1 );
     113#endif
    92114
    93115    return 0;
    94 }
     116
     117} // end sys_mkdir()
  • trunk/kernel/syscalls/sys_open.c

    r604 r610  
    4040{
    4141    error_t        error;
    42     xptr_t         file_xp;                          // extended pointer on vfs_file_t
    43     uint32_t       file_id;                          // file descriptor index
     42    xptr_t         file_xp;                 // extended pointer on vfs_file_t
     43    uint32_t       file_id;                 // file descriptor index
     44    xptr_t         root_inode_xp;           // extended pointer on path root inode
     45
    4446    char           kbuf[CONFIG_VFS_MAX_PATH_LENGTH];
    4547
     
    8890    cxy_t       ref_cxy = GET_CXY( ref_xp );
    8991
    90     // get the cwd lock in read mode from reference process
    91     remote_rwlock_rd_acquire( XPTR( ref_cxy , &ref_ptr->cwd_lock ) );
     92    // compute root inode for path
     93    if( kbuf[0] == '/' )                        // absolute path
     94    {
     95        // use extended pointer on VFS root inode
     96        root_inode_xp = process->vfs_root_xp;
     97    }
     98    else                                        // relative path
     99    {
     100        // use extended pointer on CWD inode
     101        root_inode_xp = hal_remote_l64( XPTR( ref_cxy , &ref_ptr->cwd_xp ) );
     102    }
    92103
    93104    // call the relevant VFS function
    94     error = vfs_open( process,
     105    error = vfs_open( root_inode_xp,
    95106                      kbuf,
     107                      ref_xp,
    96108                      flags,
    97109                      mode,
    98110                      &file_xp,
    99111                      &file_id );
    100 
    101     // release the cwd lock
    102     remote_rwlock_rd_release( XPTR( ref_cxy , &ref_ptr->cwd_lock ) );
    103112
    104113    if( error )
  • trunk/kernel/syscalls/sys_opendir.c

    r473 r610  
    22 * sys_opendir.c - open a directory.
    33 *
    4  * Author        Alain Greiner (2016,2017)
     4 * Author        Alain Greiner (2016,2017,2018)
    55 *
    66 * Copyright (c) UPMC Sorbonne Universites
     
    2323
    2424#include <hal_kernel_types.h>
     25#include <hal_uspace.h>
    2526#include <thread.h>
    2627#include <process.h>
     
    3536                  DIR  ** dirp )
    3637{
    37     printk("\n[ERROR] in %s : not implemented yet\n", __FUNCTION__, pathname, dirp );
    38     return -1;
    39 }  // end sys opendir()
     38    error_t       error;
     39    vseg_t      * vseg;                   // for user space checking
     40    xptr_t        root_inode_xp;          // extended pointer on path root inode
     41
     42    char          kbuf[CONFIG_VFS_MAX_PATH_LENGTH];
     43       
     44        thread_t  * this    = CURRENT_THREAD;
     45        process_t * process = this->process;
     46
     47#if (DEBUG_SYS_OPENDIR || CONFIG_INSTRUMENTATION_SYSCALLS)
     48uint64_t     tm_start = hal_get_cycles();
     49#endif
     50
     51    // check DIR buffer in user space
     52    error = vmm_get_vseg( process , (intptr_t)dirp, &vseg );
     53
     54        if( error )
     55        {
     56
     57#if DEBUG_SYSCALLS_ERROR
     58printk("\n[ERROR] in %s / thread[%x,%x] : DIR buffer %x unmapped\n",
     59__FUNCTION__ , process->pid , this->trdid, dirp );
     60vmm_display( process , false );
     61#endif
     62                this->errno = EINVAL;
     63                return -1;
     64        }       
     65
     66    // check pathname length
     67    if( hal_strlen_from_uspace( pathname ) >= CONFIG_VFS_MAX_PATH_LENGTH )
     68    {
     69
     70#if DEBUG_SYSCALLS_ERROR
     71printk("\n[ERROR] in %s / thread[%x,%x] : pathname too long\n",
     72 __FUNCTION__ , process->pid , this->trdid );
     73#endif
     74        this->errno = ENFILE;
     75        return -1;
     76    }
     77
     78    // copy pathname in kernel space
     79    hal_strcpy_from_uspace( kbuf , pathname , CONFIG_VFS_MAX_PATH_LENGTH );
     80
     81#if DEBUG_SYS_OPENDIR
     82if( DEBUG_SYS_OPENDIR < tm_start )
     83printk("\n[%s] thread[%x,%x] enter for directory <%s> / cycle %d\n",
     84__FUNCTION__, process->pid, this->trdid, kbuf, (uint32_t)tm_start );
     85#endif
     86
     87    // compute root inode for path
     88    if( kbuf[0] == '/' )                        // absolute path
     89    {
     90        // use extended pointer on VFS root inode
     91        root_inode_xp = process->vfs_root_xp;
     92    }
     93    else                                        // relative path
     94    {
     95        // get cluster and local pointer on reference process
     96        xptr_t      ref_xp  = process->ref_xp;
     97        process_t * ref_ptr = (process_t *)GET_PTR( ref_xp );
     98        cxy_t       ref_cxy = GET_CXY( ref_xp );
     99
     100        // use extended pointer on CWD inode
     101        root_inode_xp = hal_remote_l64( XPTR( ref_cxy , &ref_ptr->cwd_xp ) );
     102    }
     103
     104/*
     105    // call the relevant VFS function ???
     106    error = vfs_opendir( root_inode_xp,
     107                         kbuf );
     108    if( error )
     109        {
     110
     111#if DEBUG_SYSCALLS_ERROR
     112printk("\n[ERROR] in %s / thread[%x,%x] : cannot open directory <%s>\n",
     113__FUNCTION__ , process->pid , this->trdid , pathname );
     114#endif
     115                this->errno = ENFILE;
     116                return -1;
     117        }
     118   
     119    // copy to user space ???
     120*/
     121
     122    hal_fence();
     123
     124#if (DEBUG_SYS_OPENDIR || CONFIG_INSTRUMENTATION_SYSCALLS)
     125uint64_t     tm_end = hal_get_cycles();
     126#endif
     127
     128#if DEBUG_SYS_OPENDIR
     129if( DEBUG_SYS_OPENDIR < tm_end )
     130printk("\n[%s] thread[%x,%x] exit for directory <%s> / cycle %d\n",
     131__FUNCTION__, process->pid, this->trdid, kbuf, (uint32_t)tm_end );
     132#endif
     133 
     134#if CONFIG_INSTRUMENTATION_SYSCALLS
     135hal_atomic_add( &syscalls_cumul_cost[SYS_OPENDIR] , tm_end - tm_start );
     136hal_atomic_add( &syscalls_occurences[SYS_OPENDIR] , 1 );
     137#endif
     138
     139        return 0;
     140
     141}  // end sys_opendir()
  • trunk/kernel/syscalls/sys_read.c

    r604 r610  
    7878#if DEBUG_SYS_READ
    7979if( DEBUG_SYS_READ < tm_start )
    80 printk("\n[DBG] %s : thread[%x,%x] enter / vaddr %x / count %d / cycle %d\n",
     80printk("\n[%s] thread[%x,%x] enter / vaddr %x / count %d / cycle %d\n",
    8181__FUNCTION__, process->pid, this->trdid, vaddr, count, (uint32_t)tm_start );
    8282#endif
     
    246246#if DEBUG_SYS_READ
    247247if( DEBUG_SYS_READ < tm_end )
    248 printk("\n[DBG] %s : thread[%x,%x] exit / cycle %d\n",
     248printk("\n[%s] thread[%x,%x] exit / cycle %d\n",
    249249__FUNCTION__ , process->pid, this->trdid, (uint32_t)tm_end );
    250250#endif
  • trunk/kernel/syscalls/sys_stat.c

    r604 r610  
    11/*
    2  * sys_stat.c - Return statistics on a file or directory.
     2 * sys_stat.c - kernel function implementing the "stat" syscall.
    33 *
    44 * Author    Alain Greiner  (2016,2017,2018)
     
    4141    vseg_t      * vseg;                   // for user space checking
    4242    struct stat   k_stat;                 // in kernel space
    43     xptr_t        inode_xp;               // extended pointer on target inode
     43    xptr_t        root_inode_xp;          // extended pointer on path root inode
    4444
    4545    char          kbuf[CONFIG_VFS_MAX_PATH_LENGTH];
     
    5959
    6060#if DEBUG_SYSCALLS_ERROR
    61 printk("\n[ERROR] in %s / thread[%x,%x] : stat structure unmapped\n",
    62 __FUNCTION__ , process->pid , this->trdid );
     61printk("\n[ERROR] in %s / thread[%x,%x] : stat structure %x unmapped\n",
     62__FUNCTION__ , process->pid , this->trdid, u_stat );
    6363vmm_display( process , false );
    6464#endif
     
    8888#endif
    8989
    90     // get cluster and local pointer on reference process
    91     xptr_t      ref_xp  = process->ref_xp;
    92     process_t * ref_ptr = (process_t *)GET_PTR( ref_xp );
    93     cxy_t       ref_cxy = GET_CXY( ref_xp );
     90    // compute root inode for path
     91    if( kbuf[0] == '/' )                        // absolute path
     92    {
     93        // use extended pointer on VFS root inode
     94        root_inode_xp = process->vfs_root_xp;
     95    }
     96    else                                        // relative path
     97    {
     98        // get cluster and local pointer on reference process
     99        xptr_t      ref_xp  = process->ref_xp;
     100        process_t * ref_ptr = (process_t *)GET_PTR( ref_xp );
     101        cxy_t       ref_cxy = GET_CXY( ref_xp );
    94102
    95     // get extended pointer on cwd inode
    96     xptr_t cwd_xp = hal_remote_l64( XPTR( ref_cxy , &ref_ptr->vfs_cwd_xp ) );
    97 
    98     // get the cwd lock in read mode from reference process
    99     remote_rwlock_rd_acquire( XPTR( ref_cxy , &ref_ptr->cwd_lock ) );
    100 
    101     // get extended pointer on remote file descriptor
    102     error = vfs_lookup( cwd_xp,
    103                         kbuf,
    104                         0,
    105                         &inode_xp );
    106 
    107     // release the cwd lock
    108     remote_rwlock_rd_release( XPTR( ref_cxy , &ref_ptr->cwd_lock ) );
    109 
    110     if( error )
    111     {
    112 
    113 #if DEBUG_SYSCALLS_ERROR
    114 printk("\n[ERROR] in %s / thread[%x,%x] : cannot found file <%s>\n",
    115 __FUNCTION__ , process->pid , this->trdid , pathname );
    116 #endif
    117         this->errno = ENFILE;
    118         return -1;
     103        // use extended pointer on CWD inode
     104        root_inode_xp = hal_remote_l64( XPTR( ref_cxy , &ref_ptr->cwd_xp ) );
    119105    }
    120106
    121 #if (DEBUG_SYS_STAT & 1)
    122 if( DEBUG_SYS_STAT < tm_start )
    123 printk("\n[%s] thread[%x,%x] got inode %x in cluster %x for <%s>\n",
    124 __FUNCTION__, process->pid, this->trdid, GET_PTR(inode_xp), GET_CXY(inode_xp), kbuf );
    125 #endif
    126 
    127     // call VFS function to get stat info
    128     error = vfs_stat( inode_xp,
    129                       &k_stat );
     107    // call the relevant VFS function
     108    error = vfs_stat( root_inode_xp,
     109                      kbuf,
     110                      &k_stat );
    130111    if( error )
    131112        {
     
    139120        }
    140121   
    141 #if (DEBUG_SYS_STAT & 1)
    142 if( DEBUG_SYS_STAT < tm_start )
    143 printk("\n[%s] thread[%x,%x] set kstat : inum %d / size %d / mode %d\n",
    144 __FUNCTION__, process->pid, this->trdid, k_stat.st_ino, k_stat.st_size, k_stat.st_mode );
    145 #endif
    146 
    147122    // copy k_stat to u_stat
    148123    hal_copy_to_uspace( u_stat , &k_stat , sizeof(struct stat) );
  • trunk/kernel/syscalls/sys_unlink.c

    r604 r610  
    11/*
    2  * sys_unlink.c - file unlink a file
     2 * sys_unlink.c - unlink a file or directorya from VFS
    33 *
    44 * Author     Alain Greiner (2016,2017,2018)
     
    3737{
    3838    error_t   error;
     39    xptr_t    root_inode_xp;           // extended pointer on path root inode
     40
    3941    char      kbuf[CONFIG_VFS_MAX_PATH_LENGTH];
    4042
     
    6668#endif
    6769 
    68     // get cluster and local pointer on reference process
    69     xptr_t      ref_xp  = process->ref_xp;
    70     process_t * ref_ptr = (process_t *)GET_PTR( ref_xp );
    71     cxy_t       ref_cxy = GET_CXY( ref_xp );
     70    // compute root inode for path
     71    if( kbuf[0] == '/' )                        // absolute path
     72    {
     73        // use extended pointer on VFS root inode
     74        root_inode_xp = process->vfs_root_xp;
     75    }
     76    else                                        // relative path
     77    {
     78        // get cluster and local pointer on reference process
     79        xptr_t      ref_xp  = process->ref_xp;
     80        process_t * ref_ptr = (process_t *)GET_PTR( ref_xp );
     81        cxy_t       ref_cxy = GET_CXY( ref_xp );
    7282
    73     // get the cwd lock in write mode from reference process
    74     remote_rwlock_wr_acquire( XPTR( ref_cxy , &ref_ptr->cwd_lock ) );
     83        // use extended pointer on CWD inode
     84        root_inode_xp = hal_remote_l64( XPTR( ref_cxy , &ref_ptr->cwd_xp ) );
     85    }
    7586
    76     // get extended pointer on cwd inode
    77     xptr_t cwd_xp = hal_remote_l64( XPTR( ref_cxy , &ref_ptr->vfs_cwd_xp ) );
    78 
    79     // call relevant VFS function
    80     error  = vfs_unlink( cwd_xp , kbuf );
    81 
    82     // release the cwd lock in reference process
    83     remote_rwlock_wr_release( XPTR( ref_cxy , &ref_ptr->cwd_lock ) );
     87    // call the relevant VFS function
     88    error  = vfs_unlink( root_inode_xp , kbuf );
    8489
    8590    if( error )
  • trunk/kernel/syscalls/sys_write.c

    r604 r610  
    7777tm_start = hal_get_cycles();
    7878if( DEBUG_SYS_WRITE < tm_start )
    79 printk("\n[DBG] %s : thread[%x,%x] enter / vaddr %x / count %d / cycle %d\n",
     79printk("\n[%s] thread[%x,%x] enter / vaddr %x / count %d / cycle %d\n",
    8080__FUNCTION__, process->pid, this->trdid, vaddr, count, (uint32_t)tm_start );
    8181#endif
     
    223223#if DEBUG_SYS_WRITE
    224224if( DEBUG_SYS_WRITE < tm_end )
    225 printk("\n[DBG] %s : thread[%x,%x] exit / cycle %d\n",
     225printk("\n[%s] thread[%x,%x] exit / cycle %d\n",
    226226__FUNCTION__, process->pid, this->trdid, (uint32_t)tm_end );
    227227#endif
  • trunk/kernel/syscalls/syscalls.h

    r594 r610  
    170170
    171171/******************************************************************************************
    172  * [10] This function implement the exit system call terminating a POSIX process.
    173  * It can be called by any thread running in any cluster.
    174  * It uses both remote accesses to access the owner process descriptor, and the
    175  * RPC_PROCESS_SIGACTION to delete remote process and thread descriptors.
    176  * In the present implementation, this function implements actually the _exit():
    177  * - it does not flush open output streams.
    178  * - it does not close open streams.
    179  ******************************************************************************************
    180  * @ status   : terminaison status (not used in present implementation).
    181  *****************************************************************************************/
    182 int sys_exit( uint32_t status );
     172 * [10] This function causes the file named <old> to be renamed as <new>.
     173 * If new exists, it is first removed.  Both old and new must be of the same type (both
     174 * must be either directories or non-directories) and must reside on the same file system.
     175 * It guarantees that an instance of <new> will always exist, even if the system should
     176 * crash in the middle of the operation.
     177 ******************************************************************************************
     178 * @ old      : old file name.
     179 * @ new      : new file name.
     180 * @ return 0 if success / return -1 if failure.
     181 *****************************************************************************************/
     182int sys_rename( char *old,
     183                char *new );
    183184
    184185/******************************************************************************************
     
    301302
    302303/******************************************************************************************
    303  * [21] This function creates a new directory in file system.
    304  ******************************************************************************************
    305  * @ pathname   : pathname (can be relative or absolute).
    306  * @ mode       : access rights (as defined in chmod).
    307  * @ return 0 if success / returns -1 if failure.
    308  *****************************************************************************************/
    309 int sys_mkdir( char    * pathname,
    310                uint32_t  mode );
     304 * [21] This function implements the "mkdir" system call, creating a new directory in
     305 * the file system, as defined by the <pathname> argument, with the access permission
     306 * defined by the <rights> argument. All nodes but the last in the pathname must exist.
     307 * It can be called by any thread running in any cluster.
     308 ******************************************************************************************
     309 * @ pathname  : pathname defining the new directory location in file system.
     310 * @ rights    : access rights (non used yet).
     311 * @ return 0 if success / return -1 if failure.
     312 *****************************************************************************************/
     313int sys_mkdir( char     * pathname,
     314               uint32_t   rights );
    311315
    312316/******************************************************************************************
     
    653657               uint32_t * is_fg );
    654658
     659/******************************************************************************************
     660 * [50] This function implements the exit system call terminating a POSIX process.
     661 * It can be called by any thread running in any cluster.
     662 * It uses both remote accesses to access the owner process descriptor, and the
     663 * RPC_PROCESS_SIGACTION to delete remote process and thread descriptors.
     664 * In the present implementation, this function implements actually the _exit():
     665 * - it does not flush open output streams.
     666 * - it does not close open streams.
     667 ******************************************************************************************
     668 * @ status   : terminaison status.
     669 *****************************************************************************************/
     670int sys_exit( uint32_t status );
     671
    655672#endif  // _SYSCALLS_H_
  • trunk/libs/libalmosmkh/almosmkh.h

    r597 r610  
    132132/***************************************************************************************
    133133 * This debug function displays on the kernel terminal TXT0
    134  * the state of the  VMM for the process <pid>, in cluster <cxy>.
     134 * the state of the  VMM for the process <pid> in cluster <cxy>.
    135135 * It can be called by any thread running in any cluster.
    136136 ***************************************************************************************
  • trunk/libs/mini-libc/stdio.c

    r580 r610  
    2323
    2424#include <stdio.h>
     25#include <hal_shared_types.h>
     26#include <hal_user.h>
     27#include <syscalls_numbers.h>
    2528#include <stdarg.h>
    2629#include <almosmkh.h>
     
    3740//          stdio library functions
    3841////////////////////////////////////////////////////////////////////////////////////////
     42
     43/////////////////////////////
     44int rename( const char * old,
     45            const char * new )
     46{
     47    return hal_user_syscall( SYS_RENAME,
     48                             (reg_t)old,
     49                             (reg_t)new, 0, 0 );   
     50}
    3951
    4052///////////////////////////////////////////////////
  • trunk/libs/mini-libc/stdio.h

    r476 r610  
    4646}
    4747FILE;
     48
     49/*********************************************************************************************
     50 * This function causes the file/directory named <old> to be renamed as <new>.
     51 * If <new> exists, it is previously removed.
     52 *********************************************************************************************
     53 * @ returns 0 if success / returns -1 if failure.
     54 ********************************************************************************************/
     55int rename( const char * old,
     56            const char * new );
    4857
    4958/*********************************************************************************************
  • trunk/libs/mini-libc/unistd.h

    r589 r610  
    4848
    4949/*****************************************************************************************
    50  * This function change the current working directory in reference process descriptor.
     50 * This function change the current working directory in the reference process descriptor.
    5151 *****************************************************************************************
    5252 * @ pathname   : pathname (can be relative or absolute).
  • trunk/params-hard.mk

    r590 r610  
    22
    33ARCH      = /users/alain/soc/tsar-trunk-svn-2013/platforms/tsar_generic_iob
    4 X_SIZE    = 2
     4X_SIZE    = 1
    55Y_SIZE    = 2
    6 NB_PROCS  = 2
    7 NB_TTYS   = 3
     6NB_PROCS  = 1
     7NB_TTYS   = 2
    88IOC_TYPE  = IOC_BDV
    99TXT_TYPE  = TXT_TTY
  • trunk/params-soft.mk

    r466 r610  
    1818ifeq ($(ARCH_NAME),)
    1919$(error Please define ARCH_NAME parameter in params-soft.mk!)
     20endif
     21
     22ifeq ($(LIBC_NAME),)
     23$(error Please define LIBC_NAME parameter in params-soft.mk!)
    2024endif
    2125
  • trunk/user/ksh/ksh.c

    r608 r610  
    5555
    5656#define MAIN_DEBUG          0
     57
     58#define CMD_CAT_DEBUG       0
     59#define CMD_CP_DEBUG        0
    5760#define CMD_LOAD_DEBUG      0
    58 #define CMD_CAT_DEBUG       0
    5961
    6062//////////////////////////////////////////////////////////////////////////////////////////
     
    209211            path = argv[1];
    210212
    211         printf("  error: not implemented yet\n" );
     213        // call the relevant syscall
     214        if( chdir( path ) )
     215        {
     216            printf("  error: cannot found <%s> directory\n", path );
     217        }
    212218    }
    213219
     
    250256    }
    251257
     258#if CMD_CP_DEBUG
     259long long unsigned cycle;
     260get_cycle( &cycle );
     261printf("\n[%s] open file <%s> done / cycle %d\n",
     262__FUNCTION__ , srcpath , (int)cycle );
     263#endif
     264
    252265    // get file stats
    253266    if ( stat( srcpath , &st ) )
     
    258271    }
    259272
     273#if CMD_CP_DEBUG
     274get_cycle( &cycle );
     275printf("\n[%s] stats file <%s> done / cycle %d\n",
     276__FUNCTION__ , srcpath , (int)cycle );
     277#endif
     278
    260279        if ( S_ISDIR(st.st_mode) )
    261280    {
     
    277296        }
    278297
     298#if CMD_CP_DEBUG
     299get_cycle( &cycle );
     300printf("\n[%s] open file <%s> done / cycle %d\n",
     301__FUNCTION__ , dstpath , (int)cycle );
     302#endif
     303
    279304        if ( stat( dstpath , &st ) )
    280305    {
     
    282307                goto exit;
    283308        }
     309
     310#if CMD_CP_DEBUG
     311get_cycle( &cycle );
     312printf("\n[%s] stats file <%s> done / cycle %d\n",
     313__FUNCTION__ , dstpath , (int)cycle );
     314#endif
    284315
    285316        if ( S_ISDIR(st.st_mode ) )
     
    302333                }
    303334
     335#if CMD_CP_DEBUG
     336get_cycle( &cycle );
     337printf("\n[%s] %d bytes read from <%s> / cycle %d\n",
     338__FUNCTION__ , len, srcpath , (int)cycle );
     339#endif
     340
    304341                // write to the destination
    305342                if ( write( dst_fd , buf , len ) != len )
     
    308345                        goto exit;
    309346                }
     347
     348#if CMD_CP_DEBUG
     349get_cycle( &cycle );
     350printf("\n[%s] %d bytes writen to <%s> / cycle %d\n",
     351__FUNCTION__ , len, dstpath , (int)cycle );
     352#endif
    310353
    311354                bytes += len;
     
    733776        pathname = argv[1];
    734777
    735         printf("  error: not implemented yet\n");
     778        mkdir( pathname , 0x777 );
    736779    }
    737780
     
    744787static void cmd_mv( int argc , char **argv )
    745788{
    746 
    747         if (argc < 3)
    748         {
    749                 printf("  usage : mv src_pathname dst_pathname\n");
     789        char * old_path;
     790    char * new_path;
     791
     792        if (argc != 3)
     793    {
     794                printf("  usage: mv old_pathname new_pathname\n");
    750795        }
    751796    else
    752797    {
    753         printf("  error: not implemented yet\n");
    754     }
    755    
     798        old_path = argv[1];
     799        new_path = argv[2];
     800
     801        // call the relevant syscall
     802        if( rename( old_path , new_path ) )
     803        {
     804            printf("  error: unable to rename <%s> to <%s>\n", old_path, new_path );
     805        }
     806    }
     807
    756808    // release semaphore to get next command
    757809    sem_post( &semaphore );
     
    9961048
    9971049
    998 /* To lauch one application without interactive mode
     1050// To lauch one command without interactive mode
    9991051   
    10001052if( sem_wait( &semaphore ) )
     
    10051057else
    10061058{
    1007     printf("\n[ksh] for fft\n");
     1059    printf("\n[ksh] cp /home/Makefile /home/bloup\n");
    10081060}
    10091061
    1010 strcpy( buf , "load /bin/user/fft.elf" );
     1062strcpy( buf , "cp /home/Makefile /home/bloup" );
    10111063parse( buf );
    10121064
    1013 */
     1065//
    10141066
    10151067        enum fsm_states
Note: See TracChangeset for help on using the changeset viewer.