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.

File:
1 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
Note: See TracChangeset for help on using the changeset viewer.