Changeset 459 for trunk/kernel/fs


Ignore:
Timestamp:
Aug 13, 2018, 1:43:20 PM (6 years ago)
Author:
alain
Message:

Introduce the math library, to support the floating point
data used by the multi-thread fft application.
Fix several bugs regarding the FPU context save/restore.
Introduce support for the %f format in printf.

Location:
trunk/kernel/fs
Files:
2 edited

Legend:

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

    r457 r459  
    247247}  // end vfs_inode_create() 
    248248
    249 /////////////////////////////////////////////
    250 void vfs_inode_destroy( vfs_inode_t * inode )
    251 {
    252     if( inode->refcount )
    253     {
    254         assert( false , __FUNCTION__ , "inode refcount non zero\n" );
    255     }       
     249////////////////////////////////////////////////
     250error_t vfs_inode_destroy( vfs_inode_t * inode )
     251{
     252    assert( (inode->refcount == 0), __FUNCTION__ , "inode refcount non zero\n" );
    256253
    257254    // release memory allocated for mapper
     
    264261        kmem_free( &req );
    265262
     263    return 0;
     264
    266265}  // end vfs_inode_destroy()
    267266
     
    315314    return error;
    316315
    317 } // end vfs_load_inode()
     316} // end vfs_inode_load()
    318317
    319318////////////////////////////////////////////
     
    432431    vfs_dentry_t   * dentry;     // dentry descriptor (to be allocated)
    433432        kmem_req_t       req;        // request to kernel memory allocator
     433    error_t          error;
    434434
    435435#if DEBUG_VFS_DENTRY_CREATE
    436436uint32_t cycle = (uint32_t)hal_get_cycles();
    437437if( DEBUG_VFS_DENTRY_CREATE < cycle )
    438 printk("\n[DBG] %s : thread %x enter for <%s> / parent_inode %x / cycle %d\n",
    439 __FUNCTION__, CURRENT_THREAD , name , parent , cycle );
     438printk("\n[DBG] %s : thread %x in process %x enter for <%s> / parent_inode %x / cycle %d\n",
     439__FUNCTION__, CURRENT_THREAD->trdid, CURRENT_THREAD->process->pid, name, parent, cycle );
    440440#endif
    441441
     
    444444    else if( fs_type == FS_TYPE_RAMFS ) ctx = &fs_context[FS_TYPE_RAMFS];
    445445    else if( fs_type == FS_TYPE_DEVFS ) ctx = &fs_context[FS_TYPE_DEVFS];
    446     else
     446    else 
    447447    {
    448448        ctx = NULL;
    449         assert( false , __FUNCTION__ , "undefined file system type\n" );
     449        return EINVAL;
    450450    }
    451451
     
    453453    uint32_t length = strlen( name );
    454454
    455     if( length >= CONFIG_VFS_MAX_NAME_LENGTH )
    456     {
    457 
    458 #if DEBUG_SYSCALLS_ERROR
    459 printk("\n[ERROR] in %s : name <name> too long\n", __FUNCTION__ , name );
    460 #endif
    461         return EINVAL;
    462     }
     455    if( length >= CONFIG_VFS_MAX_NAME_LENGTH ) return EINVAL;
    463456
    464457    // allocate memory for dentry descriptor
     
    468461        dentry     = (vfs_dentry_t *)kmem_alloc( &req );
    469462
    470     if( dentry == NULL )
    471     {
    472 
    473 #if DEBUG_SYSCALLS_ERROR
    474 printk("\n[ERROR] in %s : cannot allocate dentry\n", __FUNCTION__ );
    475 #endif
    476         return ENOMEM;
    477     }
     463    if( dentry == NULL ) return ENOMEM;
    478464
    479465    // initialize dentry descriptor
     
    491477
    492478    // register dentry in hash table rooted in parent inode
    493     xhtab_insert( XPTR( local_cxy , &parent->children ),
    494                   name,
    495                   XPTR( local_cxy , &dentry->list ) );
     479    error = xhtab_insert( XPTR( local_cxy , &parent->children ),
     480                          name,
     481                          XPTR( local_cxy , &dentry->list ) );
     482
     483    if( error ) return EINVAL;
    496484
    497485#if( DEBUG_VFS_DENTRY_CREATE & 1 )
     
    507495cycle = (uint32_t)hal_get_cycles();
    508496if( DEBUG_VFS_DENTRY_CREATE < cycle )
    509 printk("\n[DBG] %s : thread %x exit for <%s> / dentry %x / cycle %d\n",
    510 __FUNCTION__, CURRENT_THREAD , name , dentry , cycle );
     497printk("\n[DBG] %s : thread %x in process %x exit for <%s> / dentry %x / cycle %d\n",
     498__FUNCTION__, CURRENT_THREAD->trdid, CURRENT_THREAD->process->pid, name, dentry, cycle );
    511499#endif
    512500
     
    515503}  // end vfs_dentry_create()
    516504
    517 ////////////////////////////////////////////////
    518 void vfs_dentry_destroy( vfs_dentry_t * dentry )
    519 {
    520     if( dentry->refcount )
    521     {
    522         assert( false , __FUNCTION__ , "dentry refcount non zero\n" );
    523     }       
    524 
     505///////////////////////////////////////////////////
     506error_t vfs_dentry_destroy( vfs_dentry_t * dentry )
     507{
     508    error_t error;
     509
     510    assert( (dentry->refcount == 0) , __FUNCTION__ , "dentry refcount non zero\n" );
     511
     512    // get pointer on parent inode
     513    vfs_inode_t * parent = dentry->parent;
     514
     515    // remove this dentry from parent inode htab
     516    error = xhtab_remove( XPTR( local_cxy , &parent->children ),
     517                          dentry->name,
     518                          XPTR( local_cxy , &dentry->list ) );
     519
     520    if( error ) return EINVAL;     
     521
     522    // release memory allocated to dentry
    525523        kmem_req_t req;
    526524        req.ptr   = dentry;
    527525        req.type  = KMEM_VFS_DENTRY;
    528526        kmem_free( &req );
     527
     528    return 0;
    529529}
    530530
     
    564564
    565565    *file_xp = XPTR( local_cxy , file );
     566
     567#if DEBUG_VFS_OPEN
     568uint32_t cycle = (uint32_t)hal_get_cycles();
     569if( DEBUG_VFS_OPEN < cycle )
     570printk("\n[DBG] %s : thread %x in process %x created file %x in cluster %x / cycle %d\n",
     571__FUNCTION__, CURRENT_THREAD->trdid, CURRENT_THREAD->process->pid, file, local_cxy, cycle );
     572#endif
     573
    566574    return 0;
    567575
     
    581589        kmem_free( &req );
    582590
     591#if DEBUG_VFS_CLOSE
     592uint32_t cycle = (uint32_t)hal_get_cycles();
     593if( DEBUG_VFS_CLOSE < cycle )
     594printk("\n[DBG] %s : thread %x in process %x deleted file %x in cluster %x / cycle %d\n",
     595__FUNCTION__, CURRENT_THREAD->trdid, CURRENT_THREAD->process->pid, file, local_cxy, cycle );
     596#endif
     597
    583598}  // end vfs_file_destroy()
    584599
     
    589604    // get file cluster and local pointer
    590605    cxy_t        file_cxy = GET_CXY( file_xp );
    591     vfs_file_t * file_ptr = (vfs_file_t *)GET_PTR( file_xp );
     606    vfs_file_t * file_ptr = GET_PTR( file_xp );
    592607
    593608    // atomically increment count
     
    600615    // get file cluster and local pointer
    601616    cxy_t        file_cxy = GET_CXY( file_xp );
    602     vfs_file_t * file_ptr = (vfs_file_t *)GET_PTR( file_xp );
     617    vfs_file_t * file_ptr = GET_PTR( file_xp );
    603618
    604619    // atomically decrement count
     
    630645uint32_t cycle = (uint32_t)hal_get_cycles();
    631646if( DEBUG_VFS_OPEN < cycle )
    632 printk("\n[DBG] %s :  thread %x enter for <%s> / cycle %d\n",
    633 __FUNCTION__, CURRENT_THREAD, path, cycle );
     647printk("\n[DBG] %s :  thread %x in process %x enter for <%s> / cycle %d\n",
     648__FUNCTION__, CURRENT_THREAD->trdid, CURRENT_THREAD->process->pid, path, cycle );
    634649#endif
    635650
     
    677692cycle = (uint32_t)hal_get_cycles();
    678693if( DEBUG_VFS_OPEN < cycle )
    679 printk("\n[DBG] %s : thread %x exit for <%s> / file %x in cluster %x / cycle %d\n",
    680 __FUNCTION__, CURRENT_THREAD, path, GET_PTR(file_xp), GET_CXY(file_xp), cycle );
     694printk("\n[DBG] %s :  thread %x in process %x exit for <%s> / fdid %d / cluster %x / cycle %d\n",
     695__FUNCTION__, CURRENT_THREAD->trdid, CURRENT_THREAD->process->pid, path,
     696file_id, GET_CXY( file_xp ), cycle );
    681697#endif
    682698
     
    868884                   uint32_t file_id )
    869885{
     886    cluster_t  * cluster;          // local pointer on local cluster
     887    cxy_t        file_cxy;         // cluster containing the file descriptor.
     888    vfs_file_t * file_ptr;         // local ponter on file descriptor
     889    cxy_t        owner_cxy;        // process owner cluster
     890    lpid_t       lpid;             // process local index
     891    xptr_t       root_xp;          // root of list of process copies
     892    xptr_t       lock_xp;          // lock protecting the list of copies
     893    xptr_t       iter_xp;          // iterator on list of process copies
     894    xptr_t       process_xp;       // extended pointer on one process copy
     895    cxy_t        process_cxy;      // process copy cluster
     896    process_t  * process_ptr;      // process copy local pointer
     897
    870898    assert( (file_xp != XPTR_NULL) , __FUNCTION__ , "file_xp == XPTR_NULL" );
    871899
     
    875903    process_t * process = this->process;
    876904
    877     // get cluster and local pointer on remote file descriptor
    878     cxy_t        file_cxy = GET_CXY( file_xp );
    879     vfs_file_t * file_ptr = (vfs_file_t *)GET_PTR( file_xp );
     905#if DEBUG_VFS_CLOSE
     906uint32_t cycle = (uint32_t)hal_get_cycles();
     907if( DEBUG_VFS_CLOSE < cycle )
     908printk("\n[DBG] %s : thread %x in process %x enter / fdid %d / cycle %d\n",
     909__FUNCTION__, this->trdid, process->pid, file_id, cycle );
     910#endif
    880911
    881912    // get local pointer on local cluster manager
    882     cluster_t * cluster = LOCAL_CLUSTER;
     913    cluster = LOCAL_CLUSTER;
    883914
    884915    // get owner process cluster and lpid
    885     cxy_t   owner_cxy  = CXY_FROM_PID( process->pid );
    886     lpid_t  lpid       = LPID_FROM_PID( process->pid );
     916    owner_cxy  = CXY_FROM_PID( process->pid );
     917    lpid       = LPID_FROM_PID( process->pid );
    887918
    888919    // get extended pointers on copies root and lock
    889     xptr_t root_xp = XPTR( owner_cxy , &cluster->pmgr.copies_root[lpid] );
    890     xptr_t lock_xp = XPTR( owner_cxy , &cluster->pmgr.copies_lock[lpid] );
    891 
    892     // take the lock protecting the copies
     920    root_xp = XPTR( owner_cxy , &cluster->pmgr.copies_root[lpid] );
     921    lock_xp = XPTR( owner_cxy , &cluster->pmgr.copies_lock[lpid] );
     922
     923    // 1) loop on the process descriptor copies to reset all fd_array[file_id] entries
     924
     925    // take the lock protecting the list of copies
    893926    remote_spinlock_lock( lock_xp );
    894927
    895     // 1) loop on the process descriptor copies to cancel all fd_array[file_id] entries
    896     xptr_t  iter_xp;
    897928    XLIST_FOREACH( root_xp , iter_xp )
    898929    {
    899         xptr_t      process_xp  = XLIST_ELEMENT( iter_xp , process_t , copies_list );
    900         cxy_t       process_cxy = GET_CXY( process_xp );
    901         process_t * process_ptr = (process_t *)GET_PTR( process_xp );
    902 
    903         xptr_t lock_xp  = XPTR( process_cxy , &process_ptr->fd_array.lock );
    904         xptr_t entry_xp = XPTR( process_cxy , &process_ptr->fd_array.array[file_id] );
    905 
    906         // lock is required for atomic write of a 64 bits word
    907         remote_rwlock_wr_lock( lock_xp );
     930        process_xp  = XLIST_ELEMENT( iter_xp , process_t , copies_list );
     931        process_cxy = GET_CXY( process_xp );
     932        process_ptr = GET_PTR( process_xp );
     933
     934#if (DEBUG_VFS_CLOSE & 1 )
     935if( DEBUG_VFS_CLOSE < cycle )
     936printk("\n[DBG] %s : reset fd_array[%d] for process %x in cluster %x\n",
     937__FUNCTION__, file_id, process_ptr, process_cxy );
     938#endif
     939
     940// fd_array lock is required for atomic write of a 64 bits word
     941// xptr_t fd_array_lock_xp = XPTR( process_cxy , &process_ptr->fd_array.lock );
     942
     943        xptr_t entry_xp         = XPTR( process_cxy , &process_ptr->fd_array.array[file_id] );
     944
     945// remote_rwlock_wr_lock( fd_array_lock_xp );
     946
    908947        hal_remote_swd( entry_xp , XPTR_NULL );
    909         remote_rwlock_wr_unlock( lock_xp );
     948       
     949// remote_rwlock_wr_unlock( fd_array_lock_xp );
     950
     951        vfs_file_count_down( file_xp );
    910952
    911953        hal_fence();
    912954    }   
    913955
     956    // release the lock protecting the list of copies
     957    remote_spinlock_unlock( lock_xp );
     958
     959#if (DEBUG_VFS_CLOSE & 1)
     960if( DEBUG_VFS_CLOSE < cycle )
     961printk("\n[DBG] %s : thread %x in process %x reset all fd-array copies\n",
     962__FUNCTION__, this->trdid, process->pid );
     963#endif
     964
    914965    // 2) release memory allocated to file descriptor in remote cluster
     966
     967    // get cluster and local pointer on remote file descriptor
     968    file_cxy = GET_CXY( file_xp );
     969    file_ptr = GET_PTR( file_xp );
     970
    915971    if( file_cxy == local_cxy )             // file cluster is local
    916972    {
     
    921977        rpc_vfs_file_destroy_client( file_cxy , file_ptr );
    922978    }
     979
     980#if DEBUG_VFS_CLOSE
     981cycle = (uint32_t)hal_get_cycles();
     982if( DEBUG_VFS_CLOSE < cycle )
     983printk("\n[DBG] %s : thread %x in process %x exit / fdid %d closed / cycle %d\n",
     984__FUNCTION__, this->trdid, process->pid, file_id, cycle );
     985#endif
    923986
    924987    return 0;
     
    13511414    cxy_t              child_cxy;    // cluster for child inode
    13521415    vfs_inode_t      * child_ptr;    // local pointer on child inode 
    1353     vfs_inode_type_t   child_type;   // child inode type
    13541416    vfs_fs_type_t      fs_type;      // File system type
    13551417    vfs_ctx_t        * ctx_ptr;      // local pointer on FS context
     
    13581420    bool_t             last;         // true when the name is the last in path
    13591421    bool_t             found;        // true when a child has been found
     1422    bool_t             dir;          // searched inode is a directory
     1423    bool_t             create;       // searched inode must be created if not found
     1424    bool_t             excl;         // searched inode must not exist
    13601425    thread_t         * this;         // pointer on calling thread descriptor
    13611426    process_t        * process;      // pointer on calling process descriptor
     
    13681433uint32_t cycle = (uint32_t)hal_get_cycles();
    13691434if( DEBUG_VFS_LOOKUP < cycle )
    1370 printk("\n[DBG] %s : thread %x enter for <%s> / cycle %d\n",
    1371 __FUNCTION__, CURRENT_THREAD, pathname, cycle );
    1372 #endif
    1373 
     1435printk("\n[DBG] %s : thread %x in process %x enter for <%s> / cycle %d\n",
     1436__FUNCTION__, this->trdid, process->pid, pathname, cycle );
     1437#endif
     1438
     1439    // compute lookup flags
     1440    dir    = mode & VFS_LOOKUP_DIR;
     1441    create = mode & VFS_LOOKUP_CREATE;
     1442    excl   = mode & VFS_LOOKUP_EXCL;
     1443   
    13741444    // get extended pointer on first inode to search
    13751445    if( pathname[0] == '/' ) parent_xp = process->vfs_root_xp;
     
    13861456
    13871457    // sequencially loop on nodes in pathname
    1388     // load from device if one node not found in inode tree
     1458    // load from device if one node in path not found in inode tree
    13891459    // exit loop when last name found (i.e. last == true)
    13901460    do
     
    13951465#if (DEBUG_VFS_LOOKUP & 1)
    13961466if( DEBUG_VFS_LOOKUP < cycle )
    1397 printk("\n[DBG] %s : look for <%s> / last = %d\n", __FUNCTION__ , name , last );
     1467printk("\n[DBG] %s : look for <%s> / last = %d\n",
     1468__FUNCTION__ , name , last );
    13981469#endif
    13991470
     
    14031474                               &child_xp );
    14041475
    1405         // if a child inode is not found in the inode tree:
    1406         // - we create the missing inode/dentry couple in the inode tree,
    1407         // - we scan the parent mapper to complete the child inode (type and extension),
    1408         // - we return an error if child not found on device.
    1409         // - if the missing child is a directory, we load the child mapper from device
    1410 
    1411         // for the last name, the behaviour depends on the "mode" argument:
    1412 
    1413         if (found == false ) // child node not found in inode tree
     1476        if (found == false )  // child not found in inode tree
    14141477        {
    14151478
    14161479#if (DEBUG_VFS_LOOKUP & 1)
    14171480if( DEBUG_VFS_LOOKUP < cycle )
    1418 printk("\n[DBG] %s : miss <%s> => load it\n", __FUNCTION__ , name );
    1419 #endif
     1481printk("\n[DBG] %s : miss <%s> node => try to create it\n",
     1482__FUNCTION__ , name );
     1483#endif
     1484            // if a child node is not found in the inode tree,
     1485            // we introduce a new (dentry/inode) in inode tree,
     1486            // and try to find it by scanning the parent directory mapper.
     1487            // . if it is found in parent mapper:
     1488            //   - if the child is a directory, the child mapper is loaded from device
     1489            //   - if the child is not a directory, the search is completed
     1490            // . if it is not found in the parent mapper:
     1491            //   - if ( not last or not create ) an error is reported
     1492            //   - if (last and create and dir) a new directory is created
     1493            //   - if (last and create and not dir) a new file is created
    14201494
    14211495            // release lock on parent inode
    14221496            vfs_inode_unlock( parent_xp );
    1423 
     1497 
    14241498            // get parent inode FS type
    14251499            parent_cxy = GET_CXY( parent_xp );
    1426             parent_ptr = (vfs_inode_t *)GET_PTR( parent_xp );
    1427             ctx_ptr    = (vfs_ctx_t *)hal_remote_lpt( XPTR( parent_cxy , &parent_ptr->ctx ) );
     1500            parent_ptr = GET_PTR( parent_xp );
     1501            ctx_ptr    = (vfs_ctx_t *)hal_remote_lpt( XPTR( parent_cxy,&parent_ptr->ctx ) );
    14281502            fs_type    = hal_remote_lw( XPTR( parent_cxy , &ctx_ptr->type ) );
    14291503
     
    14311505            child_cxy = vfs_cluster_random_select();
    14321506 
    1433             // insert a new child dentry/inode in parent inode
     1507            // insert a new child dentry/inode in inode tree
    14341508            error = vfs_add_child_in_parent( child_cxy,
    1435                                              INODE_TYPE_DIR,
     1509                                             0,           // type will be updated later
    14361510                                             fs_type,
    14371511                                             parent_xp,
    14381512                                             name,
    1439                                              NULL,     // fs_type_specific inode extend
     1513                                             NULL,        // fs_type_specific inode extend
    14401514                                             &child_xp );
    14411515            if( error )
    14421516            {
    1443                 printk("\n[ERROR] in %s : thread %x cannot allocate inode for path <%s>\n",
    1444                 __FUNCTION__ , this , pathname );
     1517                printk("\n[ERROR] in %s : cannot create node %s for path <%s>\n",
     1518                __FUNCTION__ , name, pathname );
    14451519                return ENOMEM;
    14461520            }
    14471521
    1448             // scan parent mapper to complete the missing inode
     1522            // get child inode cluster and local pointer
     1523            child_cxy = GET_CXY( child_xp );
     1524            child_ptr = GET_PTR( child_xp );
     1525
     1526#if (DEBUG_VFS_LOOKUP & 1)
     1527if( DEBUG_VFS_LOOKUP < cycle )
     1528printk("\n[DBG] %s : missing <%s> inode speculatively created / cxy %x / ptr %x\n",
     1529__FUNCTION__ , name , child_cxy, child_ptr );
     1530#endif
     1531             // scan parent mapper to complete the missing inode
    14491532            if( parent_cxy == local_cxy )
    14501533            {
     
    14621545            }
    14631546
    1464             if ( error )
     1547            if ( error )   // child not found in parent mapper
    14651548            {
    1466                 printk("\n[ERROR] in %s : thread %x / <%s> node not found in <%s>\n",
    1467                 __FUNCTION__ , this , name , pathname );
    1468                 return ENOENT;
    1469             }
    1470 
    1471             // get child inode type
    1472             child_ptr  = (vfs_inode_t *)GET_PTR( child_xp );
    1473             child_type = hal_remote_lw( XPTR( child_cxy , &child_ptr->type ) );
    1474 
    1475             // load child mapper from device if it is a directory
    1476             if( child_type == INODE_TYPE_DIR )
    1477             {
    1478                 if( child_cxy == local_cxy )
     1549                if( last && create && dir )  // new directory  => update inode type
    14791550                {
    1480                     error = vfs_mapper_load_all( child_ptr );
     1551                     hal_remote_sw( XPTR( child_cxy, &child_ptr->type ), INODE_TYPE_DIR );
     1552
     1553#if (DEBUG_VFS_LOOKUP & 1)
     1554if( DEBUG_VFS_LOOKUP < cycle )
     1555printk("\n[DBG] %s : created node <%s> in path %s / type DIR\n",
     1556__FUNCTION__ , name, pathname );
     1557#endif
    14811558                }
    1482                 else
     1559                else if ( last && create )   // new file => update inode type
    14831560                {
    1484                     rpc_vfs_mapper_load_all_client( child_cxy,
    1485                                                     child_ptr,
    1486                                                     &error );
     1561                     hal_remote_sw( XPTR( child_cxy, &child_ptr->type ), INODE_TYPE_FILE );
     1562
     1563#if (DEBUG_VFS_LOOKUP & 1)
     1564if( DEBUG_VFS_LOOKUP < cycle )
     1565printk("\n[DBG] %s : created node <%s> in path %s / type FILE\n",
     1566__FUNCTION__ , name, pathname );
     1567#endif
    14871568                }
    1488 
    1489                 if ( error )
    1490                 {
    1491                     printk("\n[ERROR] in %s : thread %x / cannot access device for <%s>\n",
    1492                     __FUNCTION__ , this , name );
    1493                     return EIO;
     1569                else                         // not last or not create => remove created node
     1570                {                       
     1571                     printk("\n[ERROR] in %s : <%s> node not found in parent for <%s>\n",
     1572                     __FUNCTION__ , name , pathname );
     1573                     vfs_remove_child_from_parent( child_xp );
     1574                     return ENOENT;
    14941575                }
    14951576            }
    1496 
    1497             // TODO handle lookup mode here [AG]
     1577            else          // child found in parent
     1578            {
     1579                // load child mapper from device if child is a directory (prefetch)
     1580                if( hal_remote_lw( XPTR( child_cxy , &child_ptr->type ) ) == INODE_TYPE_DIR )
     1581                {
     1582                    if( child_cxy == local_cxy )
     1583                    {
     1584                        error = vfs_mapper_load_all( child_ptr );
     1585                    }
     1586                    else
     1587                    {
     1588                        rpc_vfs_mapper_load_all_client( child_cxy,
     1589                                                        child_ptr,
     1590                                                        &error );
     1591                    }
     1592                    if ( error )
     1593                    {
     1594                        printk("\n[ERROR] in %s : cannot load <%s> from device\n",
     1595                        __FUNCTION__ , name );
     1596                        vfs_remove_child_from_parent( child_xp );
     1597                        return EIO;
     1598                    }
     1599
     1600#if (DEBUG_VFS_LOOKUP & 1)
     1601if( DEBUG_VFS_LOOKUP < cycle )
     1602printk("\n[DBG] %s : load mapper from device for node <%s> in path %s\n",
     1603__FUNCTION__ , name, pathname );
     1604#endif
     1605                }
     1606            }
    14981607
    14991608            // take lock on parent inode
    15001609            vfs_inode_lock( parent_xp );
    1501 
    1502 #if (DEBUG_VFS_LOOKUP & 1)
    1503 if( DEBUG_VFS_LOOKUP < cycle )
    1504 printk("\n[DBG] %s : created node <%s>\n", __FUNCTION__ , name );
    1505 #endif
    1506 
    15071610        }
    1508 
     1611        else   // child found in inode tree
     1612        {
     1613       
    15091614#if (DEBUG_VFS_LOOKUP & 1)
    15101615if( DEBUG_VFS_LOOKUP < cycle )
     
    15121617__FUNCTION__ , name , GET_PTR(child_xp) , GET_CXY(child_xp) );
    15131618#endif
     1619            child_ptr  = GET_PTR( child_xp );
     1620            child_cxy  = GET_CXY( child_xp );
     1621            parent_cxy = GET_CXY( parent_xp );
     1622            parent_ptr = GET_PTR( parent_xp );
     1623
     1624            if( last && (mode & VFS_LOOKUP_CREATE) && (mode & VFS_LOOKUP_EXCL) )
     1625            {
     1626                printk("\n[ERROR] in %s : node already exist <%s>\n", __FUNCTION__, name );
     1627                return EINVAL;
     1628            }
     1629        }
    15141630
    15151631        // TODO check access rights here [AG]
     
    15401656cycle = (uint32_t)hal_get_cycles();
    15411657if( DEBUG_VFS_LOOKUP < cycle )
    1542 printk("\n[DBG] %s : thread %x exit for <%s> / inode %x in cluster %x / cycle %d\n",
    1543 __FUNCTION__, CURRENT_THREAD, pathname, GET_PTR(child_xp), GET_CXY(child_xp), cycle );
     1658printk("\n[DBG] %s : thread %x in process %x exit for <%s>\n"
     1659"     parent %x in cluster %x / child %x in cluster %x / cycle %d\n",
     1660__FUNCTION__ , this->trdid, process->pid, pathname,
     1661parent_ptr, parent_cxy, child_ptr, child_cxy, cycle );
    15441662#endif
    15451663
    15461664    // return searched pointer
    1547     *inode_xp = child_xp;
     1665    if( mode & VFS_LOOKUP_PARENT ) *inode_xp = parent_xp;
     1666    else                           *inode_xp = child_xp;
    15481667
    15491668    return 0;
     
    16381757    // get parent inode cluster and local pointer
    16391758    parent_cxy = GET_CXY( parent_xp );
    1640     parent_ptr = (vfs_inode_t *)GET_PTR( parent_xp );
     1759    parent_ptr = GET_PTR( parent_xp );
    16411760
    16421761#if DEBUG_VFS_ADD_CHILD
    16431762uint32_t cycle = (uint32_t)hal_get_cycles();
    16441763if( DEBUG_VFS_ADD_CHILD < cycle )
    1645 printk("\n[DBG] %s : thread %x enter for <%s> / child_cxy = %x / parent_cxy = %x\n",
    1646 __FUNCTION__ , CURRENT_THREAD , name , child_cxy , parent_cxy );
     1764printk("\n[DBG] %s : thread %x enter for <%s> / child_cxy = %x / parent_cxy = %x / cycle %d\n",
     1765__FUNCTION__, CURRENT_THREAD->trdid, CURRENT_THREAD->process->pid, name,
     1766child_cxy, parent_cxy, (uint32_t)hal_get_cycles() );
    16471767#endif
    16481768
     
    17361856               __FUNCTION__ , child_cxy );
    17371857 
    1738         vfs_dentry_t * dentry = (vfs_dentry_t *)GET_PTR( dentry_xp );
     1858        vfs_dentry_t * dentry = GET_PTR( dentry_xp );
    17391859        if( parent_cxy == local_cxy ) vfs_dentry_destroy( dentry );
    1740         else rpc_vfs_dentry_destroy_client( parent_cxy , dentry );
     1860        else rpc_vfs_dentry_destroy_client( parent_cxy , dentry , &error );
    17411861        return ENOMEM;
    17421862    }
     
    17501870cycle = (uint32_t)hal_get_cycles();
    17511871if( DEBUG_VFS_ADD_CHILD < cycle )
    1752 printk("\n[DBG] %s : thread %x exit for <%s>\n",
    1753 __FUNCTION__ , CURRENT_THREAD , name );
     1872printk("\n[DBG] %s : thread %x in process %x exit for <%s>\n",
     1873__FUNCTION__, CURRENT_THREAD, CURRENT_THREAD->process->pid, name );
    17541874#endif
    17551875
     
    17581878    return 0;
    17591879
     1880    // FIXME update the refcount fields in both inode and dentry
     1881
    17601882}  // end vfs_add_child_in_parent()
     1883
     1884///////////////////////////////////////////////////////
     1885error_t vfs_remove_child_from_parent( xptr_t inode_xp )
     1886{
     1887    cxy_t          inode_cxy;
     1888    vfs_inode_t  * inode_ptr;
     1889    xptr_t         dentry_xp;
     1890    cxy_t          dentry_cxy;
     1891    vfs_dentry_t * dentry_ptr;
     1892    error_t        error;
     1893   
     1894    // get inode cluster and local pointer
     1895    inode_cxy = GET_CXY( inode_xp );
     1896    inode_ptr = GET_PTR( inode_xp );
     1897
     1898    // get cluster and pointers of associated dentry
     1899    dentry_xp  = hal_remote_lwd( XPTR( inode_cxy , &inode_ptr->parent_xp ) );
     1900    dentry_cxy = GET_CXY( dentry_xp );
     1901    dentry_ptr = GET_PTR( dentry_xp );
     1902
     1903    // FIXME update the refcount fields in both inode and dentry
     1904
     1905    // delete dentry
     1906    if( dentry_cxy == local_cxy )
     1907    {
     1908         error = vfs_dentry_destroy( dentry_ptr );
     1909    }
     1910    else
     1911    {
     1912         rpc_vfs_dentry_destroy_client( dentry_cxy,
     1913                                        dentry_ptr,
     1914                                        &error );
     1915    }
     1916    if( error ) return EINVAL;
     1917
     1918    // delete inode
     1919    if( inode_cxy == local_cxy )
     1920    {
     1921         vfs_inode_destroy( inode_ptr );
     1922    }
     1923    else
     1924    {
     1925         rpc_vfs_inode_destroy_client( inode_cxy,
     1926                                       inode_ptr,
     1927                                       &error );
     1928    }
     1929    if( error ) return EINVAL;
     1930
     1931    return 0;
     1932
     1933}  // end vfs_remove_child_from_parent()
    17611934
    17621935//////////////////////////////////////////////////////////////////////////////////////////
  • trunk/kernel/fs/vfs.h

    r457 r459  
    227227 * It is not replicated, and is dynamically allocated in the cluster that contains
    228228 * the inode, when a thread makes an open() or opendir() system call.
    229  * It cannot exist a file structure without an inode structure.
     229 * It cannot exist a file structure without an inode structure in same cluster.
    230230 * As the fd_array (containing extended pointers on the open file descriptors)
    231231 * is replicated in all process descriptors, we need a references counter.
     
    338338 * @ gid        : group owner ID.
    339339 * @ inode_xp   : [out] buffer for extended pointer on created inode.
    340  * # return 0 if success / return ENOMEM or EINVAL if error.
     340 * @ return 0 if success / return ENOMEM or EINVAL if error.
    341341 *****************************************************************************************/
    342342error_t vfs_inode_create( xptr_t            dentry_xp,
     
    353353 * This function releases memory allocated to an inode descriptor.
    354354 * It must be executed by a thread running in the cluster containing the inode,
    355  * and the inode refcount must be zero.
    356  * If the client thread is not running in the owner cluster, it must use the
    357  * rpc_vfs_inode_destroy_client() function.
     355 * and the inode refcount must be zero. If the client thread is not running in the owner
     356 * cluster, you must use the rpc_vfs_inode_destroy_client() function.
    358357 ******************************************************************************************
    359358 * @ inode  : local pointer on inode descriptor.
    360  *****************************************************************************************/
    361 void vfs_inode_destroy( vfs_inode_t *  inode ); 
     359 * @ return 0 if success / return EINVAL if error.
     360 *****************************************************************************************/
     361error_t vfs_inode_destroy( vfs_inode_t *  inode ); 
    362362
    363363/******************************************************************************************
     
    432432
    433433
    434 
    435 
    436 
    437 
    438 /******************************************************************************************
    439  * This function TODO                                                         
    440  *****************************************************************************************/
    441 error_t vfs_inode_trunc( vfs_inode_t * inode );
    442 
    443 /******************************************************************************************
    444  * This function TODO                                                         
    445  *****************************************************************************************/
    446 error_t vfs_inode_link( vfs_inode_t * inode,
    447                         uint32_t      igc );
    448 
    449 /******************************************************************************************
    450  * This function TODO                                                         
    451  *****************************************************************************************/
    452 error_t vfs_inode_unlink( vfs_inode_t * inode );
    453 
    454 
    455434/*****************************************************************************************/
    456435/***************** Dentry related functions **********************************************/
     
    478457 * This function releases memory allocated to a dentry descriptor.
    479458 * It must be executed by a thread running in the cluster containing the dentry,
    480  * and the dentry refcount must be zero.
    481  * If the client thread is not running in the owner cluster, it must use the
    482  * rpc_dentry_destroy_client() function.
     459 * and the dentry refcount must be zero. If the client thread is not running in the owner
     460 * cluster, you must use the rpc_dentry_destroy_client() function.
    483461 ******************************************************************************************
    484462 * @ dentry  : local pointer on dentry descriptor.
    485  *****************************************************************************************/
    486 void vfs_dentry_destroy( vfs_dentry_t *  dentry ); 
     463 * @ return 0 if success / return EINVAL if error.
     464 *****************************************************************************************/
     465error_t vfs_dentry_destroy( vfs_dentry_t *  dentry ); 
    487466
    488467/******************************************************************************************
     
    562541 * This function takes a pathname (absolute or relative to cwd) and returns an extended
    563542 * pointer on the associated inode.
    564  * - If a given name in the path is not found in the inode tree, it try to load the missing
    565  *   dentry/inode couple, from informations found in the parent directory.
     543 * - If a given directory name in the path is not found in the inode tree, it try to load
     544 *   the missing dentry/inode couple, from informations found in the parent directory.
    566545 * - If this directory entry does not exist on device, it returns an error.
    567546 * - If the the file identified by the pathname does not exist on device but the
     
    613592 * This function removes a couple dentry/inode from the Inode-Tree, and remove it from
    614593 * the external device.
    615  * TODO                   
    616594 ******************************************************************************************
    617595 * @ child_xp   : extended pointer on removed inode.
    618596 *****************************************************************************************/
    619 error_t vfs_remove_child_from_parent( xptr_t child_xp );
     597error_t vfs_remove_child_from_parent( xptr_t inode_xp );
    620598
    621599/******************************************************************************************
     
    716694
    717695/******************************************************************************************
    718  * This function close an open file descriptor:
    719  * 1) All entries in fd_array copies are directly cancelled by the calling thread,
     696 * This function close the -non-replicated- file descriptor identified by the <file_xp>
     697 * and <file_id> arguments.
     698 * 1) All entries in the fd_array copies are directly reset by the calling thread,
    720699 *    using remote accesses.
    721700 * 2) The memory allocated to file descriptor in cluster containing the inode is released.
    722701 *    It requires a RPC if cluster containing the file descriptor is remote.
    723702 ******************************************************************************************
    724  * @ file_xp     : extended pointer on the file descriptor.
     703 * @ file_xp     : extended pointer on the file descriptor in owner cluster.
    725704 * @ file_id     : file descriptor index in fd_array.
    726705 * @ returns 0 if success / -1 if error.
     
    848827
    849828/******************************************************************************************
    850  * This function makes I/O operations to move, from device to mapper, all pages covering
    851  * a given inode, identified by the <inode> argument. Inode be a directory or a file,
    852  * but this function is mainly used to load (prefetch) a complete directory to the mapper.
     829 * This function makes the I/O operations required to move, from device to mapper,
     830 * all pages covering a given inode, identified by the <inode> argument. The target
     831 * inode can be a directory or a file, but this function is mainly used to load (prefetch)
     832 * a complete directory to the mapper.
    853833 * Depending on the file system type, it calls the proper, FS specific function.
    854834 * It must be executed by a thread running in the cluster containing the mapper.
     
    862842
    863843
    864 
    865 /* deprecated [AG]
    866 
    867 typedef error_t (lookup_inode_t)  ( vfs_inode_t  * parent ,
    868                                     vfs_dentry_t * dentry );
    869 
    870 typedef error_t (write_inode_t)   ( vfs_inode_t  * inode );
    871 
    872 typedef error_t (release_inode_t) ( vfs_inode_t  * inode );
    873 
    874 typedef error_t (unlink_inode_t)  ( vfs_inode_t  * parent,
    875                                     vfs_dentry_t * dentry,
    876                                     uint32_t       flags );
    877 
    878 typedef error_t (stat_inode_t)    ( vfs_inode_t  * inode );
    879 
    880 typedef error_t (trunc_inode_t)   ( vfs_inode_t  * inode );
    881 
    882 typedef error_t (delete_inode_t)  ( vfs_inode_t  * inode );
    883 
    884 typedef struct vfs_inode_op_s
    885 {
    886         init_inode_t    * init;   
    887         create_inode_t  * create; 
    888         lookup_inode_t  * lookup; 
    889         write_inode_t   * write;
    890         release_inode_t * release;
    891         unlink_inode_t  * unlink;
    892         delete_inode_t  * delete;
    893         stat_inode_t    * stat;
    894         trunc_inode_t   * trunc;    // change the size of a file
    895 }
    896 vfs_inode_op_t;
    897 
    898  ******************************************************************************************
    899  * These typedef define the set of FS specific operations on a VFS DENTRY descriptor.
    900  * They must be implemented by any specific file system to be supported by ALMOS_MKH.
    901  * This code is not actually used, and is only defined for documentation
    902  ******************************************************************************************
    903 
    904 
    905 typedef error_t (vfs_compare_dentry_t) ( char * first , char * second );
    906 
    907 typedef struct vfs_dentry_op_s
    908 {
    909         vfs_compare_dentry_t * compare;
    910 }
    911 vfs_dentry_op_t;
    912 
    913 
    914  ******************************************************************************************
    915  * These typedef define the set of FS specific operations on FILE descriptors
    916  * They must be implemented by any specific file system to be supported by ALMOS_MKH.
    917  * This code is not actually used, and is only defined for documentation
    918  ******************************************************************************************
    919 
    920 
    921 typedef error_t (open_file_t   ) ( vfs_file_t * file,
    922                                    void       * extend );
    923 
    924 typedef error_t (read_file_t   ) ( vfs_file_t * file,
    925                                    char       * buffer,
    926                                    uint32_t     count );
    927 
    928 typedef error_t (write_file_t  ) ( vfs_file_t * file,
    929                                    char       * buffer,
    930                                    uint32_t     count );
    931 
    932 typedef error_t (lseek_file_t  ) ( vfs_file_t * file );
    933 
    934 typedef error_t (close_file_t  ) ( vfs_file_t * file );
    935 
    936 typedef error_t (release_file_t) ( vfs_file_t * file );
    937 
    938 typedef error_t (read_dir_t    ) ( vfs_file_t * file );
    939 
    940 typedef error_t (mmap_file_t   ) ( vfs_file_t    * file ,
    941                                    struct vseg_s * vseg );
    942 
    943 typedef error_t (munmap_file_t ) ( vfs_file_t    * file,
    944                                    struct vseg_s * vseg );
    945 
    946 typedef struct vfs_file_op_s
    947 {
    948         open_file_t    * open;
    949         read_file_t    * read;
    950         write_file_t   * write;
    951         lseek_file_t   * lseek;
    952         read_dir_t     * readdir;
    953         close_file_t   * close;
    954         release_file_t * release;
    955         mmap_file_t    * mmap;
    956         munmap_file_t  * munmap;
    957 }
    958 vfs_file_op_t;
    959 
    960 */
    961 
    962844#endif  /* _VFS_H_ */
Note: See TracChangeset for help on using the changeset viewer.