Changeset 602 for trunk/kernel/fs/vfs.c


Ignore:
Timestamp:
Dec 3, 2018, 12:15:53 PM (5 years ago)
Author:
alain
Message:

Improve the FAT32 file system to support cat, rm, cp commands.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/kernel/fs/vfs.c

    r598 r602  
    5757extern char *             lock_type_str[];            // allocated in kernel_init.c
    5858 
    59 //////////////////////////////////////////////////////////////////////////////////////////
    60 //           Context related functions
     59///////////////////////////////////////////////////////////////////////////////////////////
     60//           VFS Context related functions
    6161//////////////////////////////////////////////////////////////////////////////////////////
    6262
     
    123123
    124124//////////////////////////////////////////////////////////////////////////////////////////
    125 //           Inode related functions
     125//           VFS inode descriptor related functions
    126126//////////////////////////////////////////////////////////////////////////////////////////
    127127
     
    145145                          vfs_fs_type_t     fs_type,
    146146                          vfs_inode_type_t  inode_type,
    147                           void            * extend,
    148147                          uint32_t          attr,
    149148                          uint32_t          rights,
     
    228227    inode->ctx        = ctx;
    229228    inode->mapper     = mapper;
    230     inode->extend     = extend;
     229    inode->extend     = NULL;
    231230
    232231    // initialise inode field in mapper
     
    258257}  // end vfs_inode_create() 
    259258
    260 ////////////////////////////////////////////////
    261 error_t vfs_inode_destroy( vfs_inode_t * inode )
    262 {
    263     assert( (inode->refcount == 0) , "inode refcount non zero\n" );
     259/////////////////////////////////////////////
     260void vfs_inode_destroy( vfs_inode_t * inode )
     261{
     262
     263// check inode refcount
     264assert( (inode->refcount == 0) , "inode refcount non zero\n" );
    264265
    265266    // release memory allocated for mapper
     
    272273        kmem_free( &req );
    273274
    274     return 0;
    275 
    276275}  // end vfs_inode_destroy()
    277 
    278 /////////////////////////////////////////////
    279 error_t vfs_inode_load( vfs_inode_t * parent,
    280                         char        * name,
    281                         xptr_t        child_xp )
    282 {
    283 
    284 #if DEBUG_VFS_INODE_LOAD
    285 uint32_t cycle = (uint32_t)hal_get_cycles();
    286 if( DEBUG_VFS_INODE_LOAD < cycle )
    287 printk("\n[%s] thread %x enter for <%s> / cycle %d\n",
    288 __FUNCTION__, CURRENT_THREAD , name , cycle );
    289 #endif
    290 
    291     error_t error = 0;
    292 
    293     assert( (parent != NULL) , "parent pointer is NULL\n");
    294 
    295     assert( (child_xp != XPTR_NULL) , "child pointer is NULL\n");
    296 
    297     // get parent inode FS type
    298     vfs_fs_type_t fs_type = parent->ctx->type;
    299 
    300     // call relevant FS function
    301     if( fs_type == FS_TYPE_FATFS )
    302     {
    303         error = fatfs_inode_load( parent , name , child_xp );
    304     }
    305     else if( fs_type == FS_TYPE_RAMFS )
    306     {
    307         assert( false , "should not be called for RAMFS\n" );
    308     }
    309     else if( fs_type == FS_TYPE_DEVFS )
    310     {
    311         assert( false , "should not be called for DEVFS\n" );
    312     }
    313     else
    314     {
    315         assert( false , "undefined file system type\n" );
    316     }
    317 
    318 #if DEBUG_VFS_INODE_LOAD
    319 cycle = (uint32_t)hal_get_cycles();
    320 if( DEBUG_VFS_INODE_LOAD < cycle )
    321 printk("\n[%s] thread %x exit for <%s> / cycle %d\n",
    322 __FUNCTION__, CURRENT_THREAD , name , cycle );
    323 #endif
    324 
    325     return error;
    326 
    327 } // end vfs_inode_load()
    328276
    329277////////////////////////////////////////////
     
    429377}  // end vfs_inode_get_name()
    430378
     379///////////////////////////////////////////////////////
     380error_t vfs_inode_load_all_pages( vfs_inode_t * inode )
     381{
     382
     383assert( (inode != NULL) , "inode pointer is NULL\n" );
     384
     385    uint32_t   page_id;
     386    xptr_t     page_xp;
     387
     388    mapper_t * mapper = inode->mapper;
     389    uint32_t   size   = inode->size;
     390
     391assert( (mapper != NULL) , "mapper pointer is NULL\n" );
     392
     393#if DEBUG_VFS_INODE_LOAD_ALL
     394uint32_t   cycle = (uint32_t)hal_get_cycles();
     395thread_t * this  = CURRENT_THREAD;
     396char       name[CONFIG_VFS_MAX_NAME_LENGTH];
     397vfs_inode_get_name( XPTR( local_cxy , inode ) , name );
     398if( DEBUG_VFS_INODE_LOAD_ALL < cycle )
     399printk("\n[%s] thread[%x,%x] enter for <%s> in cluster %x / cycle %d\n",
     400__FUNCTION__, this->process->pid, this->trdid, name, local_cxy, cycle );
     401#endif
     402
     403    // compute number of pages
     404    uint32_t npages = size >> CONFIG_PPM_PAGE_SHIFT;
     405    if( (size & CONFIG_PPM_PAGE_MASK) || (size == 0) ) npages++;
     406
     407    // loop on pages
     408    for( page_id = 0 ; page_id < npages ; page_id ++ )
     409    {
     410        // If the mage is missing, this function allocates the missing page,
     411        // and load the page from IOC device into mapper
     412        page_xp = mapper_remote_get_page( XPTR( local_cxy , mapper ), page_id );
     413
     414        if( page_xp == XPTR_NULL ) return -1;
     415    }
     416
     417#if DEBUG_VFS_INODE_LOAD_ALL
     418cycle = (uint32_t)hal_get_cycles();
     419if( DEBUG_VFS_INODE_LOAD_ALL < cycle )
     420printk("\n[%s] thread[%x,%x] exit for <%x> in cluster %x / cycle %d\n",
     421__FUNCTION__, this->process->pid, this->trdid, name, local_cxy, cycle );
     422#endif
     423
     424    return 0;
     425
     426}  // end vfs_inode_load_all_pages()
     427
    431428////////////////////////////////////////////////////////////////////////////////////////////
    432 //           Dentry related functions
     429//          VFS dentry descriptor related functions
    433430//////////////////////////////////////////////////////////////////////////////////////////
    434431
     
    480477    dentry->length  = length;
    481478    dentry->parent  = parent;
     479    dentry->extend  = NULL;
    482480    strcpy( dentry->name , name );
    483481
     
    509507cycle = (uint32_t)hal_get_cycles();
    510508if( DEBUG_VFS_DENTRY_CREATE < cycle )
    511 printk("\n[%s] thread[%x,%x] exit for <%s> / dentry %x / cycle %d\n",
    512 __FUNCTION__, this->process->pid, this->trdid, name, dentry, cycle );
     509printk("\n[%s] thread[%x,%x] exit for <%s> / dentry [%x,%x] / cycle %d\n",
     510__FUNCTION__, this->process->pid, this->trdid, name, local_cxy, dentry, cycle );
    513511#endif
    514512
     
    517515}  // end vfs_dentry_create()
    518516
    519 ///////////////////////////////////////////////////
    520 error_t vfs_dentry_destroy( vfs_dentry_t * dentry )
    521 {
    522     error_t error;
    523 
    524     assert( (dentry->refcount == 0) , __FUNCTION__ , "dentry refcount non zero\n" );
     517////////////////////////////////////////////////
     518void vfs_dentry_destroy( vfs_dentry_t * dentry )
     519{
     520
     521// check dentry refcount
     522assert( (dentry->refcount == 0) , "dentry refcount non zero\n" );
    525523
    526524    // get pointer on parent inode
     
    528526
    529527    // remove this dentry from parent inode htab
    530     error = xhtab_remove( XPTR( local_cxy , &parent->children ),
    531                           dentry->name,
    532                           XPTR( local_cxy , &dentry->list ) );
    533 
    534     if( error ) return EINVAL;     
     528    xhtab_remove( XPTR( local_cxy , &parent->children ),
     529                  dentry->name,
     530                  XPTR( local_cxy , &dentry->list ) );
    535531
    536532    // release memory allocated to dentry
     
    540536        kmem_free( &req );
    541537
    542     return 0;
     538}  // end vfs_dentry_destroy()
     539
     540//////////////////////////////////////////////
     541void 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 );   
    543548}
    544549
     550////////////////////////////////////////////////
     551void 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
    545560
    546561
    547562//////////////////////////////////////////////////////////////////////////////////////////
    548 //           File descriptor related functions
     563//       VFS file descriptor related functions
    549564//////////////////////////////////////////////////////////////////////////////////////////
    550565
     
    645660
    646661//////////////////////////////////////////////////////////////////////////////////////////
    647 //           File access related functions
     662//           "syscalls" API related functions
    648663//////////////////////////////////////////////////////////////////////////////////////////
    649664
     
    665680    uint32_t      file_id;      // created file descriptor index in reference fd_array
    666681
    667     assert( (mode == 0), __FUNCTION__,
    668     "the mode parameter is not supported yet\n" );
     682
     683    if( mode != 0 )
     684    {
     685        printk("\n[ERROR] in %s : the mode parameter is not supported yet\n" );
     686        return -1;
     687    }
    669688
    670689#if DEBUG_VFS_OPEN
     
    736755                   uint32_t size )
    737756{
    738     assert( ( file_xp != XPTR_NULL ) , "file_xp == XPTR_NULL" );
    739 
    740757    cxy_t              file_cxy;     // remote file descriptor cluster
    741758    vfs_file_t       * file_ptr;     // remote file descriptor local pointer
     
    745762    error_t            error;
    746763
     764// check argument
     765assert( (file_xp != XPTR_NULL), "file_xp == XPTR_NULL\n" );
     766
    747767    // get cluster and local pointer on remote file descriptor
    748768    file_cxy  = GET_CXY( file_xp );
     
    752772    inode_type = hal_remote_l32( XPTR( file_cxy , &file_ptr->type   ) );
    753773   
    754     assert( (inode_type == INODE_TYPE_FILE) ,
    755     "inode type is not INODE_TYPE_FILE" );
     774// check inode type
     775assert( (inode_type == INODE_TYPE_FILE), "inode type is not INODE_TYPE_FILE" );
    756776
    757777    // get mapper pointer and file offset from file descriptor
     
    770790    else
    771791    {
    772         rpc_mapper_move_buffer_client( file_cxy,
    773                                        mapper,
    774                                        to_buffer,
    775                                        true,          // user buffer
    776                                        file_offset,
    777                                        (uint64_t)(intptr_t)buffer,
    778                                        size,
    779                                        &error );
     792        rpc_mapper_move_user_client( file_cxy,
     793                                     mapper,
     794                                     to_buffer,
     795                                     file_offset,
     796                                     buffer,
     797                                     size,
     798                                     &error );
    780799    }
    781800
    782     if( error ) return -1;
    783     else        return size;
     801    // update file offset in file descriptor
     802    hal_remote_atomic_add( XPTR( file_cxy , &file_ptr->offset ) , size );
     803
     804    if( error )
     805    {
     806        return -1;
     807    }
     808
     809    return size;
    784810
    785811}  // end vfs_user_move()
     
    791817                         uint32_t size )
    792818{
    793     assert( ( file_xp != XPTR_NULL ) , "file_xp == XPTR_NULL" );
    794 
    795819    cxy_t              file_cxy;     // remote file descriptor cluster
    796820    vfs_file_t       * file_ptr;     // remote file descriptor local pointer
    797     vfs_inode_type_t   inode_type;
     821    vfs_inode_type_t   inode_type;   // remote file type
    798822    uint32_t           file_offset;  // current offset in file
    799     mapper_t         * mapper;
     823    mapper_t         * mapper_ptr;   // remote mapper local pointer
     824    xptr_t             mapper_xp;    // remote mapper extended pointer
    800825    error_t            error;
     826
     827// check argument
     828assert( (file_xp != XPTR_NULL) , "file_xp == XPTR_NULL\n" );
    801829
    802830    // get cluster and local pointer on remote file descriptor
     
    810838    if( inode_type == INODE_TYPE_FILE )
    811839    {
    812         // get mapper pointer and file offset from file descriptor
     840        // get mapper pointers and file offset from file descriptor
    813841        file_offset = hal_remote_l32( XPTR( file_cxy , &file_ptr->offset ) );
    814         mapper = (mapper_t *)hal_remote_lpt( XPTR( file_cxy , &file_ptr->mapper ) );
     842        mapper_ptr  = hal_remote_lpt( XPTR( file_cxy , &file_ptr->mapper ) );
     843        mapper_xp   = XPTR( file_cxy , mapper_ptr );
    815844
    816845        // move data between mapper and buffer
    817         if( file_cxy == local_cxy )
    818         {
    819             error = mapper_move_kernel( mapper,
    820                                         to_buffer,
    821                                         file_offset,
    822                                         buffer_xp,
    823                                         size );
    824         }
    825         else
    826         {
    827             rpc_mapper_move_buffer_client( file_cxy,
    828                                            mapper,
    829                                            to_buffer,
    830                                            false,          // kernel buffer
    831                                            file_offset,
    832                                            buffer_xp,
    833                                            size,
    834                                            &error );
    835         }
    836 
     846        error = mapper_move_kernel( mapper_xp,
     847                                    to_buffer,
     848                                    file_offset,
     849                                    buffer_xp,
     850                                    size );
    837851        if( error ) return -1;
    838         else        return 0;
    839852    }
    840853    else
     
    843856        return -1;
    844857    }
     858
     859    return 0;
     860
    845861}  // end vfs_kernel_move()
    846862
     
    853869    xptr_t         offset_xp;
    854870    xptr_t         lock_xp;
     871    xptr_t         size_xp;
    855872    cxy_t          file_cxy;
    856873    vfs_file_t  *  file_ptr;
     
    858875    uint32_t       new;
    859876
    860     assert( (file_xp != XPTR_NULL) , "file_xp == XPTR_NULL" );
     877// check argument
     878assert( (file_xp != XPTR_NULL) , "file_xp == XPTR_NULL\n" );
    861879
    862880    // get cluster and local pointer on remote file descriptor
     
    864882    file_ptr = GET_PTR( file_xp );
    865883
    866     // build extended pointers on lock and offset
     884    // get local pointer on remote inode
     885    inode_ptr = (vfs_inode_t *)hal_remote_lpt( XPTR( file_cxy , &file_ptr->inode ) );
     886
     887    // build extended pointers on lock, offset and size
    867888    offset_xp = XPTR( file_cxy , &file_ptr->offset );
    868889    lock_xp   = XPTR( file_cxy , &file_ptr->lock );
     890    size_xp   = XPTR( file_cxy , &inode_ptr->size );
    869891
    870892    // take file descriptor lock
     
    881903    else if ( whence == SEEK_END )   // new = size + offset
    882904    {
    883         // get local pointer on remote inode
    884         inode_ptr = (vfs_inode_t *)hal_remote_lpt( XPTR( file_cxy , &file_ptr->inode ) );
    885 
    886         new = hal_remote_l32( XPTR( file_cxy , &inode_ptr->size ) ) + offset;
     905        new = hal_remote_l32( size_xp ) + offset;
    887906    }
    888907    else
     
    893912    }
    894913
     914#if DEBUG_VFS_LSEEK
     915uint32_t   cycle = (uint32_t)hal_get_cycles();
     916thread_t * this  = CURRENT_THREAD;
     917char       name[CONFIG_VFS_MAX_NAME_LENGTH];
     918vfs_inode_get_name( XPTR( file_cxy , inode_ptr ) , name );
     919if( cycle > DEBUG_VFS_LSEEK )
     920printk("\n[%s] thread[%x,%x] for <%s> / new offset %d / cycle %d\n",
     921__FUNCTION__ , this->process->pid, this->trdid, name, new, cycle );
     922#endif
     923
    895924    // set new offset
    896925    hal_remote_s32( offset_xp , new );
     
    900929
    901930    // success
    902     if ( new_offset != NULL )
    903         *new_offset = new;
     931    if ( new_offset != NULL ) *new_offset = new;
    904932    return 0;
    905933
     
    922950    process_t  * process_ptr;      // process copy local pointer
    923951
    924     assert( (file_xp != XPTR_NULL) , "file_xp == XPTR_NULL" );
    925 
    926     assert( (file_id < CONFIG_PROCESS_FILE_MAX_NR) , "illegal file_id" );
     952// check arguments
     953assert( (file_xp != XPTR_NULL) , "file_xp == XPTR_NULL\n" );
     954assert( (file_id < CONFIG_PROCESS_FILE_MAX_NR) , "illegal file_id\n" );
    927955
    928956    thread_t  * this    = CURRENT_THREAD;
     
    10191047                    char   * path )
    10201048{
    1021     assert( false , "not implemented cwd_xp %x, path <%s> \n",
    1022       cwd_xp, path );   
    1023     return 0;
    1024 }
     1049    error_t           error;
     1050    xptr_t            inode_xp;           // extended pointer on target inode
     1051    cxy_t             inode_cxy;          // target inode cluster identifier       
     1052    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
     1061
     1062#if DEBUG_VFS_UNLINK
     1063thread_t * this  = CURRENT_THREAD;
     1064uint32_t   cycle = (uint32_t)hal_get_cycles();
     1065if( DEBUG_VFS_UNLINK < cycle )
     1066printk("\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
     1076    inode_cxy = GET_CXY( inode_xp );
     1077    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
     1092assert( (inode_refcount  == 1), "illegal inode refcount for <%s>\n", path );
     1093assert( (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 )
     1102        {
     1103            printk("\n[ERROR] in %s : cannot update FAT mapper <%s>\n", path );
     1104            return -1;
     1105        }
     1106
     1107#if(DEBUG_VFS_UNLINK & 1)
     1108if( DEBUG_VFS_UNLINK < cycle )
     1109printk("\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
     1116        {
     1117            error = vfs_fs_remove_dentry( dentry_parent_ptr,
     1118                                          dentry_ptr );
     1119        }
     1120        else                                                  // dentry is remote
     1121        {
     1122            rpc_vfs_fs_remove_dentry_client( dentry_cxy,
     1123                                             dentry_parent_ptr,
     1124                                             dentry_ptr,
     1125                                             &error );
     1126        }
     1127        if( error )
     1128        {
     1129            printk("\n[ERROR] in %s : cannot update dentry on device for <%s>\n", path );
     1130            return -1;
     1131        }
     1132
     1133#if(DEBUG_VFS_UNLINK & 1)
     1134if( DEBUG_VFS_UNLINK < cycle )
     1135printk("\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 );
     1140
     1141#if DEBUG_VFS_UNLINK
     1142if( DEBUG_VFS_UNLINK < cycle )
     1143printk("\n[%s] thread[%x,%x] exit / removed <%s> inode from Inode Tree / cycle %d\n",
     1144__FUNCTION__, this->process->pid, this->trdid, path, cycle );
     1145#endif
     1146        return 0;
     1147    }
     1148    /////////////////////////////////
     1149    else if( type == INODE_TYPE_DIR )
     1150    {
     1151        printk("\n[ERROR] in %s : unsupported type %s\n", vfs_inode_type_str( type ) );
     1152        return -1;
     1153    }
     1154    ////
     1155    else
     1156    {
     1157        printk("\n[ERROR] in %s : unsupported type %s\n", vfs_inode_type_str( type ) );
     1158        return -1;
     1159    }
     1160
     1161}  // end vfs_unlink()
    10251162
    10261163//////////////////////////////////////
     
    10581195
    10591196    return 0;
    1060 }
     1197
     1198}  // end vfs_stat()
    10611199
    10621200/////////////////////////////////////////////
     
    11721310
    11731311//////////////////////////////////////////////////////////////////////////////////////////
    1174 //            Inode Tree functions
     1312//       Distributed Inode Tree access related functions
    11751313//////////////////////////////////////////////////////////////////////////////////////////
    11761314
     
    13361474}  // end vfs_display()
    13371475
     1476/*
    13381477//////////////////////////////////////////////////////////////////////////////////////////
    1339 // This function is used by the vfs_lookup() function.
     1478// This static function is used by the vfs_lookup() function.
    13401479// It takes an extended pointer on a remote inode (parent directory inode),
    13411480// and check access_rights violation for the calling thread.
     
    13471486// @ return true if access rights are violated.
    13481487//////////////////////////////////////////////////////////////////////////////////////////
    1349 bool_t vfs_access_denied( xptr_t   inode_xp,
     1488static bool_t vfs_access_denied( xptr_t   inode_xp,
    13501489                          uint32_t client_uid,
    13511490                          uint32_t client_gid )
     
    13641503    else                                             return true;
    13651504}
     1505*/
    13661506
    13671507//////////////////////////////////////////////////////////////////////////////////////////
     
    14651605    cxy_t              parent_cxy;   // cluster for parent inode
    14661606    vfs_inode_t      * parent_ptr;   // local pointer on parent inode 
     1607    xptr_t             dentry_xp;    // extended pointer on dentry       
    14671608    xptr_t             child_xp;     // extended pointer on child inode
    14681609    cxy_t              child_cxy;    // cluster for child inode
    1469     vfs_inode_t      * child_ptr;    // local pointer on child inode 
     1610    vfs_inode_t      * child_ptr;    // local pointer on child inode
     1611    vfs_inode_type_t   child_type;   // child inode type
    14701612    vfs_fs_type_t      fs_type;      // File system type
    14711613    vfs_ctx_t        * ctx_ptr;      // local pointer on FS context
     
    15191661#if (DEBUG_VFS_LOOKUP & 1)
    15201662if( DEBUG_VFS_LOOKUP < cycle )
    1521 printk("\n[%s]  look for <%s> / last = %d\n",
    1522 __FUNCTION__ , name , last );
     1663printk("\n[%s] thread[%x,%x] look for <%s> in <%s> / last = %d\n",
     1664__FUNCTION__, process->pid, this->trdid, name, pathname, last );
    15231665#endif
    15241666
     
    15331675#if (DEBUG_VFS_LOOKUP & 1)
    15341676if( DEBUG_VFS_LOOKUP < cycle )
    1535 printk("\n[%s] miss <%s> node => try to create it\n",
    1536 __FUNCTION__ , name );
     1677printk("\n[%s] thread[%x,%x] miss <%s> node => try to create it\n",
     1678__FUNCTION__, process->pid, this->trdid, name );
    15371679#endif
    15381680            // if a child node is not found in the inode tree,
     
    15441686            // . if it is not found in the parent mapper:
    15451687            //   - if ( not last or not create ) an error is reported
    1546             //   - if (last and create and dir) a new directory is created
    1547             //   - if (last and create and not dir) a new file is created
     1688            //   - if (last and create) a new file or directory is created
    15481689
    15491690            // release lock on parent inode
    15501691            vfs_inode_unlock( parent_xp );
    15511692 
    1552             // get parent inode FS type
     1693            // get parent inode cluster and local pointer
    15531694            parent_cxy = GET_CXY( parent_xp );
    15541695            parent_ptr = GET_PTR( parent_xp );
    1555             ctx_ptr    = (vfs_ctx_t *)hal_remote_lpt( XPTR( parent_cxy,&parent_ptr->ctx ) );
     1696
     1697            // get parent inode FS type
     1698            ctx_ptr    = hal_remote_lpt( XPTR( parent_cxy,&parent_ptr->ctx ) );
    15561699            fs_type    = hal_remote_l32( XPTR( parent_cxy , &ctx_ptr->type ) );
    15571700
    15581701            // select a cluster for missing inode
    15591702            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;
    15601707 
    15611708            // insert a new child dentry/inode in inode tree
    15621709            error = vfs_add_child_in_parent( child_cxy,
    1563                                              0,           // type will be updated later
     1710                                             child_type,
    15641711                                             fs_type,
    15651712                                             parent_xp,
    15661713                                             name,
    1567                                              NULL,        // fs_type_specific inode extend
     1714                                             &dentry_xp,
    15681715                                             &child_xp );
    15691716            if( error )
    15701717            {
    1571                 printk("\n[ERROR] in %s : cannot create node %s for path <%s>\n",
     1718                printk("\n[ERROR] in %s : cannot create node <%s> in path <%s>\n",
    15721719                __FUNCTION__ , name, pathname );
    1573                 return ENOMEM;
     1720                return -1;
    15741721            }
    15751722
    1576             // get child inode cluster and local pointer
    1577             child_cxy = GET_CXY( child_xp );
     1723            // get child inode local pointer
    15781724            child_ptr = GET_PTR( child_xp );
    15791725
    15801726#if (DEBUG_VFS_LOOKUP & 1)
    15811727if( DEBUG_VFS_LOOKUP < cycle )
    1582 printk("\n[%s]  missing <%s> inode speculatively created / cxy %x / ptr %x\n",
    1583 __FUNCTION__ , name , child_cxy, child_ptr );
    1584 #endif
    1585              // scan parent mapper to complete the missing inode
     1728printk("\n[%s] thread[%x,%x] created missing inode <%s> in cluster %x\n",
     1729__FUNCTION__, process->pid, this->trdid, name, child_cxy );
     1730#endif
     1731            // scan parent mapper to find the missing dentry, and complete
     1732            // the initialisation of dentry and child inode desciptors
    15861733            if( parent_cxy == local_cxy )
     1734
    15871735            {
    1588                 error = vfs_inode_load( parent_ptr,
    1589                                         name,
    1590                                         child_xp );
     1736                error = vfs_fs_child_init( parent_ptr,
     1737                                           name,
     1738                                           child_xp );
    15911739            }
    15921740            else
    15931741            {
    1594                 rpc_vfs_inode_load_client( parent_cxy,
    1595                                            parent_ptr,
    1596                                            name,
    1597                                            child_xp,
    1598                                            &error );
     1742                rpc_vfs_fs_child_init_client( parent_cxy,
     1743                                              parent_ptr,
     1744                                              name,
     1745                                              child_xp,
     1746                                              &error );
    15991747            }
    16001748
    16011749            if ( error )   // child not found in parent mapper
    16021750            {
    1603                 if( last && create && dir )  // new directory  => update inode type
     1751                if ( last && create )  // add a new dentry in parent
    16041752                {
    1605                      hal_remote_s32( XPTR( child_cxy, &child_ptr->type ), INODE_TYPE_DIR );
     1753                    error = vfs_new_child_init( parent_xp,               
     1754                                                dentry_xp,
     1755                                                child_xp );
     1756                    if ( error )
     1757                    {
     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 );
     1761                        return -1;
     1762                    }
    16061763
    16071764#if (DEBUG_VFS_LOOKUP & 1)
    16081765if( DEBUG_VFS_LOOKUP < cycle )
    1609 printk("\n[%s]  created node <%s> in path %s / type DIR\n",
    1610 __FUNCTION__ , name, pathname );
     1766printk("\n[%s] thread[%x,%x] created inode <%s> in path\n",
     1767__FUNCTION__, process->pid, this->trdid, name );
    16111768#endif
    16121769                }
    1613                 else if ( last && create )   // new file => update inode type
    1614                 {
    1615                      hal_remote_s32( XPTR( child_cxy, &child_ptr->type ), INODE_TYPE_FILE );
    1616 
    1617 #if (DEBUG_VFS_LOOKUP & 1)
    1618 if( DEBUG_VFS_LOOKUP < cycle )
    1619 printk("\n[%s]  created node <%s> in path %s / type FILE\n",
    1620 __FUNCTION__ , name, pathname );
    1621 #endif
    1622                 }
    1623                 else                         // not last or not create => remove created node
     1770                else                   // not last or not create => error
    16241771                {                       
    16251772                     printk("\n[ERROR] in %s : <%s> node not found in parent for <%s>\n",
     
    16291776                }
    16301777            }
    1631             else          // child found in parent
     1778            else          // child found in parent mapper
    16321779            {
    16331780                // load child mapper from device if child is a directory (prefetch)
     
    16361783                    if( child_cxy == local_cxy )
    16371784                    {
    1638                         error = vfs_mapper_load_all( child_ptr );
     1785                        error = vfs_inode_load_all_pages( child_ptr );
    16391786                    }
    16401787                    else
    16411788                    {
    1642                         rpc_vfs_mapper_load_all_client( child_cxy,
    1643                                                         child_ptr,
    1644                                                         &error );
     1789                        rpc_vfs_inode_load_all_pages_client( child_cxy,
     1790                                                             child_ptr,
     1791                                                             &error );
    16451792                    }
    16461793                    if ( error )
     
    16541801#if (DEBUG_VFS_LOOKUP & 1)
    16551802if( DEBUG_VFS_LOOKUP < cycle )
    1656 printk("\n[%s]  load mapper from device for node <%s> in path %s\n",
    1657 __FUNCTION__ , name, pathname );
     1803printk("\n[%s] thread[%x,%x] loaded from IOC device mapper for <%s> in <%s>\n",
     1804__FUNCTION__ , process->pid, this->trdid, name, pathname );
    16581805#endif
    16591806                }
     
    16681815#if (DEBUG_VFS_LOOKUP & 1)
    16691816if( DEBUG_VFS_LOOKUP < cycle )
    1670 printk("\n[%s] found <%s> / inode %x in cluster %x\n",
    1671 __FUNCTION__ , name , GET_PTR(child_xp) , GET_CXY(child_xp) );
     1817printk("\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) );
    16721819#endif
    16731820            child_ptr  = GET_PTR( child_xp );
     
    17101857cycle = (uint32_t)hal_get_cycles();
    17111858if( DEBUG_VFS_LOOKUP < cycle )
    1712 printk("\n[%s] thread[%x,%x] exit for <%s>\n"
    1713 "     parent %x in cluster %x / child %x in cluster %x / cycle %d\n",
    1714 __FUNCTION__ , process->pid, this->trdid, pathname,
    1715 parent_ptr, parent_cxy, child_ptr, child_cxy, cycle );
     1859printk("\n[%s] thread[%x,%x] exit for <%s> cycle %d\n",
     1860__FUNCTION__ , process->pid, this->trdid, pathname, cycle );
    17161861#endif
    17171862
     
    17231868
    17241869}  // end vfs_lookup()
     1870
     1871
     1872
     1873///////////////////////////////////////////////
     1874error_t vfs_new_child_init( xptr_t   parent_xp,
     1875                            xptr_t   dentry_xp,
     1876                            xptr_t   child_xp )
     1877{
     1878    error_t     error;
     1879    uint32_t    cluster;
     1880    uint32_t    child_type;
     1881    uint32_t    child_size;
     1882
     1883#if DEBUG_VFS_NEW_CHILD_INIT
     1884char parent_name[CONFIG_VFS_MAX_NAME_LENGTH];
     1885char child_name[CONFIG_VFS_MAX_NAME_LENGTH];
     1886vfs_inode_get_name( parent_xp , parent_name );
     1887vfs_inode_get_name( child_xp  , child_name );
     1888uint32_t   cycle = (uint32_t)hal_get_cycles();
     1889thread_t * this  = CURRENT_THREAD;
     1890if( DEBUG_VFS_NEW_CHILD_INIT < cycle )
     1891printk("\n[%s] thread[%x,%x] enter / parent <%s> / child <%s> / cycle %d\n",
     1892__FUNCTION__ , this->process->pid, this->trdid, parent_name, child_name, cycle );
     1893#endif
     1894
     1895    // get parent inode cluster and local pointer
     1896    cxy_t          parent_cxy = GET_CXY( parent_xp );
     1897    vfs_inode_t  * parent_ptr = GET_PTR( parent_xp );
     1898
     1899    // get dentry local pointer
     1900    vfs_dentry_t * dentry_ptr = GET_PTR( dentry_xp );
     1901
     1902    // get child inode cluster and local pointer
     1903    cxy_t          child_cxy  = GET_CXY( child_xp );
     1904    vfs_inode_t  * child_ptr  = GET_PTR( child_xp );
     1905
     1906    // 1. allocate one free cluster to child inode
     1907    // depending on the child inode FS type
     1908    vfs_ctx_t * ctx = hal_remote_lpt( XPTR( child_cxy , &child_ptr->ctx ) );
     1909
     1910    error = vfs_fs_cluster_alloc( ctx->type,
     1911                                  &cluster );
     1912    if ( error )
     1913    {
     1914        printk("\n[ERROR] in %s : cannot find a free VFS cluster\n",
     1915        __FUNCTION__ );
     1916        return -1;
     1917    }
     1918
     1919#if( DEBUG_VFS_NEW_CHILD_INIT & 1)
     1920if( DEBUG_VFS_NEW_CHILD_INIT < cycle )
     1921printk("\n[%s] thread[%x,%x] allocated one FAT cluster to <%s>\n",
     1922__FUNCTION__ , this->process->pid, this->trdid, child_name );
     1923#endif
     1924
     1925    // 2. update the child inode descriptor
     1926    child_type = hal_remote_l32( XPTR( child_cxy , &child_ptr->type ) );
     1927    child_size = (child_type == INODE_TYPE_DIR) ? 4096 : 0;
     1928   
     1929    hal_remote_s32( XPTR( child_cxy , &child_ptr->size )   , child_size );
     1930    hal_remote_spt( XPTR( child_cxy , &child_ptr->extend ) , (void*)(intptr_t)cluster );
     1931
     1932    // 3. update the parent inode mapper, and
     1933    // update the dentry extension if required
     1934    if( local_cxy == parent_cxy )
     1935    {
     1936        error = vfs_fs_add_dentry( parent_ptr,
     1937                                   dentry_ptr );
     1938    }
     1939    else
     1940    {
     1941        rpc_vfs_fs_add_dentry_client( parent_cxy,
     1942                                      parent_ptr,
     1943                                      dentry_ptr,
     1944                                      &error );
     1945    }
     1946    if ( error )
     1947    {
     1948        printk("\n[ERROR] in %s : cannot register child in parent directory\n",
     1949        __FUNCTION__ );
     1950        return -1;
     1951    }
     1952
     1953#if DEBUG_VFS_NEW_CHILD_INIT
     1954cycle = (uint32_t)hal_get_cycles();
     1955if( DEBUG_VFS_NEW_CHILD_INIT < cycle )
     1956printk("\n[%s] thread[%x,%x] exit / parent <%s> / child <%> / cycle %d\n",
     1957__FUNCTION__ , this->process->pid, this->trdid, parent_name, child_name, cycle );
     1958#endif
     1959
     1960    return 0;
     1961
     1962}  // end vfs_new_child_init()
    17251963
    17261964////////////////////////////////////////////
     
    17942032
    17952033     
    1796 //////////////////////////////////////////////////////////////
    1797 error_t vfs_add_child_in_parent( cxy_t              child_cxy,
    1798                                  vfs_inode_type_t   inode_type,
     2034////////////////////////////////////////////////////////////////////
     2035error_t vfs_add_child_in_parent( cxy_t              child_inode_cxy,
     2036                                 vfs_inode_type_t   child_inode_type,
    17992037                                 vfs_fs_type_t      fs_type,
    1800                                  xptr_t             parent_xp,
     2038                                 xptr_t             parent_inode_xp,
    18012039                                 char             * name,
    1802                                  void             * extend,
    1803                                  xptr_t           * child_xp )
     2040                                 xptr_t           * dentry_xp,
     2041                                 xptr_t           * child_inode_xp )
    18042042{
    18052043    error_t         error;
    1806     xptr_t          dentry_xp;   // extended pointer on created dentry
    1807     xptr_t          inode_xp;    // extended pointer on created inode
    1808     cxy_t           parent_cxy;  // parent inode cluster identifier
    1809     vfs_inode_t   * parent_ptr;  // parent inode local pointer
     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
    18102049
    18112050    // get parent inode cluster and local pointer
    1812     parent_cxy = GET_CXY( parent_xp );
    1813     parent_ptr = GET_PTR( parent_xp );
     2051    parent_inode_cxy = GET_CXY( parent_inode_xp );
     2052    parent_inode_ptr = GET_PTR( parent_inode_xp );
    18142053
    18152054#if DEBUG_VFS_ADD_CHILD
     2055char parent_name[CONFIG_VFS_MAX_NAME_LENGTH];
     2056vfs_inode_get_name( parent_inode_xp , parent_name );
    18162057uint32_t cycle = (uint32_t)hal_get_cycles();
    18172058thread_t * this = CURRENT_THREAD;
    18182059if( DEBUG_VFS_ADD_CHILD < cycle )
    1819 printk("\n[%s] thread[%x,%x] enter for <%s> / child_cxy %x / parent_cxy %x / cycle %d\n",
    1820 __FUNCTION__, this->process->pid, this->trdid, name,
    1821 child_cxy, parent_cxy, (uint32_t)hal_get_cycles() );
     2060printk("\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,
     2062parent_name, parent_inode_cxy, (uint32_t)hal_get_cycles() );
    18222063#endif
    18232064
    18242065    // 1. create dentry
    1825     if( parent_cxy == local_cxy )      // parent cluster is the local cluster
     2066    if( parent_inode_cxy == local_cxy )      // parent cluster is the local cluster
    18262067    {
    18272068        error = vfs_dentry_create( fs_type,
    18282069                                   name,
    1829                                    parent_ptr,
    1830                                    &dentry_xp );
     2070                                   parent_inode_ptr,
     2071                                   &new_dentry_xp );
    18312072    }
    18322073    else                               // parent cluster is remote
    18332074    {
    1834         rpc_vfs_dentry_create_client( parent_cxy,
     2075        rpc_vfs_dentry_create_client( parent_inode_cxy,
    18352076                                      fs_type,
    18362077                                      name,
    1837                                       parent_ptr,
    1838                                       &dentry_xp,
     2078                                      parent_inode_ptr,
     2079                                      &new_dentry_xp,
    18392080                                      &error );
    18402081    }
     
    18432084    {
    18442085        printk("\n[ERROR] in %s : cannot create dentry <%s> in cluster %x\n",
    1845         __FUNCTION__ , name , parent_cxy );
    1846         return ENOMEM;
    1847     }
     2086        __FUNCTION__ , name , parent_inode_cxy );
     2087        return -1;
     2088    }
     2089
     2090    // get dentry local pointer
     2091    new_dentry_ptr = GET_PTR( new_dentry_xp );
    18482092
    18492093#if(DEBUG_VFS_ADD_CHILD & 1)
    18502094if( DEBUG_VFS_ADD_CHILD < cycle )
    18512095printk("\n[%s] thread[%x,%x] / dentry <%s> created in cluster %x\n",
    1852 __FUNCTION__, this->process->pid, this->trdid, name, parent_cxy );
     2096__FUNCTION__, this->process->pid, this->trdid, name, parent_inode_cxy );
    18532097#endif
    18542098
     
    18592103    uint32_t gid  = 0;
    18602104   
    1861     if( child_cxy == local_cxy )      // child cluster is the local cluster
    1862     {
    1863         error = vfs_inode_create( dentry_xp,
     2105    if( child_inode_cxy == local_cxy )      // child cluster is the local cluster
     2106    {
     2107        error = vfs_inode_create( new_dentry_xp,
    18642108                                  fs_type,
    1865                                   inode_type,
    1866                                   extend,
     2109                                  child_inode_type,
    18672110                                  attr,
    18682111                                  mode,
    18692112                                  uid,
    18702113                                  gid,
    1871                                   &inode_xp );
     2114                                  &new_inode_xp );
    18722115    }
    18732116    else                              // child cluster is remote
    18742117    {
    1875         rpc_vfs_inode_create_client( child_cxy,
    1876                                      dentry_xp,
     2118        rpc_vfs_inode_create_client( child_inode_cxy,
     2119                                     new_dentry_xp,
    18772120                                     fs_type,
    1878                                      inode_type,
    1879                                      extend,
     2121                                     child_inode_type,
    18802122                                     attr,
    18812123                                     mode,
    18822124                                     uid,
    18832125                                     gid,
    1884                                      &inode_xp,
     2126                                     &new_inode_xp,
    18852127                                     &error );
    18862128    }
     
    18892131    {
    18902132        printk("\n[ERROR] in %s : cannot create inode in cluster %x\n",
    1891                __FUNCTION__ , child_cxy );
     2133               __FUNCTION__ , child_inode_cxy );
    18922134 
    1893         vfs_dentry_t * dentry = GET_PTR( dentry_xp );
    1894         if( parent_cxy == local_cxy ) vfs_dentry_destroy( dentry );
    1895         else rpc_vfs_dentry_destroy_client( parent_cxy , dentry , &error );
    1896         return ENOMEM;
     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 );
     2137        return -1;
    18972138    }
    18982139
     
    19002141if( DEBUG_VFS_ADD_CHILD < cycle )
    19012142printk("\n[%s] thread[%x,%x] / inode <%s> created in cluster %x\n",
    1902 __FUNCTION__ , this->process->pid, this->trdid, name , child_cxy );
    1903 #endif
    1904 
    1905     // 3. update extended pointer on inode in dentry
    1906     cxy_t          dentry_cxy = GET_CXY( dentry_xp );
    1907     vfs_dentry_t * dentry_ptr = GET_PTR( dentry_xp );
    1908     hal_remote_s64( XPTR( dentry_cxy , &dentry_ptr->child_xp ) , inode_xp );
     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 );
    19092150
    19102151#if DEBUG_VFS_ADD_CHILD
     
    19152156#endif
    19162157
    1917     // success : return extended pointer on child inode
    1918     *child_xp = inode_xp;
     2158    // return extended pointer on dentry & child inode
     2159    *dentry_xp      = new_dentry_xp;
     2160    *child_inode_xp = new_inode_xp;
    19192161    return 0;
    19202162
    1921     // FIXME update the refcount fields in both inode and dentry
    1922 
    19232163}  // end vfs_add_child_in_parent()
    19242164
    1925 ///////////////////////////////////////////////////////
    1926 error_t vfs_remove_child_from_parent( xptr_t inode_xp )
     2165////////////////////////////////////////////////////
     2166void vfs_remove_child_from_parent( xptr_t inode_xp )
    19272167{
    19282168    cxy_t          inode_cxy;
     
    19312171    cxy_t          dentry_cxy;
    19322172    vfs_dentry_t * dentry_ptr;
    1933     error_t        error;
    19342173   
    19352174    // get inode cluster and local pointer
     
    19372176    inode_ptr = GET_PTR( inode_xp );
    19382177
    1939     // get cluster and pointers of associated dentry
     2178    // get associated dentry cluster and pointers
    19402179    dentry_xp  = hal_remote_l64( XPTR( inode_cxy , &inode_ptr->parent_xp ) );
    19412180    dentry_cxy = GET_CXY( dentry_xp );
    19422181    dentry_ptr = GET_PTR( dentry_xp );
    19432182
    1944     // FIXME update the refcount fields in both inode and dentry
     2183// check dentry refcount
     2184assert( ( hal_remote_l32( XPTR( dentry_cxy , &dentry_ptr->refcount ) ) == 1 ),
     2185"dentry refcount must be 1\n" );
     2186
     2187// check inode refcount
     2188assert( ( 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 );
    19452194
    19462195    // delete dentry
    19472196    if( dentry_cxy == local_cxy )
    19482197    {
    1949          error = vfs_dentry_destroy( dentry_ptr );
     2198         vfs_dentry_destroy( dentry_ptr );
    19502199    }
    19512200    else
    19522201    {
    19532202         rpc_vfs_dentry_destroy_client( dentry_cxy,
    1954                                         dentry_ptr,
    1955                                         &error );
    1956     }
    1957     if( error ) return EINVAL;
     2203                                        dentry_ptr );
     2204    }
    19582205
    19592206    // delete inode
     
    19652212    {
    19662213         rpc_vfs_inode_destroy_client( inode_cxy,
    1967                                        inode_ptr,
    1968                                        &error );
    1969     }
    1970     if( error ) return EINVAL;
    1971 
    1972     return 0;
     2214                                       inode_ptr );
     2215    }
    19732216
    19742217}  // end vfs_remove_child_from_parent()
    19752218
    19762219//////////////////////////////////////////////////////////////////////////////////////////
    1977 //            Mapper related functions
     2220//    API used by VFS to access a specific FS 
    19782221//////////////////////////////////////////////////////////////////////////////////////////
    19792222
    1980 ////////////////////////////////////////////
    1981 error_t vfs_mapper_move_page( page_t * page,
    1982                               bool_t   to_mapper )
     2223///////////////////////////////////////////
     2224error_t vfs_fs_move_page( xptr_t   page_xp,
     2225                          bool_t   to_mapper )
    19832226{
    19842227    error_t error = 0;
    19852228
    1986     assert( (page != NULL) , "page pointer is NULL\n" );
    1987 
    1988     mapper_t    * mapper = page->mapper;
    1989 
    1990     assert( (mapper != NULL) , "no mapper for page\n" );
    1991 
    1992 #if DEBUG_VFS_MAPPER_MOVE
    1993 uint32_t   cycle = (uint32_t)hal_get_cycles();
    1994 thread_t * this  = CURRENT_THREAD;
    1995 if( DEBUG_VFS_MAPPER_MOVE < cycle )
    1996 printk("\n[%s] thread[%x,%x] enter for page %d / mapper %x / inode %x / cycle %d\n",
    1997 __FUNCTION__, this->process->pid, this->trdid, page->index, mapper, mapper->inode, cycle );
    1998 #endif
     2229assert( (page_xp != XPTR_NULL) , "page pointer is NULL\n" );
     2230
     2231    page_t * page_ptr = GET_PTR( page_xp );
     2232    cxy_t    page_cxy = GET_CXY( page_xp );
     2233
     2234    // get local pointer on page mapper
     2235    mapper_t * mapper = hal_remote_lpt( XPTR( page_cxy , &page_ptr->mapper ) );
     2236
     2237assert( (mapper != NULL) , "no mapper for page\n" );
     2238
     2239    // get FS type
     2240    vfs_fs_type_t fs_type = hal_remote_l32( XPTR( page_cxy , &mapper->type ) );
     2241
     2242    // call relevant FS function
     2243    if( fs_type == FS_TYPE_FATFS )
     2244    {
     2245        error = fatfs_move_page( page_xp , to_mapper );
     2246    }
     2247    else if( fs_type == FS_TYPE_RAMFS )
     2248    {
     2249        assert( false , "should not be called for RAMFS\n" );
     2250    }
     2251    else if( fs_type == FS_TYPE_DEVFS )
     2252    {
     2253        assert( false , "should not be called for DEVFS\n" );
     2254    }
     2255    else
     2256    {
     2257        assert( false , "undefined file system type\n" );
     2258    }
     2259
     2260    return error;
     2261
     2262}  // end vfs_fs_move_page()
     2263
     2264////////////////////////////////////////////////
     2265error_t vfs_fs_add_dentry( vfs_inode_t  * inode,
     2266                           vfs_dentry_t * dentry )
     2267{
     2268    error_t error = 0;
     2269
     2270assert( (inode  != NULL) , "inode  pointer is NULL\n" );
     2271assert( (dentry != NULL) , "dentry pointer is NULL\n" );
     2272
     2273    mapper_t * mapper = inode->mapper;
     2274
     2275assert( (mapper != NULL) , "mapper pointer is NULL\n" );
    19992276
    20002277    // get FS type
     
    20042281    if( fs_type == FS_TYPE_FATFS )
    20052282    {
    2006         // enter mapper in write mode
    2007         rwlock_wr_acquire( &mapper->lock );
    2008 
    2009         // move page to mapper
    2010         error = fatfs_mapper_move_page( page , to_mapper );
    2011 
    2012         // exit mapper in write mode
    2013         rwlock_wr_release( &mapper->lock );
     2283        error = fatfs_add_dentry( inode , dentry );
    20142284    }
    20152285    else if( fs_type == FS_TYPE_RAMFS )
     
    20262296    }
    20272297
    2028 #if DEBUG_VFS_MAPPER_MOVE
    2029 cycle = (uint32_t)hal_get_cycles();
    2030 if( DEBUG_VFS_MAPPER_MOVE < cycle )
    2031 printk("\n[%s] thread[%x,%x] exit for page %d / mapper %x / inode %x / cycle %d\n",
    2032 __FUNCTION__, this->process->pid, this->trdid, page->index, mapper, mapper->inode, cycle );
    2033 #endif
    2034 
    20352298    return error;
    20362299
    2037 }  // end vfs_move_page()
    2038 
    2039 //////////////////////////////////////////////////
    2040 error_t vfs_mapper_load_all( vfs_inode_t * inode )
    2041 {
    2042     assert( (inode != NULL) , "inode pointer is NULL\n" );
    2043 
    2044     uint32_t   index;
    2045     page_t   * page;
     2300}  // end vfs_fs_add_dentry()
     2301
     2302///////////////////////////////////////////////////
     2303error_t vfs_fs_remove_dentry( vfs_inode_t  * inode,
     2304                              vfs_dentry_t * dentry )
     2305{
     2306    error_t error = 0;
     2307
     2308assert( (inode  != NULL) , "inode  pointer is NULL\n" );
     2309assert( (dentry != NULL) , "dentry pointer is NULL\n" );
    20462310
    20472311    mapper_t * mapper = inode->mapper;
    2048     uint32_t   size   = inode->size;
    20492312
    20502313assert( (mapper != NULL) , "mapper pointer is NULL\n" );
    20512314
    2052 #if DEBUG_VFS_MAPPER_LOAD
    2053 uint32_t   cycle = (uint32_t)hal_get_cycles();
    2054 thread_t * this  = CURRENT_THREAD;
    2055 if( DEBUG_VFS_MAPPER_MOVE < cycle )
    2056 printk("\n[%s] thread[%x,%x] enter for inode %x in cluster %x / cycle %d\n",
    2057 __FUNCTION__, this->process->pid, this->trdid, inode, local_cxy, cycle );
    2058 #endif
    2059 
    2060     // compute number of pages
    2061     uint32_t npages = size >> CONFIG_PPM_PAGE_SHIFT;
    2062     if( (size & CONFIG_PPM_PAGE_MASK) || (size == 0) ) npages++;
    2063 
    2064     // loop on pages
    2065     for( index = 0 ; index < npages ; index ++ )
    2066     {
    2067         // this function allocates the missing page in mapper,
    2068         // and call the vfs_mapper_move_page() to load the page from device
    2069         page = mapper_get_page( mapper , index );
    2070 
    2071         if( page == NULL ) return EIO;
    2072     }
    2073 
    2074 #if DEBUG_VFS_MAPPER_LOAD
    2075 cycle = (uint32_t)hal_get_cycles();
    2076 if( DEBUG_VFS_MAPPER_MOVE < cycle )
    2077 printk("\n[%s] thread[%x,%x] exit for inode %x in cluster %x / cycle %d\n",
    2078 __FUNCTION__, this->process->pid, this->trdid, inode, local_cxy, cycle );
    2079 #endif
    2080 
    2081     return 0;
    2082 
    2083 }  // end vfs_mapper_load_all()
    2084 
     2315    // get FS type
     2316    vfs_fs_type_t fs_type = mapper->type;
     2317
     2318    // call relevant FS function
     2319    if( fs_type == FS_TYPE_FATFS )
     2320    {
     2321        error = fatfs_remove_dentry( inode , dentry );
     2322    }
     2323    else if( fs_type == FS_TYPE_RAMFS )
     2324    {
     2325        assert( false , "should not be called for RAMFS\n" );
     2326    }
     2327    else if( fs_type == FS_TYPE_DEVFS )
     2328    {
     2329        assert( false , "should not be called for DEVFS\n" );
     2330    }
     2331    else
     2332    {
     2333        assert( false , "undefined file system type\n" );
     2334    }
     2335
     2336    return error;
     2337
     2338}  // end vfs_fs_remove_dentry()
     2339
     2340////////////////////////////////////////////////
     2341error_t vfs_fs_child_init( vfs_inode_t * parent,
     2342                           char        * name,
     2343                           xptr_t        child_xp )
     2344{
     2345    error_t error = 0;
     2346
     2347// check arguments
     2348assert( (parent != NULL) , "parent pointer is NULL\n");
     2349assert( (child_xp != XPTR_NULL) , "child pointer is NULL\n");
     2350
     2351    // get parent inode FS type
     2352    vfs_fs_type_t fs_type = parent->ctx->type;
     2353
     2354    // call relevant FS function
     2355    if( fs_type == FS_TYPE_FATFS )
     2356    {
     2357        error = fatfs_child_init( parent , name , child_xp );
     2358    }
     2359    else if( fs_type == FS_TYPE_RAMFS )
     2360    {
     2361        assert( false , "should not be called for RAMFS\n" );
     2362    }
     2363    else if( fs_type == FS_TYPE_DEVFS )
     2364    {
     2365        assert( false , "should not be called for DEVFS\n" );
     2366    }
     2367    else
     2368    {
     2369        assert( false , "undefined file system type\n" );
     2370    }
     2371
     2372    return error;
     2373
     2374} // end vfs_fs_child_init()
     2375
     2376/////////////////////////////////////////////////
     2377error_t vfs_fs_cluster_alloc( uint32_t   fs_type,
     2378                              uint32_t * cluster )
     2379{
     2380    error_t error = 0;
     2381
     2382    // call relevant FS function
     2383    if( fs_type == FS_TYPE_FATFS )
     2384    {
     2385        error = fatfs_cluster_alloc( cluster );
     2386    }
     2387    else if( fs_type == FS_TYPE_RAMFS )
     2388    {
     2389        assert( false , "should not be called for RAMFS\n" );
     2390    }
     2391    else if( fs_type == FS_TYPE_DEVFS )
     2392    {
     2393        assert( false , "should not be called for DEVFS\n" );
     2394    }
     2395    else
     2396    {
     2397        assert( false , "undefined file system type\n" );
     2398    }
     2399
     2400    return error;
     2401
     2402} // end vfs_fs_alloc_cluster()
     2403
     2404////////////////////////////////////////////////
     2405error_t vfs_fs_release_inode( xptr_t  inode_xp )
     2406{
     2407    error_t error = 0;
     2408
     2409assert( (inode_xp  != XPTR_NULL) , "inode pointer is NULL\n")       
     2410
     2411    vfs_inode_t * inode_ptr = GET_PTR( inode_xp );
     2412    cxy_t         inode_cxy = GET_CXY( inode_xp );
     2413
     2414    // get local pointer on page mapper
     2415    mapper_t * mapper = hal_remote_lpt( XPTR( inode_cxy , &inode_ptr->mapper ) );
     2416
     2417assert( (mapper != NULL) , "mapper pointer is NULL\n")       
     2418
     2419    // get FS type from mapper
     2420    vfs_fs_type_t fs_type = hal_remote_l32( XPTR( inode_cxy , &mapper->type ) );
     2421
     2422    // call relevant FS function
     2423    if( fs_type == FS_TYPE_FATFS )
     2424    {
     2425        error = fatfs_release_inode( inode_xp );
     2426    }
     2427    else if( fs_type == FS_TYPE_RAMFS )
     2428    {
     2429        assert( false , "should not be called for RAMFS\n" );
     2430    }
     2431    else if( fs_type == FS_TYPE_DEVFS )
     2432    {
     2433        assert( false , "should not be called for DEVFS\n" );
     2434    }
     2435    else
     2436    {
     2437        assert( false , "undefined file system type\n" );
     2438    }
     2439
     2440    return error;
     2441   
     2442}  // end vfs_fs_release_inode()
     2443
     2444
Note: See TracChangeset for help on using the changeset viewer.