Ticket #1774: pr1774-imfs-mounted-paths-3.diff

File pr1774-imfs-mounted-paths-3.diff, 10.7 KB (added by Chris Johns, on May 11, 2011 at 1:43:41 AM)

Fixes the IMFS eval and also the introduced problems.

  • cpukit/libfs/src/imfs/imfs_eval.c

    RCS file: /usr1/CVS/rtems/cpukit/libfs/src/imfs/imfs_eval.c,v
    retrieving revision 1.31
    diff -p -u -u -r1.31 imfs_eval.c
    int IMFS_evaluate_link( 
    256256  return result;
    257257}
    258258
     259/*
     260 * IMFS_skip_separator
     261 *
     262 * Skip the separator in the path.
     263 */
     264static void IMFS_skip_separator (
     265   const char *path,       /* IN     */
     266   size_t     *len,        /* IN/OUT */
     267   int        *index       /* IN/OUT */
     268)
     269{
     270  while ( IMFS_is_separator( path[*index] ) && path[*index] && *len ) {
     271    ++(*index);
     272    --(*len);
     273  }
     274}
    259275
    260276/*
    261277 *  IMFS_evaluate_for_make
    int IMFS_evaluate_link( 
    267283 */
    268284
    269285int IMFS_evaluate_for_make(
    270    const char                         *path,       /* IN     */
    271    rtems_filesystem_location_info_t   *pathloc,    /* IN/OUT */
    272    const char                        **name        /* OUT    */
    273 )
     286  const char                         *path,       /* IN     */
     287  rtems_filesystem_location_info_t   *pathloc,    /* IN/OUT */
     288  const char                        **name        /* OUT    */
     289                           )
    274290{
    275   int                                 i = 0;
    276   int                                 len;
    277   IMFS_token_types                    type;
    278   char                                token[ IMFS_NAME_MAX + 1 ];
    279   rtems_filesystem_location_info_t    newloc;
    280   IMFS_jnode_t                       *node;
    281   bool                                done = false;
    282   int                                 pathlen;
    283   int                                 result;
     291  int               i = 0;
     292  int               len;
     293  IMFS_token_types  type;
     294  char              token[ IMFS_NAME_MAX + 1 ];
     295  IMFS_jnode_t     *node;
     296  bool              done = false;
     297  size_t            pathlen;
     298  int               result;
    284299
    285300  /*
    286301   * This was filled in by the caller and is valid in the
    int IMFS_evaluate_for_make( 
    312327    if ( type != IMFS_NO_MORE_PATH )
    313328      if ( node->type == IMFS_DIRECTORY )
    314329        if ( !IMFS_evaluate_permission( pathloc, RTEMS_LIBIO_PERMS_SEARCH ) )
    315            rtems_set_errno_and_return_minus_one( EACCES );
     330          rtems_set_errno_and_return_minus_one( EACCES );
    316331
    317332    node = pathloc->node_access;
    318333
    319334    switch( type ) {
    320335
    321336      case IMFS_UP_DIR:
    322        /*
    323         *  Am I at the root of all filesystems? (chroot'ed?)
    324         */
     337        /*
     338         *  Am I at the root of all filesystems? (chroot'ed?)
     339         */
    325340
    326        if ( pathloc->node_access == rtems_filesystem_root.node_access )
    327          break;       /* Throw out the .. in this case */
     341        if ( pathloc->node_access == rtems_filesystem_root.node_access )
     342          break;       /* Throw out the .. in this case */
    328343
    329344
    330         /*
    331         * Am I at the root of this mounted filesystem?
    332         */
     345        /*
     346        * Am I at the root of this mounted filesystem?
     347        */
    333348
    334349        if (pathloc->node_access == pathloc->mt_entry->mt_fs_root.node_access){
    335350
    336351          /*
    337            *  Am I at the root of all filesystems?
    338            */
     352           *  Am I at the root of all filesystems?
     353           */
    339354
    340355          if ( pathloc->node_access == rtems_filesystem_root.node_access ) {
    341356            break;
    342357
    343           } else {
    344             newloc = pathloc->mt_entry->mt_point_node;
    345             *pathloc = newloc;
     358          } else {
     359            *pathloc = pathloc->mt_entry->mt_point_node;
    346360            return (*pathloc->ops->evalformake_h)( &path[i-len], pathloc, name );
    347           }
    348         } else {
     361          }
     362        } else {
    349363
    350364          if ( !node->Parent )
    351365            rtems_set_errno_and_return_minus_one( ENOENT );
    352366
    353367          node = node->Parent;
    354         }
     368        }
    355369
    356370        pathloc->node_access = node;
    357371        break;
    358372
    359373      case IMFS_NAME:
    360374
    361         if ( node->type == IMFS_HARD_LINK ) {
     375        if ( node->type == IMFS_HARD_LINK ) {
    362376
    363377          result = IMFS_evaluate_link( pathloc, 0 );
    364378          if ( result == -1 )
    365379            return -1;
    366380
    367         } else if ( node->type == IMFS_SYM_LINK ) {
     381        } else if ( node->type == IMFS_SYM_LINK ) {
    368382
    369383          result = IMFS_evaluate_link( pathloc, 0 );
    370384
    371385          if ( result == -1 )
    372386            return -1;
    373         }
     387        }
    374388
    375389        node = pathloc->node_access;
    376390        if ( !node )
    int IMFS_evaluate_for_make( 
    378392
    379393        /*
    380394         * Only a directory can be decended into.
    381         */
     395        */
    382396
    383397        if ( node->type != IMFS_DIRECTORY )
    384398          rtems_set_errno_and_return_minus_one( ENOTDIR );
    385399
    386         /*
    387          * If we are at a node that is a mount point. Set loc to the
    388          * new fs root node and let them finish evaluating the path.
    389          */
    390 
    391         if ( node->info.directory.mt_fs != NULL ) {
    392           newloc  = node->info.directory.mt_fs->mt_fs_root;
    393           *pathloc = newloc;
    394           return (*pathloc->ops->evalformake_h)( &path[i-len], pathloc, name );
    395         }
    396 
    397         /*
    398          * Otherwise find the token name in the present location.
    399          */
     400        /*
     401         * Find the token name in the present location.
     402         */
    400403
    401404        node = IMFS_find_match_in_dir( node, token );
    402405
    403         /*
    404         * If there is no node we have found the name of the node we
     406        /*
     407        * If there is no node we have found the name of the node we
    405408         * wish to create.
    406         */
     409        */
    407410
    408411        if ( ! node )
    409412          done = true;
    410         else
     413        else {
     414        if (( node->type == IMFS_DIRECTORY ) && ( node->info.directory.mt_fs != NULL )) {
     415            IMFS_skip_separator( path, &pathlen, &i);
     416            if ((path[i] != '.') || (path[i + 1] != '.')) {
     417              *pathloc = node->info.directory.mt_fs->mt_fs_root;
     418              return (*pathloc->ops->evalformake_h)( &path[i],
     419                                                     pathloc,
     420                                                     name );
     421            }
     422            i += 2;
     423            pathlen -= 2;
     424            node = node->Parent;
     425          }
    411426          pathloc->node_access = node;
    412 
     427        }
    413428        break;
    414429
    415430      case IMFS_NO_MORE_PATH:
    int IMFS_evaluate_for_make( 
    460475  return result;
    461476}
    462477
    463 
    464478/*
    465479 *  IMFS_eval_path
    466480 *
    int IMFS_eval_path( 
    476490  rtems_filesystem_location_info_t  *pathloc       /* IN/OUT */
    477491                   )
    478492{
    479   int                                 i = 0;
    480   int                                 len;
    481   IMFS_token_types                    type = IMFS_CURRENT_DIR;
    482   char                                token[ IMFS_NAME_MAX + 1 ];
    483   rtems_filesystem_location_info_t    newloc;
    484   IMFS_jnode_t                       *node;
    485   int                                 result;
     493  int               i = 0;
     494  int               len;
     495  IMFS_token_types  type = IMFS_CURRENT_DIR;
     496  char              token[ IMFS_NAME_MAX + 1 ];
     497  IMFS_jnode_t     *node;
     498  int               result;
    486499
    487500  if ( !rtems_libio_is_valid_perms( flags ) ) {
    488501    rtems_set_errno_and_return_minus_one( EIO );
    int IMFS_eval_path( 
    541554          if ( pathloc->node_access == rtems_filesystem_root.node_access ) {
    542555            break;       /* Throw out the .. in this case */
    543556          } else {
    544             newloc = pathloc->mt_entry->mt_point_node;
    545             *pathloc = newloc;
     557            *pathloc = pathloc->mt_entry->mt_point_node;
    546558            return (*pathloc->ops->evalpath_h)(&(pathname[i-len]),
    547559                                               pathnamelen+len,
    548560                                               flags,pathloc);
    int IMFS_eval_path( 
    569581          node = pathloc->node_access;
    570582       
    571583          /*
    572            * It would be a design error if we evaluated the link and
    573            * was broken.
    574            */
     584           * It would be a design error if we evaluated the link and
     585           * was broken.
     586           */
    575587          IMFS_assert( node );
    576588
    577589        } else if ( node->type == IMFS_SYM_LINK ) {
    int IMFS_eval_path( 
    593605          rtems_set_errno_and_return_minus_one( ENOTDIR );
    594606
    595607        /*
    596          *  If we are at a node that is a mount point. Set loc to the
    597          *  new fs root node and let them finish evaluating the path.
    598          */
    599         if ( node->info.directory.mt_fs != NULL ) {
    600           newloc   = node->info.directory.mt_fs->mt_fs_root;
    601           *pathloc = newloc;
    602           return (*pathloc->ops->evalpath_h)( &pathname[i-len],
    603                                               pathnamelen+len,
    604                                               flags, pathloc );
    605         }
    606 
    607         /*
    608          *  Otherwise find the token name in the present location.
     608         *  Find the token name in the current node.
    609609         */
    610610        node = IMFS_find_match_in_dir( node, token );
    611611        if ( !node )
    612612          rtems_set_errno_and_return_minus_one( ENOENT );
    613613
    614614        /*
    615          *  Set the node access to the point we have found.
     615         *  If we are at a node that is a mount point so current directory
     616         *  actually exists on the mounted file system and not in the node that
     617         *  contains the mount point node. For example a stat of the mount
     618         *  point should return the details of the root of the mounted file
     619         *  system not the mount point node of parent file system.
     620         *
     621         *  If the node we have just moved to is a mount point do not loop and
     622         *  get the token because the token may be suitable for the mounted
     623         *  file system and not the IMFS. For example the IMFS length is
     624         *  limited. If the token is a parent directory move back up otherwise
     625         *  set loc to the new fs root node and let them finish evaluating the
     626         *  path.
    616627         */
     628        if (( node->type == IMFS_DIRECTORY ) && ( node->info.directory.mt_fs != NULL )) {
     629          IMFS_skip_separator( pathname, &pathnamelen, &i);
     630          if ((pathname[i] != '.') || (pathname[i + 1] != '.')) {
     631            *pathloc = node->info.directory.mt_fs->mt_fs_root;
     632            return (*pathloc->ops->evalpath_h)( &pathname[i],
     633                                                pathnamelen,
     634                                                flags, pathloc );
     635          }
     636          i += 2;
     637          pathnamelen -= 2;
     638          node = node->Parent;
     639        }
    617640
     641        /*
     642         *  Set the node access to the point we have found.
     643         */
    618644        pathloc->node_access = node;
    619645        break;
    620646
    int IMFS_eval_path( 
    640666
    641667  if ( node->type == IMFS_DIRECTORY ) {
    642668    if ( node->info.directory.mt_fs != NULL ) {
    643       newloc   = node->info.directory.mt_fs->mt_fs_root;
    644       *pathloc = newloc;
     669      *pathloc = node->info.directory.mt_fs->mt_fs_root;
    645670      return (*pathloc->ops->evalpath_h)( &pathname[i-len],
    646671                                          pathnamelen+len,
    647672                                          flags, pathloc );