Changeset 612 for trunk/kernel/fs


Ignore:
Timestamp:
Jan 11, 2019, 6:35:07 PM (5 years ago)
Author:
alain
Message:

Fix several bugs in vfs.c, fatfs.c, and devfs.c to support
the <.> and <..> directory entries.

Location:
trunk/kernel/fs
Files:
6 edited

Legend:

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

    r610 r612  
    2727#include <hal_uspace.h>
    2828#include <printk.h>
     29#include <string.h>
    2930#include <chdev.h>
    3031#include <thread.h>
     
    102103                                     devfs_dev_inode_xp );
    103104
     105    // create dentries <.> and <..> in <dev>
     106    error |= vfs_add_special_dentries( *devfs_dev_inode_xp,
     107                                       root_inode_xp );
     108
    104109// check success
    105110assert( (error == 0) , "cannot create <dev>\n" );
     
    122127                                     devfs_external_inode_xp );
    123128
    124     assert( (error == 0) , "cannot create <external>\n" );
     129    // create dentries <.> and <..> in <external>
     130    error |= vfs_add_special_dentries( *devfs_external_inode_xp,
     131                                       *devfs_dev_inode_xp );
     132
     133// check success
     134assert( (error == 0) , "cannot create <external>\n" );
    125135
    126136#if DEBUG_DEVFS_INIT
     
    147157    uint32_t      channel;
    148158    xptr_t        unused_xp;    // required by add_child_in_parent()
     159    error_t       error;
    149160
    150161    // create "internal" directory
    151162    snprintf( node_name , 16 , "internal_%x" , local_cxy );
    152163
    153     vfs_add_child_in_parent( local_cxy,
    154                              INODE_TYPE_DIR,
    155                              FS_TYPE_DEVFS,
    156                              devfs_dev_inode_xp,
    157                              node_name,
    158                              &unused_xp,
    159                              devfs_internal_inode_xp );
     164    error = vfs_add_child_in_parent( local_cxy,
     165                                     INODE_TYPE_DIR,
     166                                     FS_TYPE_DEVFS,
     167                                     devfs_dev_inode_xp,
     168                                     node_name,
     169                                     &unused_xp,
     170                                     devfs_internal_inode_xp );
     171
     172    // create dentries <.> and <..> in <internal>
     173    error |= vfs_add_special_dentries( *devfs_internal_inode_xp,
     174                                       devfs_dev_inode_xp );
     175
     176// check success
     177assert( (error == 0) , "cannot create <external>\n" );
     178
    160179#if DEBUG_DEVFS_INIT
    161180uint32_t   cycle = (uint32_t)hal_get_cycles();
     
    173192        chdev_cxy = GET_CXY( chdev_xp );
    174193
    175 assert( (chdev_cxy == local_cxy ),
    176 "illegal MMC chdev_xp in cluster %x\n", local_cxy );
    177 
    178         vfs_add_child_in_parent( local_cxy,
    179                                  INODE_TYPE_DEV,
    180                                  FS_TYPE_DEVFS,
    181                                  *devfs_internal_inode_xp,
    182                                  chdev_ptr->name,
    183                                  &unused_xp,
    184                                  &inode_xp );
     194assert( (chdev_cxy == local_cxy ), "illegal MMC chdev in cluster %x\n", local_cxy );
     195
     196        error = vfs_add_child_in_parent( local_cxy,
     197                                         INODE_TYPE_DEV,
     198                                         FS_TYPE_DEVFS,
     199                                         *devfs_internal_inode_xp,
     200                                         chdev_ptr->name,
     201                                         &unused_xp,
     202                                         &inode_xp );
     203
     204assert( (error == 0) , "cannot create MMC inode\n" );
    185205
    186206        // update child inode "extend" field
     
    207227            chdev_cxy = GET_CXY( chdev_xp );
    208228
    209 assert( (chdev_cxy == local_cxy ),
    210 "illegal DMA[%d] chdev_xp in cluster %x\n", channel, local_cxy );
    211 
    212             vfs_add_child_in_parent( local_cxy,
    213                                      INODE_TYPE_DEV,
    214                                      FS_TYPE_DEVFS,
    215                                      *devfs_internal_inode_xp,
    216                                      chdev_ptr->name,
    217                                      &unused_xp,
    218                                      &inode_xp );
     229assert( (chdev_cxy == local_cxy ), "illegal DMA chdev in cluster %x\n", local_cxy );
     230
     231            error = vfs_add_child_in_parent( local_cxy,
     232                                             INODE_TYPE_DEV,
     233                                             FS_TYPE_DEVFS,
     234                                             *devfs_internal_inode_xp,
     235                                             chdev_ptr->name,
     236                                             &unused_xp,
     237                                             &inode_xp );
     238
     239assert( (error == 0) , "cannot create DMA inode\n" );
    219240
    220241            // update child inode "extend" field
     
    241262        if( chdev_cxy == local_cxy )
    242263        {
    243             vfs_add_child_in_parent( local_cxy,
    244                                      INODE_TYPE_DEV,
    245                                      FS_TYPE_DEVFS,
    246                                      devfs_external_inode_xp,
    247                                      chdev_ptr->name,
    248                                      &unused_xp,
    249                                      &inode_xp );
     264            error = vfs_add_child_in_parent( local_cxy,
     265                                             INODE_TYPE_DEV,
     266                                             FS_TYPE_DEVFS,
     267                                             devfs_external_inode_xp,
     268                                             chdev_ptr->name,
     269                                             &unused_xp,
     270                                             &inode_xp );
     271
     272assert( (error == 0) , "cannot create IOB inode\n" );
    250273
    251274            // update child inode "extend" field
     
    272295        if( chdev_cxy == local_cxy )
    273296        {
    274             vfs_add_child_in_parent( local_cxy,
    275                                      INODE_TYPE_DEV,
    276                                      FS_TYPE_DEVFS,
    277                                      devfs_external_inode_xp,
    278                                      chdev_ptr->name,
    279                                      &unused_xp,
    280                                      &inode_xp );
     297            error = vfs_add_child_in_parent( local_cxy,
     298                                             INODE_TYPE_DEV,
     299                                             FS_TYPE_DEVFS,
     300                                             devfs_external_inode_xp,
     301                                             chdev_ptr->name,
     302                                             &unused_xp,
     303                                             &inode_xp );
     304
     305assert( (error == 0) , "cannot create PIC inode\n" );
    281306
    282307            // update child inode "extend" field
     
    305330            if( chdev_cxy == local_cxy )
    306331            {
    307                 vfs_add_child_in_parent( local_cxy,
    308                                          INODE_TYPE_DEV,
    309                                          FS_TYPE_DEVFS,
    310                                          devfs_external_inode_xp,
    311                                          chdev_ptr->name,
    312                                          &unused_xp,
    313                                          &inode_xp );
     332                error = vfs_add_child_in_parent( local_cxy,
     333                                                 INODE_TYPE_DEV,
     334                                                 FS_TYPE_DEVFS,
     335                                                 devfs_external_inode_xp,
     336                                                 chdev_ptr->name,
     337                                                 &unused_xp,
     338                                                 &inode_xp );
     339
     340assert( (error == 0) , "cannot create TXT_RX inode\n" );
    314341
    315342                // update child inode "extend" field
     
    339366            if( chdev_cxy == local_cxy )
    340367            {
    341                 vfs_add_child_in_parent( local_cxy,
    342                                          INODE_TYPE_DEV,
    343                                          FS_TYPE_DEVFS,
    344                                          devfs_external_inode_xp,
    345                                          chdev_ptr->name,
    346                                          &unused_xp,
    347                                          &inode_xp );
     368                error = vfs_add_child_in_parent( local_cxy,
     369                                                 INODE_TYPE_DEV,
     370                                                 FS_TYPE_DEVFS,
     371                                                 devfs_external_inode_xp,
     372                                                 chdev_ptr->name,
     373                                                 &unused_xp,
     374                                                 &inode_xp );
     375
     376assert( (error == 0) , "cannot create TXT_TX inode\n" );
    348377
    349378                // update child inode "extend" field
     
    373402            if( chdev_cxy == local_cxy )
    374403            {
    375                 vfs_add_child_in_parent( local_cxy,
    376                                          INODE_TYPE_DEV,
    377                                          FS_TYPE_DEVFS,
    378                                          devfs_external_inode_xp,
    379                                          chdev_ptr->name,
    380                                          &unused_xp,
    381                                          &inode_xp );
     404                error = vfs_add_child_in_parent( local_cxy,
     405                                                 INODE_TYPE_DEV,
     406                                                 FS_TYPE_DEVFS,
     407                                                 devfs_external_inode_xp,
     408                                                 chdev_ptr->name,
     409                                                 &unused_xp,
     410                                                 &inode_xp );
     411
     412assert( (error == 0) , "cannot create IOC inode\n" );
    382413
    383414                // update child inode "extend" field
     
    407438            if( chdev_cxy == local_cxy )
    408439            {
    409                 vfs_add_child_in_parent( local_cxy,
    410                                          INODE_TYPE_DEV,
    411                                          FS_TYPE_DEVFS,
    412                                          devfs_external_inode_xp,
    413                                          chdev_ptr->name,
    414                                          &unused_xp,
    415                                          &inode_xp );
     440                error = vfs_add_child_in_parent( local_cxy,
     441                                                 INODE_TYPE_DEV,
     442                                                 FS_TYPE_DEVFS,
     443                                                 devfs_external_inode_xp,
     444                                                 chdev_ptr->name,
     445                                                 &unused_xp,
     446                                                 &inode_xp );
     447
     448assert( (error == 0) , "cannot create FBF inode\n" );
    416449
    417450                // update child inode "extend" field
     
    441474            if( chdev_cxy == local_cxy )
    442475            {
    443                 vfs_add_child_in_parent( local_cxy,
    444                                          INODE_TYPE_DEV,
    445                                          FS_TYPE_DEVFS,
    446                                          devfs_external_inode_xp,
    447                                          chdev_ptr->name,
    448                                          &unused_xp,
    449                                          &inode_xp );
     476                error = vfs_add_child_in_parent( local_cxy,
     477                                                 INODE_TYPE_DEV,
     478                                                 FS_TYPE_DEVFS,
     479                                                 devfs_external_inode_xp,
     480                                                 chdev_ptr->name,
     481                                                 &unused_xp,
     482                                                 &inode_xp );
     483
     484assert( (error == 0) , "cannot create NIC_RX inode\n" );
     485
     486                // update child inode "extend" field
     487                inode_cxy = GET_CXY( inode_xp );
     488                inode_ptr = GET_PTR( inode_xp );
     489                hal_remote_spt( XPTR( inode_cxy , &inode_ptr->extend ) , chdev_ptr );
     490 
    450491#if DEBUG_DEVFS_INIT
    451492cycle = (uint32_t)hal_get_cycles();
     
    469510            if( chdev_cxy == local_cxy )
    470511            {
    471                 vfs_add_child_in_parent( local_cxy,
    472                                          INODE_TYPE_DEV,
    473                                          FS_TYPE_DEVFS,
    474                                          devfs_external_inode_xp,
    475                                          chdev_ptr->name,
    476                                          &unused_xp,
    477                                          &inode_xp );
     512                error = vfs_add_child_in_parent( local_cxy,
     513                                                 INODE_TYPE_DEV,
     514                                                 FS_TYPE_DEVFS,
     515                                                 devfs_external_inode_xp,
     516                                                 chdev_ptr->name,
     517                                                 &unused_xp,
     518                                                 &inode_xp );
     519
     520assert( (error == 0) , "cannot create NIC_TX inode\n" );
    478521
    479522                // update child inode "extend" field
     
    620663}  // end devfs_user_move()
    621664
    622 
     665///////////////////////////////////////////////////////
     666error_t devfs_get_user_dir( struct vfs_inode_s * inode,
     667                            struct dirent      * array,
     668                            uint32_t             max_dirent,
     669                            uint32_t             min_dentry,
     670                            bool_t               detailed,
     671                            uint32_t           * entries,
     672                            bool_t             * done )
     673{
     674    xptr_t         xhtab_xp;    // extended pointer on inode xhtab (children dentries)
     675    xptr_t         dentry_xp;   // extended pointer on current dentry
     676    vfs_dentry_t * dentry_ptr;  // local pointer on current dentry
     677    uint32_t       dentry_id;   // dentry index in set of children dentry   
     678    uint32_t       dirent_id;   // dirent index in array of dirent
     679
     680// detailed argument unused
     681assert( (detailed == false) , "detailed argument not supported\n");
     682 
     683    // One loop to scan the target inode xhtab containing the set of dentries
     684    // exit loop if no more dentries, or dirent array full
     685
     686#if DEBUG_DEVFS_GET_USER_DIR
     687char       inode_name[CONFIG_VFS_MAX_NAME_LENGTH];
     688uint32_t   cycle = (uint32_t)hal_get_cycles();
     689thread_t * this  = CURRENT_THREAD;
     690vfs_inode_get_name( XPTR( local_cxy , inode ) , inode_name );
     691if( DEBUG_DEVFS_GET_USER_DIR < cycle )
     692printk("\n[%s]  thread[%x,%x] enter for inode <%s> / cycle %d\n",
     693__FUNCTION__, this->process->pid, this->trdid, inode_name , cycle );
     694#endif
     695
     696    // get extended pointer on inode xhtab
     697    xhtab_xp  = XPTR( local_cxy , &inode->children );
     698
     699    // initialize loop variables
     700    dentry_xp = xhtab_get_first( xhtab_xp );
     701    dentry_id = 0;
     702    dirent_id = 0;
     703
     704    while( (dentry_xp != XPTR_NULL ) && (dirent_id < max_dirent) )
     705    {
     706        if( dentry_id >= min_dentry )
     707        {
     708            // copy name into dirent array
     709            dentry_ptr = GET_PTR( dentry_xp );
     710            strcpy( array[dirent_id].d_name , dentry_ptr->name );
     711
     712            // increment dirent_id
     713            dirent_id++;
     714        }
     715         
     716        // update loop variables
     717        dentry_xp = xhtab_get_next( xhtab_xp );
     718        dentry_id++;
     719    }
     720
     721    // return results of scan
     722    *done    = (dentry_xp == XPTR_NULL);
     723    *entries = dirent_id;
     724
     725#if DEBUG_DEVFS_GET_USER_DIR
     726cycle = (uint32_t)hal_get_cycles();
     727if( DEBUG_DEVFS_GET_USER_DIR < cycle )
     728printk("\n[%s]  thread[%x,%x] exit for inode <%s> / %d entries / cycle %d\n",
     729__FUNCTION__, this->process->pid, this->trdid, inode_name, entries, cycle );
     730#endif
     731
     732    return 0;
     733   
     734}  // en devfs_get_user_dir()
     735
  • trunk/kernel/fs/devfs.h

    r598 r612  
    137137                     uint32_t size );
    138138
     139/******************************************************************************************
     140 * As the DEVFS is dynamically build in memory during kernel init, all relevant
     141 * information is contained in the Inode Tree. Therefore, this function simply
     142 * access the xhtab contained in the <inode> descriptor, to get the  dentries
     143 * to be copied in the dirent <array>.
     144 ******************************************************************************************
     145 * @ inode      : [in]  local pointer on directory inode.
     146 * @ array      : [in]  local pointer on array of dirents.
     147 * @ max_dirent : [in]  max number of slots in dirent array.
     148 * @ min_dentry : [in]  index of first dentry to be copied into array.
     149 * @ detailed   : [in]  dynamic inode creation if true.
     150 * @ entries    : [out] number of dentries actually copied into array.
     151 * @ done       : [out] Boolean true when last entry found.
     152 * @ return 0 if success / return -1 if failure.
     153 *****************************************************************************************/
     154error_t devfs_get_user_dir( struct vfs_inode_s * inode,
     155                            struct dirent      * array,
     156                            uint32_t             max_dirent,
     157                            uint32_t             min_dentry,
     158                            bool_t               detailed,
     159                            uint32_t           * entries,
     160                            bool_t             * done );
     161
    139162
    140163#endif  /* _DEVFS_H_ */
  • trunk/kernel/fs/fatfs.c

    r611 r612  
    13591359}  // end fatfs_remove_dentry
    13601360
    1361 ////////////////////////////////////////////////////////////////
    1362 error_t fatfs_child_init( vfs_inode_t * parent_inode,
     1361/////////////////////////////////////////////////////
     1362error_t fatfs_get_dentry( vfs_inode_t * parent_inode,
    13631363                          char        * name,
    13641364                          xptr_t        child_inode_xp )
     
    13681368    // - scan the directory entries in each 4 Kbytes page
    13691369
    1370 #if DEBUG_FATFS_CHILD_INIT
     1370#if DEBUG_FATFS_GET_DENTRY
    13711371char       parent_name[CONFIG_VFS_MAX_NAME_LENGTH];
    13721372uint32_t   cycle = (uint32_t)hal_get_cycles();
    13731373thread_t * this  = CURRENT_THREAD;
    13741374vfs_inode_get_name( XPTR( local_cxy , parent_inode ) , parent_name );
    1375 if( DEBUG_FATFS_CHILD_INIT < cycle )
     1375if( DEBUG_FATFS_GET_DENTRY < cycle )
    13761376printk("\n[%s]  thread[%x,%x] enter for child <%s> in parent <%s> / cycle %d\n",
    13771377__FUNCTION__, this->process->pid, this->trdid, name , parent_name , cycle );
     
    14201420        base    = (uint8_t *)GET_PTR( base_xp );
    14211421
    1422 #if (DEBUG_FATFS_CHILD_INIT & 0x1)
    1423 if( DEBUG_FATFS_CHILD_INIT < cycle )
    1424 {
    1425     uint32_t * buf = (uint32_t *)base;
    1426     uint32_t line , word;
    1427     printk("\n[%s] First 16 dentries for <%s>\n",
    1428     __FUNCTION__ , parent_name );
    1429     for( line = 0 ; line < 16 ; line++ )
    1430     {
    1431         printk("%X : ", line );
    1432         for( word = 0 ; word < 8 ; word++ ) printk("%X ", buf[(line<<4) + word] );
    1433         printk("\n");
    1434     }
    1435 }
     1422#if (DEBUG_FATFS_GET_DENTRY & 0x1)
     1423if( DEBUG_FATFS_GET_DENTRY < cycle )
     1424mapper_display_page( mapper_xp , page_id , 256 , parent_name );
    14361425#endif
    14371426        // scan this page until end of directory, end of page, or name found
     
    15061495    {
    15071496
    1508 #if DEBUG_FATFS_CHILD_INIT
     1497#if DEBUG_FATFS_GET_DENTRY
    15091498cycle = (uint32_t)hal_get_cycles();
    1510 if( DEBUG_FATFS_CHILD_INIT < cycle )
     1499if( DEBUG_FATFS_GET_DENTRY < cycle )
    15111500printk("\n[%s]  thread[%x,%x] exit / child <%s> not found / cycle %d\n",
    15121501__FUNCTION__, this->process->pid, this->trdid, name, cycle );
     
    15441533    dentry_ptr->extend = (void *)(intptr_t)dentry_id;
    15451534
    1546 #if DEBUG_FATFS_CHILD_INIT
     1535#if DEBUG_FATFS_GET_DENTRY
    15471536cycle = (uint32_t)hal_get_cycles();
    1548 if( DEBUG_FATFS_CHILD_INIT < cycle )
     1537if( DEBUG_FATFS_GET_DENTRY < cycle )
    15491538printk("\n[%s]  thread[%x,%x] exit / child <%s> loaded in <%s> / cycle %d\n",
    15501539__FUNCTION__, this->process->pid, this->trdid, name, parent_name, cycle );
     
    15531542    return 0;
    15541543
    1555 }  // end fatfs_child_init()
     1544}  // end fatfs_get_dentry()
     1545
     1546///////////////////////////////////////////////////////
     1547error_t fatfs_get_user_dir( struct vfs_inode_s * inode,
     1548                            struct dirent      * array,
     1549                            uint32_t             max_dirent,
     1550                            uint32_t             min_dentry,
     1551                            bool_t               detailed,
     1552                            uint32_t           * entries,
     1553                            bool_t             * done )
     1554{
     1555    // Two embedded loops to scan the directory mapper:
     1556    // - scan the parent directory mapper pages starting always from page 0
     1557    // - scan the 32 bytes NORMAL/LFN directory entries in each page
     1558    // Only valid dentries are copied : dentry_id >= min_dentry && dirent_id < dirent_max
     1559
     1560#if DEBUG_FATFS_GET_USER_DIR
     1561char       inode_name[CONFIG_VFS_MAX_NAME_LENGTH];
     1562uint32_t   cycle = (uint32_t)hal_get_cycles();
     1563thread_t * this  = CURRENT_THREAD;
     1564vfs_inode_get_name( XPTR( local_cxy , inode ) , inode_name );
     1565if( DEBUG_FATFS_GET_USER_DIR < cycle )
     1566printk("\n[%s]  thread[%x,%x] enter for inode <%s> / cycle %d\n",
     1567__FUNCTION__, this->process->pid, this->trdid, inode_name , cycle );
     1568#endif
     1569
     1570    mapper_t * mapper    = inode->mapper;
     1571    xptr_t     mapper_xp = XPTR( local_cxy , mapper );
     1572
     1573// check mapper pointer
     1574assert( (mapper != NULL) , "mapper is NULL\n");
     1575   
     1576// TODO handle the detailed flag
     1577assert( (detailed == false), "detailed argument not supported/n");
     1578
     1579    char       cname[CONFIG_VFS_MAX_NAME_LENGTH];  // name extracter from each directory entry
     1580
     1581    char       lfn1[16];           // buffer for one partial cname
     1582    char       lfn2[16];           // buffer for one partial cname
     1583    char       lfn3[16];           // buffer for one partial cname
     1584    xptr_t     page_xp;            // extended pointer on page descriptor
     1585    xptr_t     base_xp;            // extended pointer on page base
     1586    uint8_t  * base;               // local pointer on page base
     1587    uint32_t   attr;               // directory entry ATTR field
     1588    uint32_t   ord;                // directory entry ORD field
     1589    uint32_t   seq;                // sequence index
     1590    uint32_t   lfn       = 0;      // LFN entries number
     1591    uint32_t   offset    = 0;      // byte offset in page
     1592    uint32_t   page_id   = 0;      // page index in mapper
     1593    uint32_t   dentry_id = 0;      // valid (i.e. copied) dentry index in mapper
     1594    uint32_t   dirent_id = 0;      // slot index in dirent array to initialize
     1595    bool_t     end       = false;  // true if end of directory found
     1596
     1597    // loop on mapper pages
     1598    while ( (end == false) && (dirent_id < max_dirent) )
     1599    {
     1600        // get one page from mapper
     1601        page_xp = mapper_remote_get_page( mapper_xp , page_id );
     1602
     1603        if( page_xp == XPTR_NULL) return -1;
     1604
     1605        // get page base
     1606        base_xp = ppm_page2base( page_xp );
     1607        base    = (uint8_t *)GET_PTR( base_xp );
     1608
     1609#if (DEBUG_FATFS_GET_USER_DIR & 0x1)
     1610if( DEBUG_FATFS_GET_USER_DIR < cycle )
     1611mapper_display_page( mapper_xp , page_id , 256 , inode_name );
     1612#endif
     1613        // loop on NORMAL/LFN (32 bytes) directory entries in this page
     1614        while( (end == false) && (offset < 4096) )
     1615        {
     1616            // compute condition to copy one dentry to dirent array
     1617            bool_t valid = (dentry_id >= min_dentry) && (dirent_id <  max_dirent );
     1618
     1619            attr = fatfs_get_record( DIR_ATTR , base + offset , 0 );   
     1620            ord  = fatfs_get_record( LDIR_ORD , base + offset , 0 );   
     1621
     1622            if (ord == NO_MORE_ENTRY)                 // no more entry => break
     1623            {
     1624                end = true;
     1625            }
     1626            else if ( ord == FREE_ENTRY )             // free entry => skip
     1627            {
     1628                offset = offset + 32;
     1629            }
     1630            else if ( attr == ATTR_LONG_NAME_MASK )   // LFN entry
     1631            {
     1632                if( valid )
     1633                {
     1634                    // get partial cname
     1635                    seq = ord & 0x3;
     1636                    lfn = (seq > lfn) ? seq : lfn;   
     1637                    if      ( seq == 1 ) fatfs_get_name_from_long( base + offset, lfn1 );
     1638                    else if ( seq == 2 ) fatfs_get_name_from_long( base + offset, lfn2 );
     1639                    else if ( seq == 3 ) fatfs_get_name_from_long( base + offset, lfn3 );
     1640                }
     1641                offset = offset + 32;
     1642            }
     1643            else                                     // NORMAL entry
     1644            {
     1645                // increment dentry_id
     1646                dentry_id++;
     1647
     1648                if( valid )
     1649                {
     1650                    // build the complete cname
     1651                    if      ( lfn == 0 )
     1652                    {
     1653                        fatfs_get_name_from_short( base + offset , cname );
     1654                    }
     1655                    else if ( lfn == 1 )
     1656                    {
     1657                        strcpy( cname      , lfn1 );
     1658                    }   
     1659                    else if ( lfn == 2 )
     1660                    {
     1661                        strcpy( cname      , lfn1 );
     1662                        strcpy( cname + 13 , lfn2 );
     1663                    }
     1664                    else if ( lfn == 3 )
     1665                    {
     1666                        strcpy( cname      , lfn1 );
     1667                        strcpy( cname + 13 , lfn2 );
     1668                        strcpy( cname + 26 , lfn3 );
     1669                    }
     1670                   
     1671                    // copy cname into dirent array
     1672                    strcpy( array[dirent_id].d_name , cname );
     1673
     1674                    // increment dirent_id
     1675                    dirent_id++;
     1676                }
     1677                offset = offset + 32;
     1678                lfn    = 0;
     1679            }
     1680        }  // end loop on directory entries in page
     1681
     1682        page_id++;
     1683        offset = 0;
     1684
     1685    }  // end loop on pages
     1686
     1687    // return result of scan
     1688    *done    = end;
     1689    *entries = dirent_id;
     1690
     1691#if DEBUG_FATFS_GET_USER_DIR
     1692cycle = (uint32_t)hal_get_cycles();
     1693if( DEBUG_FATFS_GET_USER_DIR < cycle )
     1694printk("\n[%s]  thread[%x,%x] exit for inode <%s> / %d entries / cycle %d\n",
     1695__FUNCTION__, this->process->pid, this->trdid, inode_name, entries, cycle );
     1696#endif
     1697
     1698    return 0;
     1699
     1700}  // end fatfs_get_user_dir()
    15561701
    15571702///////////////////////////////////////////////
  • trunk/kernel/fs/fatfs.h

    r611 r612  
    114114#define NAME_MAX_SIZE           31
    115115
    116 /******* Directory Entry Structure (32 bytes) **********************************/
     116/******* SFN Directory Entry Structure (32 bytes) ******************************/
    117117//                            offset | length
    118118#define DIR_NAME                   0 , 11   // dir_entry name
     
    308308
    309309/*****************************************************************************************
    310  * This function implements the generic vfs_fs_child_init() function for the FATFS.
    311  *****************************************************************************************
    312  * It tries to initialise a new child (new inode/dentry couple in Inode Tree), identified
     310 * This function implements the generic vfs_fs_get_dentry() function for the FATFS.
     311 *****************************************************************************************
     312 * It initialises a new child (new inode/dentry couple in Inode Tree), identified
    313313 * by the <child_inode_xp> argument, from the parent directory mapper, identified by the
    314314 * <parent_inode> argument.
    315  * - It scan the parent mapper to find the <name> argument.
    316  * - it set the "type", "size", and "extend" fields in inode descriptor.
    317  * - it set the " extend" field in dentry descriptor.
     315 * It scan the parent mapper to find the <name> argument.
     316 * It set the "type", "size", and "extend" fields in inode descriptor.
     317 * It set the " extend" field in dentry descriptor.
    318318 * It must be called by a thread running in the cluster containing the parent inode.
    319319 *****************************************************************************************
     
    323323 * @ return 0 if success / return ENOENT if child not found.
    324324 ****************************************************************************************/
    325 error_t fatfs_child_init( struct vfs_inode_s * parent_inode,
     325error_t fatfs_get_dentry( struct vfs_inode_s * parent_inode,
    326326                          char               * name,
    327327                          xptr_t               child_inode_xp );
     328
     329/*****************************************************************************************
     330 * This function implements the generic vfs_fs_get_user_dir() function for the FATFS.
     331 *****************************************************************************************
     332 * It is called by the remote_dir_create() function to scan the mapper of a directory
     333 * identified by the <inode> argument and copy up to <max_dirent> valid dentries to a
     334 * local dirent array, defined by the <array> argument. The <min_dentry> argument defines
     335 * the index of the first dentry to copied to the target dirent array.
     336 * This function returns in the <entries> buffer the number of dentries actually written,
     337 * and signals in the <done> buffer when the last valid entry has been found.
     338 * If the <detailed> argument is true, a dentry/inode couple that does not exist in
     339 * the Inode Tree is dynamically created, and all dirent fiels are documented in the
     340 * dirent array. Otherwise, only the dentry name is documented.
     341 * It must be called by a thread running in the cluster containing the directory inode.
     342 *****************************************************************************************
     343 * @ inode      : [in]  local pointer on directory inode.
     344 * @ array      : [in]  local pointer on array of dirents.
     345 * @ max_dirent : [in]  max number of slots in dirent array.
     346 * @ min_dentry : [in]  index of first dentry to be copied into array.
     347 * @ detailed   : [in]  dynamic inode creation if true.
     348 * @ entries    : [out] number of dentries actually copied into array.
     349 * @ done       : [out] Boolean true when last entry found.
     350 * @ return 0 if success / return -1 if failure.
     351 ****************************************************************************************/
     352error_t fatfs_get_user_dir( struct vfs_inode_s * inode,
     353                            struct dirent      * array,
     354                            uint32_t             max_dirent,
     355                            uint32_t             min_dentry,
     356                            bool_t               detailed,
     357                            uint32_t           * entries,
     358                            bool_t             * done );
    328359
    329360/*****************************************************************************************
  • trunk/kernel/fs/vfs.c

    r611 r612  
    23502350                if( parent_cxy == local_cxy )
    23512351                {
    2352                     error = vfs_fs_child_init( parent_ptr,
     2352                    error = vfs_fs_get_dentry( parent_ptr,
    23532353                                               name,
    23542354                                               child_xp );
     
    23562356                else
    23572357                {
    2358                     rpc_vfs_fs_child_init_client( parent_cxy,
     2358                    rpc_vfs_fs_get_dentry_client( parent_cxy,
    23592359                                                  parent_ptr,
    23602360                                                  name,
     
    23672367                    if ( last && create )  // add a brand new dentry in parent
    23682368                    {
    2369                         error = vfs_new_child_init( parent_xp,               
    2370                                                     dentry_xp,
    2371                                                     child_xp );
     2369                        error = vfs_new_dentry_init( parent_xp,               
     2370                                                     dentry_xp,
     2371                                                     child_xp );
    23722372                        if ( error )
    23732373                        {
     
    25102510}  // end vfs_lookup()
    25112511
    2512 ///////////////////////////////////////////////
    2513 error_t vfs_new_child_init( xptr_t   parent_xp,
    2514                             xptr_t   dentry_xp,
    2515                             xptr_t   child_xp )
     2512////////////////////////////////////////////////
     2513error_t vfs_new_dentry_init( xptr_t   parent_xp,
     2514                             xptr_t   dentry_xp,
     2515                             xptr_t   child_xp )
    25162516{
    25172517    error_t     error;
     
    25992599    return 0;
    26002600
    2601 }  // end vfs_new_child_init()
     2601}  // end vfs_new_dentry_init()
    26022602
    26032603///////////////////////////////////////////////////
     
    26152615    vfs_dentry_t  * dentry_ptr;        // local pointer on dentry (used for . and ..)
    26162616
    2617     xptr_t          parents_root_xp;   // extended pointer on inode "parents" field
    2618     xptr_t          parents_entry_xp;  // extended pointer on dentry "parents" field
     2617    // xptr_t          parents_root_xp;   // extended pointer on inode "parents" field
     2618    // xptr_t          parents_entry_xp;  // extended pointer on dentry "parents" field
    26192619    xptr_t          children_xhtab_xp; // extended pointer on inode "children" field
    26202620    xptr_t          children_entry_xp; // extended pointer on dentry "children" field
     
    26282628vfs_inode_get_name( parent_xp , parent_name );
    26292629if( DEBUG_VFS_ADD_SPECIAL < cycle )
    2630 printk("\n[%s] thread[%x,%x] enter / child <%s> / parent <%s> / cycle %d\n",
     2630printk("\n[%s] thread[%x,%x] enter for child <%s> in parent <%s> / cycle %d\n",
    26312631__FUNCTION__, this->process->pid, this->trdid, child_name, parent_name, cycle );
    26322632#endif
     
    26862686    }
    26872687
    2688     // register <.> dentry in child_inode xlist of parents TODO faut-il ?
    2689     parents_root_xp  = XPTR( child_cxy , &child_ptr->parents );
    2690     parents_entry_xp = XPTR( child_cxy , &dentry_ptr->parents );
    2691     xlist_add_first( parents_root_xp , parents_entry_xp );
    2692     hal_remote_atomic_add( XPTR( child_cxy , &child_ptr->links ) , 1 );
     2688   
     2689    // don't register <.> dentry in child_inode xlist of parents
     2690    // parents_root_xp  = XPTR( child_cxy , &child_ptr->parents );
     2691    // parents_entry_xp = XPTR( child_cxy , &dentry_ptr->parents );
     2692    // xlist_add_first( parents_root_xp , parents_entry_xp );
     2693    // hal_remote_atomic_add( XPTR( child_cxy , &child_ptr->links ) , 1 );
    26932694
    26942695    // update "parent" and "child_xp" fields in <.> dentry
     
    27702771    }
    27712772
    2772     // register <..> dentry in parent_inode xlist of parents TODO faut-il ?
    2773     parents_root_xp  = XPTR( parent_cxy , &parent_ptr->parents );
    2774     parents_entry_xp = XPTR( child_cxy  , &dentry_ptr->parents );
    2775     xlist_add_first( parents_root_xp , parents_entry_xp );
    2776     hal_remote_atomic_add( XPTR( parent_cxy , &parent_ptr->links ) , 1 );
     2773    // don't register <..> dentry in parent_inode xlist of parents
     2774    // parents_root_xp  = XPTR( parent_cxy , &parent_ptr->parents );
     2775    // parents_entry_xp = XPTR( child_cxy  , &dentry_ptr->parents );
     2776    // xlist_add_first( parents_root_xp , parents_entry_xp );
     2777    // hal_remote_atomic_add( XPTR( parent_cxy , &parent_ptr->links ) , 1 );
    27772778
    27782779    // update "parent" and "child_xp" fields in <..> dentry
     
    28152816cycle = (uint32_t)hal_get_cycles();
    28162817if( DEBUG_VFS_ADD_SPECIAL < cycle )
    2817 printk("\n[%s] thread[%x,%x] exit / cycle %d\n",
    2818 __FUNCTION__, this->process->pid, this->trdid, (uint32_t)hal_get_cycles() );
     2818printk("\n[%s] thread[%x,%x] exit for child <%s> in parent <%s> / cycle %d\n",
     2819__FUNCTION__, this->process->pid, this->trdid, child_name, parent_name, cycle );
    28192820#endif
    28202821
     
    31833184}  // end vfs_remove_child_from_parent()
    31843185
     3186
     3187
     3188
    31853189//////////////////////////////////////////////////////////////////////////////////////////
    31863190//    API used by VFS to access a specific FS 
     
    32513255    else if( fs_type == FS_TYPE_RAMFS )
    32523256    {
    3253         assert( false , "should not be called for RAMFS\n" );
     3257        error = 0;     // does nothing for RAMFS
    32543258    }
    32553259    else if( fs_type == FS_TYPE_DEVFS )
    32563260    {
    3257         assert( false , "should not be called for DEVFS\n" );
     3261        error = 0;     // does nothing for DEVFS
    32583262    }
    32593263    else
     
    32893293    else if( fs_type == FS_TYPE_RAMFS )
    32903294    {
    3291         assert( false , "should not be called for RAMFS\n" );
     3295        error = 0;     // does nothing for RAMFS
    32923296    }
    32933297    else if( fs_type == FS_TYPE_DEVFS )
    32943298    {
    3295         assert( false , "should not be called for DEVFS\n" );
     3299        error = 0;     // does nothing for DEVFS
    32963300    }
    32973301    else
     
    33053309
    33063310////////////////////////////////////////////////
    3307 error_t vfs_fs_child_init( vfs_inode_t * parent,
     3311error_t vfs_fs_get_dentry( vfs_inode_t * parent,
    33083312                           char        * name,
    33093313                           xptr_t        child_xp )
     
    33213325    if( fs_type == FS_TYPE_FATFS )
    33223326    {
    3323         error = fatfs_child_init( parent , name , child_xp );
     3327        error = fatfs_get_dentry( parent , name , child_xp );
    33243328    }
    33253329    else if( fs_type == FS_TYPE_RAMFS )
     
    33383342    return error;
    33393343
    3340 } // end vfs_fs_child_init()
    3341 
     3344} // end vfs_fs_get_dentry()
     3345
     3346///////////////////////////////////////////////////
     3347error_t vfs_fs_get_user_dir( vfs_inode_t   * inode,
     3348                             struct dirent * array,
     3349                             uint32_t        max_dirent,
     3350                             uint32_t        min_dentry,
     3351                             bool_t          detailed,
     3352                             uint32_t      * entries,
     3353                             bool_t        * done )
     3354{
     3355    error_t error = 0;
     3356
     3357// check arguments
     3358assert( (inode != NULL) , "parent pointer is NULL\n");
     3359assert( (array != NULL) , "child pointer is NULL\n");
     3360assert( (detailed == false) , "detailed argument not supported\n");
     3361
     3362    // check inode type
     3363    if( inode->type != INODE_TYPE_DIR )
     3364    {
     3365        printk("\n[ERROR] in %s : target inode is not a directory\n",
     3366        __FUNCTION__ );
     3367        return -1;
     3368    }
     3369
     3370    // get parent inode FS type
     3371    vfs_fs_type_t fs_type = inode->ctx->type;
     3372
     3373    // call relevant FS function
     3374    if( fs_type == FS_TYPE_FATFS )
     3375    {
     3376        error = fatfs_get_user_dir( inode,
     3377                                    array,
     3378                                    max_dirent,
     3379                                    min_dentry,
     3380                                    detailed,
     3381                                    entries,
     3382                                    done );
     3383    }
     3384    else if( fs_type == FS_TYPE_RAMFS )
     3385    {
     3386        assert( false , "should not be called for RAMFS\n" );
     3387    }
     3388    else if( fs_type == FS_TYPE_DEVFS )
     3389    {
     3390        error = devfs_get_user_dir( inode,
     3391                                    array,
     3392                                    max_dirent,
     3393                                    min_dentry,
     3394                                    detailed,
     3395                                    entries,
     3396                                    done );
     3397    }
     3398    else
     3399    {
     3400        assert( false , "undefined file system type\n" );
     3401    }
     3402
     3403    return error;
     3404
     3405}  // end vfs_fs_get_user_dir()
     3406 
    33423407////////////////////////////////////////////////
    33433408error_t vfs_fs_sync_inode( vfs_inode_t * inode )
  • trunk/kernel/fs/vfs.h

    r611 r612  
    467467
    468468
     469
    469470/******************************************************************************************
    470471 *        These functions access / modify the distributed VFS Inode Tree
     
    599600 * @ return 0 if success / -1 if failure.
    600601 *****************************************************************************************/
    601 error_t vfs_new_child_init( xptr_t   parent_xp,
    602                             xptr_t   dentry_xp,
    603                             xptr_t   child_xp );
    604 
    605 /******************************************************************************************
    606  * This function is called by the vfs_mkdir() function to create the two special dentries
    607  * <.> and <..> in a new directory identified by the <child_xp> argument. The parent
    608  * directory inode is defined by the <parent_xp> argument.
    609  * The two dentries are introduced in the Inode Tree. They are also introduced in the
    610  * in the child directory mapper, and the IOC device is updated.
     602error_t vfs_new_dentry_init( xptr_t   parent_xp,
     603                             xptr_t   dentry_xp,
     604                             xptr_t   child_xp );
     605
     606/******************************************************************************************
     607 * This function creates in the directory identified by the <child_xp> argument,
     608 * the two special dentries <.> and <..>. The parent directory inode is defined
     609 * by the <parent_xp> argument. The two dentries are introduced in the Inode Tree.
     610 * They are also introduced in the child directory mapper, and the IOC device is updated.
     611 * This function is called by all functions creating a brand new directory : vfs_mkdir(),
     612 * devfs_global_init(), and devfs_local_init().
    611613 ******************************************************************************************
    612614 * @ child_xp    : extended pointer on new directory inode.
     
    633635                                       uint32_t           fs_type,
    634636                                       struct process_s * process );
     637
    635638
    636639
     
    865868
    866869
    867 /******************************************************************************************
    868  *        These functions define the VFS "FS" API (to a specific File System)
     870
     871
     872/******************************************************************************************
     873 *        These functions define the VFS "FS" API to a specific File System
    869874 *****************************************************************************************/
    870875
     
    923928 * @ return 0 if success / return ENOENT if not found.
    924929 *****************************************************************************************/
    925 error_t vfs_fs_child_init( vfs_inode_t * parent,
     930error_t vfs_fs_get_dentry( vfs_inode_t * parent,
    926931                           char        * name,
    927932                           xptr_t        child_xp );
    928933
     934/******************************************************************************************
     935 * This function scan the mapper of an an existing parent inode directory, identified by
     936 * the <inode> argument and copy up to <max_dirent> valid dentries to a
     937 * local dirent array, defined by the <array> argument. The <min_dentry> argument defines
     938 * the index of the first dentry to copied to the target dirent array.
     939 * This function returns in the <entries> buffer the number of dentries actually written,
     940 * and signals in the <done> buffer when the last valid entry has been found.
     941 * If the <detailed> argument is true, a dentry/inode couple that does not exist in
     942 * the Inode Tree is dynamically created, and all dirent fiels are documented in the
     943 * dirent array. Otherwise, only the dentry name is documented.
     944 *
     945 * Depending on the file system type, it calls the relevant, FS specific function.
     946 * It must be called by a thread running in the cluster containing the parent inode.
     947 * This function does NOT take any lock.
     948 ******************************************************************************************
     949 * @ inode      : [in]  local pointer on directory inode.
     950 * @ array      : [in]  local pointer on array of dirents.
     951 * @ max_dirent : [in]  max number of slots in dirent array.
     952 * @ min_dentry : [in]  index of first dentry to be copied into array.
     953 * @ detailed   : [in]  dynamic inode creation if true.
     954 * @ entries    : [out] number of dentries actually copied into array.
     955 * @ done       : [out] Boolean true when last entry found.
     956 * @ return 0 if success / return -1 if failure.
     957 *****************************************************************************************/
     958error_t vfs_fs_get_user_dir( vfs_inode_t   * inode,
     959                             struct dirent * array,
     960                             uint32_t        max_dirent,
     961                             uint32_t        min_dentry,
     962                             bool_t          detailed,
     963                             uint32_t      * entries,
     964                             bool_t        * done );
     965 
    929966/*****************************************************************************************
    930967 * This function  updates the FS on the IOC device for a given inode identified by
Note: See TracChangeset for help on using the changeset viewer.