diff options
Diffstat (limited to 'cpukit/libfs/src/imfs')
35 files changed, 635 insertions, 1610 deletions
diff --git a/cpukit/libfs/src/imfs/deviceio.c b/cpukit/libfs/src/imfs/deviceio.c index bb66703be9..69f409e472 100644 --- a/cpukit/libfs/src/imfs/deviceio.c +++ b/cpukit/libfs/src/imfs/deviceio.c @@ -15,15 +15,13 @@ */ #if HAVE_CONFIG_H -#include "config.h" + #include "config.h" #endif -#include <rtems.h> -#include <rtems/libio.h> -#include <rtems/devfs.h> - #include "imfs.h" +#include <rtems/devfs.h> + /* * device_open * @@ -33,8 +31,8 @@ int device_open( rtems_libio_t *iop, const char *pathname, - uint32_t flag, - uint32_t mode + int oflag, + mode_t mode ) { rtems_libio_open_close_args_t args; diff --git a/cpukit/libfs/src/imfs/fifoimfs_init.c b/cpukit/libfs/src/imfs/fifoimfs_init.c index 13dc373eec..d2af7af8e5 100644 --- a/cpukit/libfs/src/imfs/fifoimfs_init.c +++ b/cpukit/libfs/src/imfs/fifoimfs_init.c @@ -20,26 +20,29 @@ */ #if HAVE_CONFIG_H -#include "config.h" + #include "config.h" #endif #include "imfs.h" const rtems_filesystem_operations_table fifoIMFS_ops = { - .evalpath_h = IMFS_eval_path, - .evalformake_h = IMFS_evaluate_for_make, + .lock_h = rtems_filesystem_default_lock, + .unlock_h = rtems_filesystem_default_unlock, + .eval_path_h = IMFS_eval_path, .link_h = IMFS_link, - .unlink_h = IMFS_unlink, + .are_nodes_equal_h = rtems_filesystem_default_are_nodes_equal, .node_type_h = IMFS_node_type, .mknod_h = IMFS_mknod, + .rmnod_h = IMFS_rmnod, + .fchmod_h = IMFS_fchmod, .chown_h = IMFS_chown, + .clonenod_h = rtems_filesystem_default_clonenode, .freenod_h = rtems_filesystem_default_freenode, .mount_h = IMFS_mount, .fsmount_me_h = fifoIMFS_initialize, .unmount_h = IMFS_unmount, .fsunmount_me_h = IMFS_fsunmount, .utime_h = IMFS_utime, - .eval_link_h = IMFS_evaluate_link, .symlink_h = IMFS_symlink, .readlink_h = IMFS_readlink, .rename_h = IMFS_rename, @@ -54,8 +57,7 @@ int fifoIMFS_initialize( return IMFS_initialize_support( mt_entry, &fifoIMFS_ops, - &IMFS_memfile_handlers, - &IMFS_directory_handlers, + &IMFS_link_handlers, &IMFS_fifo_handlers ); } diff --git a/cpukit/libfs/src/imfs/imfs.h b/cpukit/libfs/src/imfs/imfs.h index b412c2a1fe..2a851acae4 100644 --- a/cpukit/libfs/src/imfs/imfs.h +++ b/cpukit/libfs/src/imfs/imfs.h @@ -18,13 +18,9 @@ #ifndef _RTEMS_IMFS_H #define _RTEMS_IMFS_H -#include <rtems.h> -#include <rtems/chain.h> - -#include <sys/types.h> #include <limits.h> -#include <rtems/libio.h> +#include <rtems/libio_.h> #include <rtems/pipe.h> #ifdef __cplusplus @@ -32,15 +28,6 @@ extern "C" { #endif /* - * File name macros - */ - -#define IMFS_is_valid_name_char( _ch ) ( 1 ) - -#define IMFS_is_separator( _ch ) \ - rtems_filesystem_is_separator( _ch ) - -/* * Data types */ @@ -226,22 +213,11 @@ typedef struct { ino_t ino_count; const rtems_filesystem_file_handlers_r *memfile_handlers; const rtems_filesystem_file_handlers_r *directory_handlers; + const rtems_filesystem_file_handlers_r *link_handlers; const rtems_filesystem_file_handlers_r *fifo_handlers; } IMFS_fs_info_t; /* - * Type defination for tokens returned from IMFS_get_token - */ - -typedef enum { - IMFS_NO_MORE_PATH, - IMFS_CURRENT_DIR, - IMFS_UP_DIR, - IMFS_NAME, - IMFS_INVALID_TOKEN -} IMFS_token_types; - -/* * Shared Data */ @@ -276,29 +252,18 @@ extern int miniIMFS_initialize( extern int IMFS_initialize_support( rtems_filesystem_mount_table_entry_t *mt_entry, const rtems_filesystem_operations_table *op_table, - const rtems_filesystem_file_handlers_r *memfile_handlers, - const rtems_filesystem_file_handlers_r *directory_handlers, + const rtems_filesystem_file_handlers_r *link_handlers, const rtems_filesystem_file_handlers_r *fifo_handlers ); -extern int IMFS_fsunmount( +extern void IMFS_fsunmount( rtems_filesystem_mount_table_entry_t *mt_entry ); extern int rtems_tarfs_load( - char *mountpoint, - uint8_t *tar_image, - size_t tar_size -); - -/* - * Returns the number of characters copied from path to token. - */ -extern IMFS_token_types IMFS_get_token( - const char *path, - int pathlen, - char *token, - int *token_len + const char *mountpoint, + uint8_t *tar_image, + size_t tar_size ); extern void IMFS_dump( void ); @@ -309,88 +274,59 @@ extern void IMFS_dump( void ); */ extern int IMFS_memfile_maximum_size( void ); -extern void IMFS_initialize_jnode( - IMFS_jnode_t *the_jnode, - IMFS_jnode_types_t type, - IMFS_jnode_t *the_parent, - char *name, - mode_t mode -); - -extern IMFS_jnode_t *IMFS_find_match_in_dir( - IMFS_jnode_t *directory, /* IN */ - char *name /* IN */ -); extern rtems_filesystem_node_types_t IMFS_node_type( - rtems_filesystem_location_info_t *pathloc /* IN */ + const rtems_filesystem_location_info_t *loc ); extern int IMFS_stat( - rtems_filesystem_location_info_t *loc, /* IN */ - struct stat *buf /* OUT */ -); - -extern int IMFS_Set_handlers( - rtems_filesystem_location_info_t *loc + const rtems_filesystem_location_info_t *loc, + struct stat *buf ); -extern int IMFS_evaluate_link( - rtems_filesystem_location_info_t *node, /* IN/OUT */ - int flags /* IN */ -); +extern void IMFS_Set_handlers( rtems_filesystem_location_info_t *loc ); -extern int IMFS_eval_path( - const char *pathname, /* IN */ - size_t pathnamelen, /* IN */ - int flags, /* IN */ - rtems_filesystem_location_info_t *pathloc /* IN/OUT */ +extern void IMFS_eval_path( + rtems_filesystem_eval_path_context_t *ctx ); extern int IMFS_link( - rtems_filesystem_location_info_t *to_loc, /* IN */ - rtems_filesystem_location_info_t *parent_loc, /* IN */ - const char *token /* IN */ -); - -extern int IMFS_unlink( - rtems_filesystem_location_info_t *parent_pathloc, /* IN */ - rtems_filesystem_location_info_t *pathloc /* IN */ + const rtems_filesystem_location_info_t *parentloc, + const rtems_filesystem_location_info_t *targetloc, + const char *name, + size_t namelen ); extern int IMFS_chown( - rtems_filesystem_location_info_t *pathloc, /* IN */ - uid_t owner, /* IN */ - gid_t group /* IN */ + const rtems_filesystem_location_info_t *loc, + uid_t owner, + gid_t group ); extern int IMFS_mknod( - const char *path, /* IN */ - mode_t mode, /* IN */ - dev_t dev, /* IN */ - rtems_filesystem_location_info_t *pathloc /* IN/OUT */ + const rtems_filesystem_location_info_t *parentloc, + const char *name, + size_t namelen, + mode_t mode, + dev_t dev ); extern IMFS_jnode_t *IMFS_allocate_node( IMFS_jnode_types_t type, /* IN */ const char *name, /* IN */ + size_t namelen, /* IN */ mode_t mode /* IN */ ); extern IMFS_jnode_t *IMFS_create_root_node(void); extern IMFS_jnode_t *IMFS_create_node( - rtems_filesystem_location_info_t *parent_loc, /* IN */ - IMFS_jnode_types_t type, /* IN */ - const char *name, /* IN */ - mode_t mode, /* IN */ - const IMFS_types_union *info /* IN */ -); - -extern int IMFS_evaluate_for_make( - const char *path, /* IN */ - rtems_filesystem_location_info_t *pathloc, /* IN/OUT */ - const char **name /* OUT */ + const rtems_filesystem_location_info_t *pathloc, /* IN */ + IMFS_jnode_types_t type, /* IN */ + const char *name, /* IN */ + size_t namelen, /* IN */ + mode_t mode, /* IN */ + const IMFS_types_union *info /* IN */ ); extern int IMFS_mount( @@ -413,8 +349,8 @@ extern int memfile_ftruncate( extern int imfs_dir_open( rtems_libio_t *iop, /* IN */ const char *pathname, /* IN */ - uint32_t flag, /* IN */ - uint32_t mode /* IN */ + int oflag, /* IN */ + mode_t mode /* IN */ ); extern int imfs_dir_close( @@ -433,21 +369,11 @@ extern off_t imfs_dir_lseek( int whence /* IN */ ); -extern int imfs_dir_fstat( - rtems_filesystem_location_info_t *loc, /* IN */ - struct stat *buf /* OUT */ -); - -extern int imfs_dir_rmnod( - rtems_filesystem_location_info_t *parent_pathloc, /* IN */ - rtems_filesystem_location_info_t *pathloc /* IN */ -); - extern int memfile_open( rtems_libio_t *iop, /* IN */ const char *pathname, /* IN */ - uint32_t flag, /* IN */ - uint32_t mode /* IN */ + int oflag, /* IN */ + mode_t mode /* IN */ ); extern int memfile_close( @@ -481,8 +407,8 @@ extern off_t memfile_lseek( extern int device_open( rtems_libio_t *iop, /* IN */ const char *pathname, /* IN */ - uint32_t flag, /* IN */ - uint32_t mode /* IN */ + int oflag, /* IN */ + mode_t mode /* IN */ ); extern int device_close( @@ -519,33 +445,35 @@ extern int device_ftruncate( ); extern int IMFS_utime( - rtems_filesystem_location_info_t *pathloc, /* IN */ - time_t actime, /* IN */ - time_t modtime /* IN */ + const rtems_filesystem_location_info_t *loc, + time_t actime, + time_t modtime ); extern int IMFS_fchmod( - rtems_filesystem_location_info_t *loc, - mode_t mode + const rtems_filesystem_location_info_t *loc, + mode_t mode ); extern int IMFS_symlink( - rtems_filesystem_location_info_t *parent_loc, /* IN */ - const char *link_name, - const char *node_name + const rtems_filesystem_location_info_t *parentloc, + const char *name, + size_t namelen, + const char *target ); extern ssize_t IMFS_readlink( - rtems_filesystem_location_info_t *loc, /* IN */ - char *buf, /* OUT */ - size_t bufsize + const rtems_filesystem_location_info_t *loc, + char *buf, + size_t bufsize ); extern int IMFS_rename( - rtems_filesystem_location_info_t *old_loc, /* IN */ - rtems_filesystem_location_info_t *old_parent_loc, /* IN */ - rtems_filesystem_location_info_t *new_parent_loc, /* IN */ - const char *new_name /* IN */ + const rtems_filesystem_location_info_t *oldparentloc, + const rtems_filesystem_location_info_t *oldloc, + const rtems_filesystem_location_info_t *newparentloc, + const char *name, + size_t namelen ); extern int IMFS_fdatasync( @@ -561,8 +489,8 @@ extern void IMFS_check_node_remove( ); extern int IMFS_rmnod( - rtems_filesystem_location_info_t *parent_pathloc, /* IN */ - rtems_filesystem_location_info_t *pathloc /* IN */ + const rtems_filesystem_location_info_t *parentloc, + const rtems_filesystem_location_info_t *loc ); /* diff --git a/cpukit/libfs/src/imfs/imfs_chown.c b/cpukit/libfs/src/imfs/imfs_chown.c index 7f0c7b5688..e31b89e0b0 100644 --- a/cpukit/libfs/src/imfs/imfs_chown.c +++ b/cpukit/libfs/src/imfs/imfs_chown.c @@ -15,18 +15,19 @@ */ #if HAVE_CONFIG_H -#include "config.h" + #include "config.h" #endif -#include <errno.h> -#include <rtems/libio_.h> -#include <rtems/seterr.h> #include "imfs.h" +#include <unistd.h> + +#include <rtems/libio_.h> + int IMFS_chown( - rtems_filesystem_location_info_t *pathloc, /* IN */ - uid_t owner, /* IN */ - gid_t group /* IN */ + const rtems_filesystem_location_info_t *loc, + uid_t owner, + gid_t group ) { IMFS_jnode_t *jnode; @@ -34,7 +35,7 @@ int IMFS_chown( uid_t st_uid; #endif - jnode = (IMFS_jnode_t *) pathloc->node_access; + jnode = (IMFS_jnode_t *) loc->node_access; /* * Verify I am the owner of the node or the super user. diff --git a/cpukit/libfs/src/imfs/imfs_creat.c b/cpukit/libfs/src/imfs/imfs_creat.c index 3b602d0c14..37e3ac0578 100644 --- a/cpukit/libfs/src/imfs/imfs_creat.c +++ b/cpukit/libfs/src/imfs/imfs_creat.c @@ -14,35 +14,32 @@ */ #if HAVE_CONFIG_H -#include "config.h" + #include "config.h" #endif +#include "imfs.h" + #include <stdlib.h> #include <string.h> -#include "imfs.h" -#include <rtems/libio_.h> /* * Create an IMFS filesystem node of an arbitrary type that is NOT * the root directory node. */ IMFS_jnode_t *IMFS_create_node( - rtems_filesystem_location_info_t *parent_loc, - IMFS_jnode_types_t type, - const char *name, - mode_t mode, - const IMFS_types_union *info + const rtems_filesystem_location_info_t *parent_loc, + IMFS_jnode_types_t type, + const char *name, + size_t namelen, + mode_t mode, + const IMFS_types_union *info ) { IMFS_jnode_t *node; IMFS_jnode_t *parent; IMFS_fs_info_t *fs_info; - /* - * MUST have a parent node to call this routine. - */ - if ( parent_loc == NULL ) - return NULL; + IMFS_assert( parent_loc != NULL ); parent = parent_loc->node_access; fs_info = parent_loc->mt_entry->fs_info; @@ -51,13 +48,16 @@ IMFS_jnode_t *IMFS_create_node( * Reject creation of FIFOs if support is disabled. */ if ( type == IMFS_FIFO && - fs_info->fifo_handlers == &rtems_filesystem_handlers_default ) + fs_info->fifo_handlers == &rtems_filesystem_handlers_default ) { + errno = ENOTSUP; + return NULL; + } /* * Allocate filesystem node and fill in basic information */ - node = IMFS_allocate_node( type, name, mode & ~rtems_filesystem_umask ); + node = IMFS_allocate_node( type, name, namelen, mode ); if ( !node ) return NULL; @@ -104,25 +104,36 @@ IMFS_jnode_t *IMFS_create_node( IMFS_jnode_t *IMFS_allocate_node( IMFS_jnode_types_t type, const char *name, + size_t namelen, mode_t mode ) { IMFS_jnode_t *node; struct timeval tv; + if ( namelen > IMFS_NAME_MAX ) { + errno = ENAMETOOLONG; + + return NULL; + } + /* * Allocate an IMFS jnode */ node = calloc( 1, sizeof( IMFS_jnode_t ) ); - if ( !node ) + if ( !node ) { + errno = ENOMEM; + return NULL; + } /* * Fill in the basic information */ node->st_nlink = 1; node->type = type; - strncpy( node->name, name, IMFS_NAME_MAX ); + memcpy( node->name, name, namelen ); + node->name [namelen] = '\0'; /* * Fill in the mode and permission information for the jnode structure. @@ -155,7 +166,7 @@ IMFS_jnode_t *IMFS_create_root_node(void) /* * Allocate filesystem node and fill in basic information */ - node = IMFS_allocate_node( IMFS_DIRECTORY, "", (S_IFDIR | 0755) ); + node = IMFS_allocate_node( IMFS_DIRECTORY, "", 0, (S_IFDIR | 0755) ); if ( !node ) return NULL; diff --git a/cpukit/libfs/src/imfs/imfs_debug.c b/cpukit/libfs/src/imfs/imfs_debug.c index f8bdf1ce41..091237275d 100644 --- a/cpukit/libfs/src/imfs/imfs_debug.c +++ b/cpukit/libfs/src/imfs/imfs_debug.c @@ -12,21 +12,14 @@ */ #if HAVE_CONFIG_H -#include "config.h" + #include "config.h" #endif -#include <string.h> -#include <fcntl.h> -#include <errno.h> -#include <stdlib.h> -#include <unistd.h> /* for close */ -#include <inttypes.h> +#include "imfs.h" +#include <inttypes.h> +#include <unistd.h> #include <stdio.h> -#include <sys/stat.h> - -#include "imfs.h" -#include <rtems/libio_.h> /* * IMFS_print_jnode @@ -142,7 +135,7 @@ void IMFS_dump( void ) { fprintf(stdout, "*************** Dump of Entire IMFS ***************\n" ); fprintf(stdout, "/\n" ); - IMFS_dump_directory( rtems_filesystem_root.node_access, 0 ); + IMFS_dump_directory( rtems_filesystem_root->location.node_access, 0 ); fprintf(stdout, "*************** End of Dump ***************\n" ); } diff --git a/cpukit/libfs/src/imfs/imfs_directory.c b/cpukit/libfs/src/imfs/imfs_directory.c index 7e0c125104..8ef05b4d1d 100644 --- a/cpukit/libfs/src/imfs/imfs_directory.c +++ b/cpukit/libfs/src/imfs/imfs_directory.c @@ -12,23 +12,14 @@ */ #if HAVE_CONFIG_H -#include "config.h" + #include "config.h" #endif -#include <sys/types.h> -#include <sys/stat.h> -#include <rtems/chain.h> -#include <fcntl.h> -#include <errno.h> -#include <stdlib.h> -#include <stdio.h> +#include "imfs.h" + #include <string.h> #include <dirent.h> -#include "imfs.h" -#include <rtems/libio_.h> -#include <rtems/seterr.h> - /* * imfs_dir_open * @@ -40,8 +31,8 @@ int imfs_dir_open( rtems_libio_t *iop, const char *pathname, - uint32_t flag, - uint32_t mode + int oflag, + mode_t mode ) { IMFS_jnode_t *the_jnode; @@ -203,115 +194,3 @@ off_t imfs_dir_lseek( return 0; } - - - -/* - * imfs_dir_fstat - * - * This routine will obtain the following information concerning the current - * directory: - * st_dev 0ll - * st_ino 1 - * st_mode mode extracted from the jnode - * st_nlink number of links to this node - * st_uid uid extracted from the jnode - * st_gid gid extracted from the jnode - * st_rdev 0ll - * st_size the number of bytes in the directory - * This is calculated by taking the number of entries - * in the directory and multiplying by the size of a - * dirent structure - * st_blksize 0 - * st_blocks 0 - * stat_atime time of last access - * stat_mtime time of last modification - * stat_ctime time of the last change - * - * This information will be returned to the calling function in a -stat- struct - * - */ - -int imfs_dir_fstat( - rtems_filesystem_location_info_t *loc, - struct stat *buf -) -{ - rtems_chain_node *the_node; - rtems_chain_control *the_chain; - IMFS_jnode_t *the_jnode; - - - the_jnode = (IMFS_jnode_t *) loc->node_access; - - buf->st_dev = 0ll; - buf->st_ino = the_jnode->st_ino; - buf->st_mode = the_jnode->st_mode; - buf->st_nlink = the_jnode->st_nlink; - buf->st_uid = the_jnode->st_uid; - buf->st_gid = the_jnode->st_gid; - buf->st_rdev = 0ll; - buf->st_blksize = 0; - buf->st_blocks = 0; - buf->st_atime = the_jnode->stat_atime; - buf->st_mtime = the_jnode->stat_mtime; - buf->st_ctime = the_jnode->stat_ctime; - - buf->st_size = 0; - - the_chain = &the_jnode->info.directory.Entries; - - /* Run through the chain and count the number of directory entries */ - /* that are subordinate to this directory node */ - for ( the_node = rtems_chain_first( the_chain ); - !rtems_chain_is_tail( the_chain, the_node ) ; - the_node = the_node->next ) { - - buf->st_size = buf->st_size + sizeof( struct dirent ); - } - - return 0; -} - -/* - * IMFS_dir_rmnod - * - * This routine is available from the optable to remove a node - * from the IMFS file system. - */ - -int imfs_dir_rmnod( - rtems_filesystem_location_info_t *parent_pathloc, /* IN */ - rtems_filesystem_location_info_t *pathloc /* IN */ -) -{ - IMFS_jnode_t *the_jnode; - - the_jnode = (IMFS_jnode_t *) pathloc->node_access; - - /* - * You cannot remove a node that still has children - */ - - if ( ! rtems_chain_is_empty( &the_jnode->info.directory.Entries ) ) - rtems_set_errno_and_return_minus_one( ENOTEMPTY ); - - /* - * You cannot remove the file system root node. - */ - - if ( rtems_filesystem_is_root_location(pathloc) ) - rtems_set_errno_and_return_minus_one( EBUSY ); - - /* - * You cannot remove a mountpoint. - */ - - if ( the_jnode->info.directory.mt_fs != NULL ) - rtems_set_errno_and_return_minus_one( EBUSY ); - - IMFS_create_orphan( the_jnode ); - IMFS_check_node_remove( the_jnode ); - - return 0; -} diff --git a/cpukit/libfs/src/imfs/imfs_eval.c b/cpukit/libfs/src/imfs/imfs_eval.c index 78fafca536..43f2ee40e0 100644 --- a/cpukit/libfs/src/imfs/imfs_eval.c +++ b/cpukit/libfs/src/imfs/imfs_eval.c @@ -4,684 +4,189 @@ * COPYRIGHT (c) 1989-1999. * On-Line Applications Research Corporation (OAR). * + * Modifications to support reference counting in the file system are + * Copyright (c) 2012 embedded brains GmbH. + * * The license and distribution terms for this file may be * found in the file LICENSE in this distribution or at * http://www.rtems.com/license/LICENSE. - * - * $Id$ */ #if HAVE_CONFIG_H -#include "config.h" + #include "config.h" #endif -#include <sys/types.h> -#include <sys/stat.h> -#include <fcntl.h> -#include <unistd.h> -#include <errno.h> -#include <stdlib.h> - #include "imfs.h" -#include <rtems/libio_.h> -#include <rtems/seterr.h> -#define RTEMS_LIBIO_PERMS_RX (RTEMS_LIBIO_PERMS_SEARCH | RTEMS_LIBIO_PERMS_READ) -#define RTEMS_LIBIO_PERMS_WX (RTEMS_LIBIO_PERMS_SEARCH | RTEMS_LIBIO_PERMS_WRITE) - -#define MAXSYMLINK 5 - -int IMFS_Set_handlers( - rtems_filesystem_location_info_t *loc -) +void IMFS_Set_handlers( rtems_filesystem_location_info_t *loc ) { - IMFS_jnode_t *node = loc->node_access; - IMFS_fs_info_t *fs_info; + IMFS_jnode_t *node = loc->node_access; + IMFS_fs_info_t *fs_info = loc->mt_entry->fs_info; + const rtems_filesystem_file_handlers_r *handlers; - fs_info = loc->mt_entry->fs_info; - switch( node->type ) { + switch ( node->type ) { case IMFS_DIRECTORY: - loc->handlers = fs_info->directory_handlers; + handlers = &IMFS_directory_handlers; break; case IMFS_DEVICE: - loc->handlers = &IMFS_device_handlers; + handlers = &IMFS_device_handlers; break; - case IMFS_SYM_LINK: case IMFS_HARD_LINK: - loc->handlers = &IMFS_link_handlers; - break; - case IMFS_LINEAR_FILE: - loc->handlers = fs_info->memfile_handlers; + case IMFS_SYM_LINK: + handlers = fs_info->link_handlers; break; case IMFS_MEMORY_FILE: - loc->handlers = fs_info->memfile_handlers; + case IMFS_LINEAR_FILE: + handlers = &IMFS_memfile_handlers; break; case IMFS_FIFO: - loc->handlers = fs_info->fifo_handlers; + handlers = fs_info->fifo_handlers; + break; + default: + IMFS_assert( 0 ); break; } - return 0; -} - -/* - * IMFS_evaluate_permission - * - * The following routine evaluates that we have permission - * to do flags on the node. - */ -static int IMFS_evaluate_permission( - rtems_filesystem_location_info_t *node, - int flags -) -{ - uid_t st_uid; - gid_t st_gid; - IMFS_jnode_t *jnode; - int flags_to_test; - - if ( !rtems_libio_is_valid_perms( flags ) ) - rtems_set_errno_and_return_minus_one( EPERM ); - - jnode = node->node_access; - -#if defined(RTEMS_POSIX_API) - st_uid = geteuid(); - st_gid = getegid(); -#else - st_uid = jnode->st_uid; - st_gid = jnode->st_gid; -#endif - - /* - * Check if I am owner or a group member or someone else. - */ - - flags_to_test = flags; - - if ( st_uid == jnode->st_uid ) - flags_to_test <<= 6; - else if ( st_gid == jnode->st_gid ) - flags_to_test <<= 3; - else { - /* must be other - do nothing */; - } - - /* - * If all of the flags are set we have permission - * to do this. - */ - if ( ( flags_to_test & jnode->st_mode) == flags_to_test ) - return 1; - - return 0; + loc->handlers = handlers; } -/* - * IMFS_evaluate_hard_link - * - * The following routine evaluates a hardlink to the actual node. - */ - -static int IMFS_evaluate_hard_link( - rtems_filesystem_location_info_t *node, /* IN/OUT */ - int flags /* IN */ +static bool IMFS_is_directory( + rtems_filesystem_eval_path_context_t *ctx, + void *arg ) { - IMFS_jnode_t *jnode = node->node_access; - int result = 0; + rtems_filesystem_location_info_t *currentloc = + rtems_filesystem_eval_path_get_currentloc( ctx ); + IMFS_jnode_t *node = currentloc->node_access; - /* - * Check for things that should never happen. - */ - IMFS_assert( jnode->type == IMFS_HARD_LINK ); - - /* - * Set the hard link value and the handlers. - */ - node->node_access = jnode->info.hard_link.link_node; - - IMFS_Set_handlers( node ); - - /* - * Verify we have the correct permissions for this node. - */ - - if ( !IMFS_evaluate_permission( node, flags ) ) - rtems_set_errno_and_return_minus_one( EACCES ); - - return result; + return node->type == IMFS_DIRECTORY; } - -/* - * IMFS_evaluate_sym_link - * - * The following routine evaluates a symbolic link to the actual node. - */ - -static int IMFS_evaluate_sym_link( - rtems_filesystem_location_info_t *node, /* IN/OUT */ - int flags /* IN */ +static IMFS_jnode_t *IMFS_search_in_directory( + IMFS_jnode_t *dir, + const char *token, + size_t tokenlen ) { - IMFS_jnode_t *jnode = node->node_access; - int result = 0; - int i; - - /* - * Check for things that should never happen. - */ - IMFS_assert( jnode->type == IMFS_SYM_LINK ); - IMFS_assert( jnode->Parent ); - - /* - * Move the node_access to either the symbolic links parent or - * root depending on the symbolic links path. - */ - node->node_access = jnode->Parent; - - rtems_filesystem_get_sym_start_loc( - jnode->info.sym_link.name, - &i, - node - ); - - /* - * Use eval path to evaluate the path of the symbolic link. - */ - result = IMFS_eval_path( - &jnode->info.sym_link.name[i], - strlen( &jnode->info.sym_link.name[i] ), - flags, - node - ); - - IMFS_Set_handlers( node ); - - /* - * Verify we have the correct permissions for this node. - */ - if ( !IMFS_evaluate_permission( node, flags ) ) - rtems_set_errno_and_return_minus_one( EACCES ); - - return result; -} + if ( rtems_filesystem_is_current_directory( token, tokenlen ) ) { + return dir; + } else { + if ( rtems_filesystem_is_parent_directory( token, tokenlen ) ) { + return dir->Parent; + } else { + rtems_chain_control *entries = &dir->info.directory.Entries; + rtems_chain_node *current = rtems_chain_first( entries ); + rtems_chain_node *tail = rtems_chain_tail( entries ); -/* - * IMFS_evaluate_link - * - * The following routine returns the real node pointed to by a link. - */ -int IMFS_evaluate_link( - rtems_filesystem_location_info_t *node, /* IN/OUT */ - int flags /* IN */ -) -{ - IMFS_jnode_t *jnode; - int result = 0; + while ( current != tail ) { + IMFS_jnode_t *entry = (IMFS_jnode_t *) current; + bool match = strncmp( entry->name, token, tokenlen ) == 0 + && entry->name [tokenlen] == '\0'; - do { - jnode = node->node_access; + if ( match ) { + return entry; + } - /* - * Increment and check the link counter. - */ + current = rtems_chain_next( current ); + } - rtems_filesystem_link_counts ++; - if ( rtems_filesystem_link_counts > MAXSYMLINK ) { - rtems_filesystem_link_counts = 0; - rtems_set_errno_and_return_minus_one( ELOOP ); + return NULL; } - - /* - * Follow the Link node. - */ - - if ( jnode->type == IMFS_HARD_LINK ) - result = IMFS_evaluate_hard_link( node, flags ); - - else if (jnode->type == IMFS_SYM_LINK ) - result = IMFS_evaluate_sym_link( node, flags ); - - } while ( ( result == 0 ) && ( ( jnode->type == IMFS_SYM_LINK ) || - ( jnode->type == IMFS_HARD_LINK ) ) ); - - /* - * Clear link counter. - */ - - rtems_filesystem_link_counts = 0; - - return result; -} - -/* - * IMFS_skip_separator - * - * Skip the separator in the path. - */ -static void IMFS_skip_separator ( - const char *path, /* IN */ - size_t *len, /* IN/OUT */ - int *index /* IN/OUT */ -) -{ - while ( IMFS_is_separator( path[*index] ) && path[*index] && *len ) { - ++(*index); - --(*len); } } -/* - * IMFS_evaluate_for_make - * - * The following routine evaluate path for a new node to be created. - * pathloc is returned with a pointer to the parent of the new node. - * name is returned with a pointer to the first character in the - * new node name. The parent node is verified to be a directory. - */ - -int IMFS_evaluate_for_make( - const char *path, /* IN */ - rtems_filesystem_location_info_t *pathloc, /* IN/OUT */ - const char **name /* OUT */ - ) +static rtems_filesystem_global_location_t **IMFS_is_mount_point( + IMFS_jnode_t *node +) { - int i = 0; - int len; - IMFS_token_types type; - char token[ IMFS_NAME_MAX + 1 ]; - IMFS_jnode_t *node; - bool done = false; - size_t pathlen; - int result; - - /* - * This was filled in by the caller and is valid in the - * mount table. - */ - node = pathloc->node_access; - - /* - * Get the path length. - */ - pathlen = strlen( path ); - /* - * Evaluate all tokens until we are done or an error occurs. - */ - - while( !done ) { - - type = IMFS_get_token( &path[i], pathlen, token, &len ); - pathlen -= len; - i += len; - - if ( !pathloc->node_access ) - rtems_set_errno_and_return_minus_one( ENOENT ); - - /* - * I cannot move out of this directory without execute permission. - */ + rtems_filesystem_global_location_t **fs_root_ptr = NULL; - if ( type != IMFS_NO_MORE_PATH ) - if ( node->type == IMFS_DIRECTORY ) - if ( !IMFS_evaluate_permission( pathloc, RTEMS_LIBIO_PERMS_SEARCH ) ) - rtems_set_errno_and_return_minus_one( EACCES ); - - node = pathloc->node_access; - - switch( type ) { - - case IMFS_UP_DIR: - /* - * Am I at the root of all filesystems? (chroot'ed?) - */ - - if ( pathloc->node_access == rtems_filesystem_root.node_access ) - break; /* Throw out the .. in this case */ - - - /* - * Am I at the root of this mounted filesystem? - */ - - if ( rtems_filesystem_is_root_location( pathloc ) ) { - - /* - * Am I at the root of all filesystems? - */ - - if ( pathloc->node_access == rtems_filesystem_root.node_access ) { - break; - - } else { - *pathloc = pathloc->mt_entry->mt_point_node; - return (*pathloc->ops->evalformake_h)( &path[i-len], pathloc, name ); - } - } else { - - if ( !node->Parent ) - rtems_set_errno_and_return_minus_one( ENOENT ); - - node = node->Parent; - } - - pathloc->node_access = node; - break; - - case IMFS_NAME: - - if ( node->type == IMFS_HARD_LINK ) { - - result = IMFS_evaluate_link( pathloc, 0 ); - if ( result == -1 ) - return -1; - - } else if ( node->type == IMFS_SYM_LINK ) { - - result = IMFS_evaluate_link( pathloc, 0 ); - - if ( result == -1 ) - return -1; - } - - node = pathloc->node_access; - if ( !node ) - rtems_set_errno_and_return_minus_one( ENOTDIR ); - - /* - * Only a directory can be decended into. - */ - - if ( node->type != IMFS_DIRECTORY ) - rtems_set_errno_and_return_minus_one( ENOTDIR ); - - /* - * Find the token name in the present location. - */ - - node = IMFS_find_match_in_dir( node, token ); - - /* - * If there is no node we have found the name of the node we - * wish to create. - */ - - if ( ! node ) - done = true; - else { - if (( node->type == IMFS_DIRECTORY ) && ( node->info.directory.mt_fs != NULL )) { - IMFS_skip_separator( path, &pathlen, &i); - if ((path[i] != '.') || (path[i + 1] != '.')) { - *pathloc = node->info.directory.mt_fs->mt_fs_root; - return (*pathloc->ops->evalformake_h)( &path[i], - pathloc, - name ); - } - i += 2; - pathlen -= 2; - node = node->Parent; - } - pathloc->node_access = node; - } - break; - - case IMFS_NO_MORE_PATH: - rtems_set_errno_and_return_minus_one( EEXIST ); - break; - - case IMFS_INVALID_TOKEN: - rtems_set_errno_and_return_minus_one( ENAMETOOLONG ); - break; - - case IMFS_CURRENT_DIR: - break; + if ( node->type == IMFS_DIRECTORY ) { + if ( node->info.directory.mt_fs != NULL ) { + fs_root_ptr = &node->info.directory.mt_fs->mt_fs_root; } } - *name = &path[ i - len ]; - - /* - * We have evaluated the path as far as we can. - * Verify there is not any invalid stuff at the end of the name. - */ - - for( ; path[i] != '\0'; i++) { - if ( !IMFS_is_separator( path[ i ] ) ) - rtems_set_errno_and_return_minus_one( ENOENT ); - } - - /* - * Verify we can execute and write to this directory. - */ - - result = IMFS_Set_handlers( pathloc ); - - /* - * The returned node must be a directory - */ - node = pathloc->node_access; - if ( node->type != IMFS_DIRECTORY ) - rtems_set_errno_and_return_minus_one( ENOTDIR ); - - /* - * We must have Write and execute permission on the returned node. - */ - - if ( !IMFS_evaluate_permission( pathloc, RTEMS_LIBIO_PERMS_WX ) ) - rtems_set_errno_and_return_minus_one( EACCES ); - - return result; + return fs_root_ptr; } -/* - * IMFS_eval_path - * - * The following routine evaluate path for a node that wishes to be - * accessed with mode. pathloc is returned with a pointer to the - * node to be accessed. - */ - -int IMFS_eval_path( - const char *pathname, /* IN */ - size_t pathnamelen, /* IN */ - int flags, /* IN */ - rtems_filesystem_location_info_t *pathloc /* IN/OUT */ - ) +static rtems_filesystem_eval_path_generic_status IMFS_eval_token( + rtems_filesystem_eval_path_context_t *ctx, + void *arg, + const char *token, + size_t tokenlen +) { - int i = 0; - int len; - IMFS_token_types type = IMFS_CURRENT_DIR; - char token[ IMFS_NAME_MAX + 1 ]; - IMFS_jnode_t *node; - int result; - - if ( !rtems_libio_is_valid_perms( flags ) ) { - rtems_set_errno_and_return_minus_one( EIO ); - } - - /* - * This was filled in by the caller and is valid in the - * mount table. - */ - - node = pathloc->node_access; - - /* - * Evaluate all tokens until we are done or an error occurs. - */ - - while( (type != IMFS_NO_MORE_PATH) && (type != IMFS_INVALID_TOKEN) ) { - - type = IMFS_get_token( &pathname[i], pathnamelen, token, &len ); - pathnamelen -= len; - i += len; - - if ( !pathloc->node_access ) - rtems_set_errno_and_return_minus_one( ENOENT ); + rtems_filesystem_eval_path_generic_status status = + RTEMS_FILESYSTEM_EVAL_PATH_GENERIC_DONE; + rtems_filesystem_location_info_t *currentloc = + rtems_filesystem_eval_path_get_currentloc( ctx ); + IMFS_jnode_t *dir = currentloc->node_access; + bool access_ok = rtems_filesystem_eval_path_check_access( + ctx, + RTEMS_LIBIO_PERMS_SEARCH, + dir->st_mode, + dir->st_uid, + dir->st_gid + ); - /* - * I cannot move out of this directory without execute permission. - */ - if ( type != IMFS_NO_MORE_PATH ) - if ( node->type == IMFS_DIRECTORY ) - if ( !IMFS_evaluate_permission( pathloc, RTEMS_LIBIO_PERMS_SEARCH ) ) - rtems_set_errno_and_return_minus_one( EACCES ); + if ( access_ok ) { + IMFS_jnode_t *entry = IMFS_search_in_directory( dir, token, tokenlen ); - node = pathloc->node_access; + if ( entry != NULL ) { + bool terminal = !rtems_filesystem_eval_path_has_path( ctx ); + int eval_flags = rtems_filesystem_eval_path_get_flags( ctx ); + bool follow_hard_link = (eval_flags & RTEMS_LIBIO_FOLLOW_HARD_LINK) != 0; + bool follow_sym_link = (eval_flags & RTEMS_LIBIO_FOLLOW_SYM_LINK) != 0; - switch( type ) { - case IMFS_UP_DIR: - /* - * Am I at the root of all filesystems? (chroot'ed?) - */ + rtems_filesystem_eval_path_clear_token( ctx ); - if ( pathloc->node_access == rtems_filesystem_root.node_access ) - break; /* Throw out the .. in this case */ + if ( entry->type == IMFS_HARD_LINK && (follow_hard_link || !terminal)) { + entry = entry->info.hard_link.link_node; + } - /* - * Am I at the root of this mounted filesystem? - */ + if ( entry->type == IMFS_SYM_LINK && (follow_sym_link || !terminal)) { + const char *target = entry->info.sym_link.name; - if ( rtems_filesystem_is_root_location( pathloc ) ) { + rtems_filesystem_eval_path_recursive( ctx, target, strlen( target ) ); + } else { + rtems_filesystem_global_location_t **fs_root_ptr = + IMFS_is_mount_point( entry ); - /* - * Am I at the root of all filesystems? - */ + if ( fs_root_ptr == NULL ) { + currentloc->node_access = entry; + IMFS_Set_handlers( currentloc ); - if ( pathloc->node_access == rtems_filesystem_root.node_access ) { - break; /* Throw out the .. in this case */ - } else { - *pathloc = pathloc->mt_entry->mt_point_node; - return (*pathloc->ops->evalpath_h)(&(pathname[i-len]), - pathnamelen+len, - flags,pathloc); + if ( !terminal ) { + status = RTEMS_FILESYSTEM_EVAL_PATH_GENERIC_CONTINUE; } } else { - - if ( !node->Parent ) - rtems_set_errno_and_return_minus_one( ENOENT ); - - node = node->Parent; - pathloc->node_access = node; - - } - - pathloc->node_access = node; - break; - - case IMFS_NAME: - /* - * If we are at a link follow it. - */ - if ( node->type == IMFS_HARD_LINK ) { - IMFS_evaluate_hard_link( pathloc, 0 ); - node = pathloc->node_access; - - /* - * It would be a design error if we evaluated the link and - * was broken. - */ - IMFS_assert( node ); - - } else if ( node->type == IMFS_SYM_LINK ) { - result = IMFS_evaluate_sym_link( pathloc, 0 ); - - /* - * In contrast to a hard link, it is possible to have a broken - * symbolic link. - */ - node = pathloc->node_access; - if ( result == -1 ) - return -1; - } - - /* - * Only a directory can be decended into. - */ - if ( node->type != IMFS_DIRECTORY ) - rtems_set_errno_and_return_minus_one( ENOTDIR ); - - /* - * Find the token name in the current node. - */ - node = IMFS_find_match_in_dir( node, token ); - if ( !node ) - rtems_set_errno_and_return_minus_one( ENOENT ); - - /* - * If we are at a node that is a mount point so current directory - * actually exists on the mounted file system and not in the node that - * contains the mount point node. For example a stat of the mount - * point should return the details of the root of the mounted file - * system not the mount point node of parent file system. - * - * If the node we have just moved to is a mount point do not loop and - * get the token because the token may be suitable for the mounted - * file system and not the IMFS. For example the IMFS length is - * limited. If the token is a parent directory move back up otherwise - * set loc to the new fs root node and let them finish evaluating the - * path. - */ - if (( node->type == IMFS_DIRECTORY ) && ( node->info.directory.mt_fs != NULL )) { - IMFS_skip_separator( pathname, &pathnamelen, &i); - if ((pathname[i] != '.') || (pathname[i + 1] != '.')) { - *pathloc = node->info.directory.mt_fs->mt_fs_root; - return (*pathloc->ops->evalpath_h)( &pathname[i], - pathnamelen, - flags, pathloc ); + access_ok = rtems_filesystem_eval_path_check_access( + ctx, + RTEMS_LIBIO_PERMS_EXEC, + entry->st_mode, + entry->st_uid, + entry->st_gid + ); + if ( access_ok ) { + rtems_filesystem_eval_path_restart( ctx, fs_root_ptr ); } - i += 2; - pathnamelen -= 2; - node = node->Parent; } - - /* - * Set the node access to the point we have found. - */ - pathloc->node_access = node; - break; - - case IMFS_NO_MORE_PATH: - case IMFS_CURRENT_DIR: - break; - - case IMFS_INVALID_TOKEN: - rtems_set_errno_and_return_minus_one( ENAMETOOLONG ); - break; - - } - } - - /* - * Always return the root node. - * - * If we are at a node that is a mount point. Set loc to the - * new fs root node and let let the mounted filesystem set the handlers. - * - * NOTE: The behavior of stat() on a mount point appears to be questionable. - */ - - if ( node->type == IMFS_DIRECTORY ) { - if ( node->info.directory.mt_fs != NULL ) { - *pathloc = node->info.directory.mt_fs->mt_fs_root; - return (*pathloc->ops->evalpath_h)( &pathname[i-len], - pathnamelen+len, - flags, pathloc ); + } } else { - result = IMFS_Set_handlers( pathloc ); + status = RTEMS_FILESYSTEM_EVAL_PATH_GENERIC_NO_ENTRY; } - } else { - result = IMFS_Set_handlers( pathloc ); } - /* - * Verify we have the correct permissions for this node. - */ + return status; +} - if ( !IMFS_evaluate_permission( pathloc, flags ) ) - rtems_set_errno_and_return_minus_one( EACCES ); +static const rtems_filesystem_eval_path_generic_config IMFS_eval_config = { + .is_directory = IMFS_is_directory, + .eval_token = IMFS_eval_token +}; - return result; +void IMFS_eval_path( rtems_filesystem_eval_path_context_t *ctx ) +{ + rtems_filesystem_eval_path_generic( ctx, NULL, &IMFS_eval_config ); } diff --git a/cpukit/libfs/src/imfs/imfs_fchmod.c b/cpukit/libfs/src/imfs/imfs_fchmod.c index 54a093de2f..4236a2901b 100644 --- a/cpukit/libfs/src/imfs/imfs_fchmod.c +++ b/cpukit/libfs/src/imfs/imfs_fchmod.c @@ -12,18 +12,14 @@ */ #if HAVE_CONFIG_H -#include "config.h" + #include "config.h" #endif -#include <errno.h> - -#include <rtems/libio_.h> -#include <rtems/seterr.h> #include "imfs.h" int IMFS_fchmod( - rtems_filesystem_location_info_t *loc, - mode_t mode + const rtems_filesystem_location_info_t *loc, + mode_t mode ) { IMFS_jnode_t *jnode; diff --git a/cpukit/libfs/src/imfs/imfs_fifo.c b/cpukit/libfs/src/imfs/imfs_fifo.c index e447b26a70..790471e472 100644 --- a/cpukit/libfs/src/imfs/imfs_fifo.c +++ b/cpukit/libfs/src/imfs/imfs_fifo.c @@ -11,13 +11,9 @@ */ #if HAVE_CONFIG_H -#include "config.h" + #include "config.h" #endif -#include <stdlib.h> -#include <rtems/libio_.h> -#include <rtems/seterr.h> - #include "imfs.h" #define JNODE2PIPE(_jnode) ( (_jnode)->info.fifo.pipe ) @@ -35,8 +31,8 @@ do { \ static int IMFS_fifo_open( rtems_libio_t *iop, const char *pathname, - uint32_t flag, - uint32_t mode + int oflag, + mode_t mode ) { IMFS_jnode_t *jnode = iop->pathinfo.node_access; @@ -138,10 +134,8 @@ const rtems_filesystem_file_handlers_r IMFS_fifo_handlers = { IMFS_fifo_ioctl, IMFS_fifo_lseek, IMFS_stat, - IMFS_fchmod, rtems_filesystem_default_ftruncate, rtems_filesystem_default_fsync, rtems_filesystem_default_fdatasync, - rtems_filesystem_default_fcntl, - IMFS_rmnod, + rtems_filesystem_default_fcntl }; diff --git a/cpukit/libfs/src/imfs/imfs_fsunmount.c b/cpukit/libfs/src/imfs/imfs_fsunmount.c index b65c20e60d..49ade1bab9 100644 --- a/cpukit/libfs/src/imfs/imfs_fsunmount.c +++ b/cpukit/libfs/src/imfs/imfs_fsunmount.c @@ -12,20 +12,10 @@ */ #if HAVE_CONFIG_H -#include "config.h" + #include "config.h" #endif -#include <sys/types.h> /* for mkdir */ -#include <fcntl.h> -#include <unistd.h> -#include <stdlib.h> - #include "imfs.h" -#include <rtems/libio_.h> - -#if defined(IMFS_DEBUG) -#include <stdio.h> -#endif /* * IMFS_fsunmount @@ -43,7 +33,7 @@ #define jnode_get_first_child( jnode ) \ ((IMFS_jnode_t *)( rtems_chain_head( jnode_get_control( jnode ) )->next)) -int IMFS_fsunmount( +void IMFS_fsunmount( rtems_filesystem_mount_table_entry_t *temp_mt_entry ) { @@ -57,29 +47,24 @@ int IMFS_fsunmount( * associated memory space */ - jnode = (IMFS_jnode_t *)temp_mt_entry->mt_fs_root.node_access; - loc = temp_mt_entry->mt_fs_root; + loc = temp_mt_entry->mt_fs_root->location; + jnode = (IMFS_jnode_t *)loc.node_access; /* * Set this to null to indicate that it is being unmounted. */ - temp_mt_entry->mt_fs_root.node_access = NULL; + temp_mt_entry->mt_fs_root->location.node_access = NULL; do { next = jnode->Parent; loc.node_access = (void *)jnode; IMFS_Set_handlers( &loc ); - if ( jnode->type != IMFS_DIRECTORY ) { - result = IMFS_unlink( NULL, &loc ); + if ( jnode->type != IMFS_DIRECTORY || jnode_has_no_children( jnode ) ) { + result = IMFS_rmnod( NULL, &loc ); if (result != 0) - return -1; - jnode = next; - } else if ( jnode_has_no_children( jnode ) ) { - result = IMFS_unlink( NULL, &loc ); - if (result != 0) - return -1; + rtems_fatal_error_occurred(0xdeadbeef); jnode = next; } if ( jnode != NULL ) { @@ -89,6 +74,4 @@ int IMFS_fsunmount( } } } while (jnode != NULL); - - return 0; } diff --git a/cpukit/libfs/src/imfs/imfs_getchild.c b/cpukit/libfs/src/imfs/imfs_getchild.c deleted file mode 100644 index 1cfeb2a537..0000000000 --- a/cpukit/libfs/src/imfs/imfs_getchild.c +++ /dev/null @@ -1,66 +0,0 @@ -/* - * IMFS_find_match_in_dir() - * - * This routine returns the child name in the given directory. - * - * COPYRIGHT (c) 1989-1999. - * On-Line Applications Research Corporation (OAR). - * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rtems.com/license/LICENSE. - * - * $Id$ - */ - -#if HAVE_CONFIG_H -#include "config.h" -#endif - -#include <errno.h> -#include <string.h> -#include "imfs.h" - -static const char dotname[2] = "."; -static const char dotdotname[3] = ".."; - -IMFS_jnode_t *IMFS_find_match_in_dir( - IMFS_jnode_t *directory, - char *name -) -{ - rtems_chain_node *the_node; - rtems_chain_control *the_chain; - IMFS_jnode_t *the_jnode; - - /* - * Check for fatal errors. A NULL directory show a problem in the - * the IMFS code. - */ - IMFS_assert( directory ); - IMFS_assert( name ); - - /* - * Check for "." and ".." - */ - - if ( !strcmp( name, dotname ) ) - return directory; - - if ( !strcmp( name, dotdotname ) ) - return directory->Parent; - - the_chain = &directory->info.directory.Entries; - - for ( the_node = rtems_chain_first( the_chain ); - !rtems_chain_is_tail( the_chain, the_node ); - the_node = the_node->next ) { - - the_jnode = (IMFS_jnode_t *) the_node; - - if ( !strcmp( name, the_jnode->name ) ) - return the_jnode; - } - - return 0; -} diff --git a/cpukit/libfs/src/imfs/imfs_gtkn.c b/cpukit/libfs/src/imfs/imfs_gtkn.c deleted file mode 100644 index b15b2f1136..0000000000 --- a/cpukit/libfs/src/imfs/imfs_gtkn.c +++ /dev/null @@ -1,91 +0,0 @@ -/* - * IMFS_get_token - * - * Routine to get a token (name or separator) from the path - * the length of the token is returned in token_len. - * - * COPYRIGHT (c) 1989-1999. - * On-Line Applications Research Corporation (OAR). - * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rtems.com/license/LICENSE. - * - * $Id$ - */ - -#if HAVE_CONFIG_H -#include "config.h" -#endif - -#include <stdlib.h> -#include <string.h> - -#include "imfs.h" -#include <rtems/libio_.h> - -IMFS_token_types IMFS_get_token( - const char *path, - int pathlen, - char *token, - int *token_len -) -{ - register int i = 0; - IMFS_token_types type = IMFS_NAME; - register char c; - - /* - * Copy a name into token. (Remember NULL is a token.) - */ - c = path[i]; - while ( (!IMFS_is_separator(c)) && (i < pathlen) && (i <= IMFS_NAME_MAX) ) { - - token[i] = c; - - if ( i == IMFS_NAME_MAX ) - return IMFS_INVALID_TOKEN; - - if ( !IMFS_is_valid_name_char(c) ) - type = IMFS_INVALID_TOKEN; - - c = path [++i]; - } - - /* - * Copy a seperator into token. - */ - - if ( i == 0 ) { - token[i] = c; - - if ( (token[i] != '\0') && pathlen ) { - i++; - type = IMFS_CURRENT_DIR; - } else { - type = IMFS_NO_MORE_PATH; - } - } else if (token[ i-1 ] != '\0') { - token[i] = '\0'; - } - - /* - * Set token_len to the number of characters copied. - */ - - *token_len = i; - - /* - * If we copied something that was not a seperator see if - * it was a special name. - */ - - if ( type == IMFS_NAME ) { - if ( strcmp( token, "..") == 0 ) - type = IMFS_UP_DIR; - else if ( strcmp( token, "." ) == 0 ) - type = IMFS_CURRENT_DIR; - } - - return type; -} diff --git a/cpukit/libfs/src/imfs/imfs_handlers_device.c b/cpukit/libfs/src/imfs/imfs_handlers_device.c index 8e249bda33..a6edfb1f77 100644 --- a/cpukit/libfs/src/imfs/imfs_handlers_device.c +++ b/cpukit/libfs/src/imfs/imfs_handlers_device.c @@ -12,11 +12,9 @@ */ #if HAVE_CONFIG_H -#include "config.h" + #include "config.h" #endif -#include <errno.h> - #include "imfs.h" /* @@ -31,10 +29,8 @@ const rtems_filesystem_file_handlers_r IMFS_device_handlers = { device_ioctl, device_lseek, IMFS_stat, - IMFS_fchmod, device_ftruncate, rtems_filesystem_default_fsync, rtems_filesystem_default_fdatasync, - rtems_filesystem_default_fcntl, - IMFS_rmnod + rtems_filesystem_default_fcntl }; diff --git a/cpukit/libfs/src/imfs/imfs_handlers_directory.c b/cpukit/libfs/src/imfs/imfs_handlers_directory.c index 5ca715825e..4778f45599 100644 --- a/cpukit/libfs/src/imfs/imfs_handlers_directory.c +++ b/cpukit/libfs/src/imfs/imfs_handlers_directory.c @@ -12,11 +12,9 @@ */ #if HAVE_CONFIG_H -#include "config.h" + #include "config.h" #endif -#include <errno.h> - #include "imfs.h" /* @@ -30,11 +28,9 @@ const rtems_filesystem_file_handlers_r IMFS_directory_handlers = { rtems_filesystem_default_write, rtems_filesystem_default_ioctl, imfs_dir_lseek, - imfs_dir_fstat, - IMFS_fchmod, - rtems_filesystem_default_ftruncate, + IMFS_stat, + rtems_filesystem_default_ftruncate_directory, rtems_filesystem_default_fsync, IMFS_fdatasync, - rtems_filesystem_default_fcntl, - imfs_dir_rmnod + rtems_filesystem_default_fcntl }; diff --git a/cpukit/libfs/src/imfs/imfs_handlers_link.c b/cpukit/libfs/src/imfs/imfs_handlers_link.c index d8bbec82d4..967aa1410f 100644 --- a/cpukit/libfs/src/imfs/imfs_handlers_link.c +++ b/cpukit/libfs/src/imfs/imfs_handlers_link.c @@ -12,11 +12,9 @@ */ #if HAVE_CONFIG_H -#include "config.h" + #include "config.h" #endif -#include <errno.h> - #include "imfs.h" /* @@ -31,10 +29,8 @@ const rtems_filesystem_file_handlers_r IMFS_link_handlers = { rtems_filesystem_default_ioctl, rtems_filesystem_default_lseek, IMFS_stat, /* stat */ - rtems_filesystem_default_fchmod, rtems_filesystem_default_ftruncate, rtems_filesystem_default_fsync, rtems_filesystem_default_fdatasync, - rtems_filesystem_default_fcntl, - IMFS_rmnod + rtems_filesystem_default_fcntl }; diff --git a/cpukit/libfs/src/imfs/imfs_handlers_memfile.c b/cpukit/libfs/src/imfs/imfs_handlers_memfile.c index ee859ee98d..10e47fd0f8 100644 --- a/cpukit/libfs/src/imfs/imfs_handlers_memfile.c +++ b/cpukit/libfs/src/imfs/imfs_handlers_memfile.c @@ -12,11 +12,9 @@ */ #if HAVE_CONFIG_H -#include "config.h" + #include "config.h" #endif -#include <errno.h> - #include "imfs.h" /* @@ -31,10 +29,8 @@ const rtems_filesystem_file_handlers_r IMFS_memfile_handlers = { memfile_ioctl, memfile_lseek, IMFS_stat, - IMFS_fchmod, memfile_ftruncate, IMFS_fdatasync, /* fsync */ IMFS_fdatasync, - rtems_filesystem_default_fcntl, - IMFS_rmnod + rtems_filesystem_default_fcntl }; diff --git a/cpukit/libfs/src/imfs/imfs_init.c b/cpukit/libfs/src/imfs/imfs_init.c index c74d493b40..2a7d890a09 100644 --- a/cpukit/libfs/src/imfs/imfs_init.c +++ b/cpukit/libfs/src/imfs/imfs_init.c @@ -18,28 +18,29 @@ */ #if HAVE_CONFIG_H -#include "config.h" + #include "config.h" #endif -#include <rtems/libio_.h> - #include "imfs.h" const rtems_filesystem_operations_table IMFS_ops = { - .evalpath_h = IMFS_eval_path, - .evalformake_h = IMFS_evaluate_for_make, + .lock_h = rtems_filesystem_default_lock, + .unlock_h = rtems_filesystem_default_unlock, + .eval_path_h = IMFS_eval_path, .link_h = IMFS_link, - .unlink_h = IMFS_unlink, + .are_nodes_equal_h = rtems_filesystem_default_are_nodes_equal, .node_type_h = IMFS_node_type, .mknod_h = IMFS_mknod, + .rmnod_h = IMFS_rmnod, + .fchmod_h = IMFS_fchmod, .chown_h = IMFS_chown, + .clonenod_h = rtems_filesystem_default_clonenode, .freenod_h = rtems_filesystem_default_freenode, .mount_h = IMFS_mount, .fsmount_me_h = IMFS_initialize, .unmount_h = IMFS_unmount, .fsunmount_me_h = IMFS_fsunmount, .utime_h = IMFS_utime, - .eval_link_h = IMFS_evaluate_link, .symlink_h = IMFS_symlink, .readlink_h = IMFS_readlink, .rename_h = IMFS_rename, @@ -54,8 +55,7 @@ int IMFS_initialize( return IMFS_initialize_support( mt_entry, &IMFS_ops, - &IMFS_memfile_handlers, - &IMFS_directory_handlers, - &rtems_filesystem_handlers_default /* for fifos */ + &IMFS_link_handlers, + &rtems_filesystem_handlers_default /* for fifos */ ); } diff --git a/cpukit/libfs/src/imfs/imfs_initsupp.c b/cpukit/libfs/src/imfs/imfs_initsupp.c index 47e1d392e8..61ad6a70f2 100644 --- a/cpukit/libfs/src/imfs/imfs_initsupp.c +++ b/cpukit/libfs/src/imfs/imfs_initsupp.c @@ -12,21 +12,12 @@ */ #if HAVE_CONFIG_H -#include "config.h" + #include "config.h" #endif -#include <sys/types.h> /* for mkdir */ -#include <fcntl.h> -#include <unistd.h> -#include <stdlib.h> - #include "imfs.h" -#include <rtems/libio_.h> -#include <rtems/seterr.h> -#if defined(IMFS_DEBUG) -#include <stdio.h> -#endif +#include <stdlib.h> /* * IMFS_determine_bytes_per_block @@ -66,8 +57,7 @@ static int IMFS_determine_bytes_per_block( int IMFS_initialize_support( rtems_filesystem_mount_table_entry_t *temp_mt_entry, const rtems_filesystem_operations_table *op_table, - const rtems_filesystem_file_handlers_r *memfile_handlers, - const rtems_filesystem_file_handlers_r *directory_handlers, + const rtems_filesystem_file_handlers_r *link_handlers, const rtems_filesystem_file_handlers_r *fifo_handlers ) { @@ -87,9 +77,9 @@ int IMFS_initialize_support( * * NOTE: UNIX root is 755 and owned by root/root (0/0). */ - temp_mt_entry->mt_fs_root.node_access = IMFS_create_root_node(); - temp_mt_entry->mt_fs_root.handlers = directory_handlers; - temp_mt_entry->mt_fs_root.ops = op_table; + temp_mt_entry->mt_fs_root->location.node_access = IMFS_create_root_node(); + temp_mt_entry->mt_fs_root->location.handlers = &IMFS_directory_handlers; + temp_mt_entry->mt_fs_root->location.ops = op_table; temp_mt_entry->pathconf_limits_and_options = IMFS_LIMITS_AND_OPTIONS; /* @@ -97,7 +87,7 @@ int IMFS_initialize_support( */ fs_info = calloc( 1, sizeof( IMFS_fs_info_t ) ); if ( !fs_info ) { - free(temp_mt_entry->mt_fs_root.node_access); + free(temp_mt_entry->mt_fs_root->location.node_access); rtems_set_errno_and_return_minus_one(ENOMEM); } temp_mt_entry->fs_info = fs_info; @@ -108,11 +98,10 @@ int IMFS_initialize_support( fs_info->instance = imfs_instance++; fs_info->ino_count = 1; - fs_info->memfile_handlers = memfile_handlers; - fs_info->directory_handlers = directory_handlers; + fs_info->link_handlers = link_handlers; fs_info->fifo_handlers = fifo_handlers; - jnode = temp_mt_entry->mt_fs_root.node_access; + jnode = temp_mt_entry->mt_fs_root->location.node_access; jnode->st_ino = fs_info->ino_count; return 0; diff --git a/cpukit/libfs/src/imfs/imfs_link.c b/cpukit/libfs/src/imfs/imfs_link.c index c7dc6475f9..130c529d75 100644 --- a/cpukit/libfs/src/imfs/imfs_link.c +++ b/cpukit/libfs/src/imfs/imfs_link.c @@ -16,51 +16,36 @@ */ #if HAVE_CONFIG_H -#include "config.h" + #include "config.h" #endif -#include <errno.h> #include "imfs.h" -#include <rtems/libio_.h> -#include <rtems/seterr.h> int IMFS_link( - rtems_filesystem_location_info_t *to_loc, /* IN */ - rtems_filesystem_location_info_t *parent_loc, /* IN */ - const char *token /* IN */ + const rtems_filesystem_location_info_t *parentloc, + const rtems_filesystem_location_info_t *targetloc, + const char *name, + size_t namelen ) { IMFS_types_union info; IMFS_jnode_t *new_node; - char new_name[ IMFS_NAME_MAX + 1 ]; - int i; /* * Verify this node can be linked to. */ - info.hard_link.link_node = to_loc->node_access; + info.hard_link.link_node = targetloc->node_access; if ( info.hard_link.link_node->st_nlink >= LINK_MAX ) rtems_set_errno_and_return_minus_one( EMLINK ); /* - * Remove any separators at the end of the string. - */ - IMFS_get_token( token, strlen( token ), new_name, &i ); - - /* * Create a new link node. - * - * NOTE: Coverity Id 19 reports this as a leak - * While technically not a leak, it indicated that IMFS_create_node - * was ONLY passed a NULL when we created the root node. We - * added a new IMFS_create_root_node() so this path no longer - * existed. The result was simpler code which should not have - * this path. */ new_node = IMFS_create_node( - parent_loc, + parentloc, IMFS_HARD_LINK, - new_name, + name, + namelen, ( S_IFLNK | ( S_IRWXU | S_IRWXG | S_IRWXO )), &info ); diff --git a/cpukit/libfs/src/imfs/imfs_load_tar.c b/cpukit/libfs/src/imfs/imfs_load_tar.c index 69c69c3e6d..0ae0f7cf88 100644 --- a/cpukit/libfs/src/imfs/imfs_load_tar.c +++ b/cpukit/libfs/src/imfs/imfs_load_tar.c @@ -21,16 +21,12 @@ * pointing to addresses in the TAR image. */ -#include <sys/types.h> -#include <sys/stat.h> -#include <fcntl.h> -#include <tar.h> +#include "imfs.h" +#include <sys/stat.h> #include <string.h> +#include <tar.h> -#include <rtems.h> -#include <rtems/libio_.h> -#include <rtems/imfs.h> #include <rtems/untar.h> /* @@ -80,13 +76,11 @@ * create_node. */ int rtems_tarfs_load( - char *mountpoint, + const char *mountpoint, uint8_t *tar_image, - size_t tar_size + size_t tar_size ) { - rtems_filesystem_location_info_t root_loc; - rtems_filesystem_location_info_t loc; const char *hdr_ptr; char filename[100]; char full_filename[256]; @@ -97,26 +91,27 @@ int rtems_tarfs_load( int offset; unsigned long nblocks; IMFS_jnode_t *node; - int status; - - status = rtems_filesystem_evaluate_path( - mountpoint, - strlen(mountpoint), - 0, - &root_loc, - 0 + int rv = 0; + int eval_flags = RTEMS_LIBIO_FOLLOW_LINK; + rtems_filesystem_eval_path_context_t ctx; + rtems_filesystem_location_info_t rootloc; + rtems_filesystem_location_info_t *currentloc = + rtems_filesystem_eval_path_start( &ctx, mountpoint, eval_flags ); + + rtems_filesystem_eval_path_extract_currentloc( &ctx, &rootloc ); + rtems_filesystem_eval_path_set_flags( + &ctx, + RTEMS_LIBIO_MAKE | RTEMS_LIBIO_EXCLUSIVE ); - if (status != 0) - return -1; - - if (root_loc.ops != &IMFS_ops && root_loc.ops != &fifoIMFS_ops) - return -1; + if (rootloc.ops != &IMFS_ops && rootloc.ops != &fifoIMFS_ops) { + rv = -1; + } /* * Create an IMFS node structure pointing to tar image memory. */ offset = 0; - while (1) { + while ( rv == 0 ) { if (offset + 512 > tar_size) break; @@ -154,22 +149,23 @@ int rtems_tarfs_load( } /* * Create a LINEAR_FILE node - * - * NOTE: Coverity Id 20 reports this as a leak. - * While technically not a leak, it indicated that - * IMFS_create_node was ONLY passed a NULL when we created the - * root node. We added a new IMFS_create_root_node() so this - * path no longer existed. The result was simpler code which - * should not have this path. */ else if (linkflag == REGTYPE) { - const char *name; - - loc = root_loc; - if (IMFS_evaluate_for_make(filename, &loc, &name) == 0) { + rtems_filesystem_location_free( currentloc ); + rtems_filesystem_location_clone( currentloc, &rootloc ); + rtems_filesystem_eval_path_set_path( + &ctx, + filename, + strlen( filename ) + ); + rtems_filesystem_eval_path_continue( &ctx ); + + if ( !rtems_filesystem_location_is_null( currentloc ) ) { node = IMFS_create_node( - &loc, - IMFS_LINEAR_FILE, (char *)name, + currentloc, + IMFS_LINEAR_FILE, + rtems_filesystem_eval_path_get_token( &ctx ), + rtems_filesystem_eval_path_get_tokenlen( &ctx ), (file_mode & (S_IRWXU | S_IRWXG | S_IRWXO)) | S_IFREG, NULL ); @@ -181,6 +177,10 @@ int rtems_tarfs_load( offset += 512 * nblocks; } } - return status; + + rtems_filesystem_location_free( &rootloc ); + rtems_filesystem_eval_path_cleanup( &ctx ); + + return rv; } diff --git a/cpukit/libfs/src/imfs/imfs_mknod.c b/cpukit/libfs/src/imfs/imfs_mknod.c index 747391e9fd..47f7dca0e8 100644 --- a/cpukit/libfs/src/imfs/imfs_mknod.c +++ b/cpukit/libfs/src/imfs/imfs_mknod.c @@ -6,6 +6,9 @@ * COPYRIGHT (c) 1989-2010. * On-Line Applications Research Corporation (OAR). * + * Modifications to support reference counting in the file system are + * Copyright (c) 2012 embedded brains GmbH. + * * The license and distribution terms for this file may be * found in the file LICENSE in this distribution or at * http://www.rtems.com/license/LICENSE. @@ -14,65 +17,60 @@ */ #if HAVE_CONFIG_H -#include "config.h" + #include "config.h" #endif -#include <sys/types.h> -#include <sys/stat.h> -#include <fcntl.h> -#include <unistd.h> -#include <errno.h> -#include <stdlib.h> - #include "imfs.h" -#include <rtems/libio_.h> -#include <rtems/seterr.h> + +static void get_type_and_info_by_mode_and_dev( + mode_t mode, + dev_t dev, + IMFS_jnode_types_t *type, + IMFS_types_union *info +) +{ + if ( S_ISDIR( mode ) ) { + *type = IMFS_DIRECTORY; + } else if ( S_ISREG( mode ) ) { + *type = IMFS_MEMORY_FILE; + } else if ( S_ISBLK( mode ) || S_ISCHR( mode ) ) { + *type = IMFS_DEVICE; + rtems_filesystem_split_dev_t( + dev, + info->device.major, + info->device.minor + ); + } else if (S_ISFIFO( mode )) { + *type = IMFS_FIFO; + } else { + IMFS_assert( 0 ); + } +} int IMFS_mknod( - const char *token, /* IN */ - mode_t mode, /* IN */ - dev_t dev, /* IN */ - rtems_filesystem_location_info_t *pathloc /* IN/OUT */ + const rtems_filesystem_location_info_t *parentloc, + const char *name, + size_t namelen, + mode_t mode, + dev_t dev ) { - IMFS_token_types type = 0; - IMFS_jnode_t *new_node; - int result; - char new_name[ IMFS_NAME_MAX + 1 ]; - IMFS_types_union info; + int rv = 0; + IMFS_jnode_types_t type; + IMFS_types_union info; + IMFS_jnode_t *new_node; - IMFS_get_token( token, strlen( token ), new_name, &result ); + get_type_and_info_by_mode_and_dev( mode, dev, &type, &info ); - /* - * Figure out what type of IMFS node this is. - */ - if ( S_ISDIR(mode) ) - type = IMFS_DIRECTORY; - else if ( S_ISREG(mode) ) - type = IMFS_MEMORY_FILE; - else if ( S_ISBLK(mode) || S_ISCHR(mode) ) { - type = IMFS_DEVICE; - rtems_filesystem_split_dev_t( dev, info.device.major, info.device.minor ); - } else if (S_ISFIFO(mode)) - type = IMFS_FIFO; - else - IMFS_assert( 0 ); + new_node = IMFS_create_node( parentloc, type, name, namelen, mode, &info ); + if ( new_node != NULL ) { + IMFS_jnode_t *parent = parentloc->node_access; - /* - * Allocate and fill in an IMFS jnode - * - * NOTE: Coverity Id 21 reports this as a leak. - * While technically not a leak, it indicated that IMFS_create_node - * was ONLY passed a NULL when we created the root node. We - * added a new IMFS_create_root_node() so this path no longer - * existed. The result was simpler code which should not have - * this path. - */ - new_node = IMFS_create_node( pathloc, type, new_name, mode, &info ); - if ( !new_node ) - rtems_set_errno_and_return_minus_one( ENOMEM ); + IMFS_update_ctime( parent ); + IMFS_update_mtime( parent ); + } else { + rv = -1; + } - IMFS_update_ctime(new_node->Parent); - IMFS_update_mtime(new_node->Parent); - return 0; + return rv; } diff --git a/cpukit/libfs/src/imfs/imfs_mount.c b/cpukit/libfs/src/imfs/imfs_mount.c index 3ec16da3f7..243e5a0e30 100644 --- a/cpukit/libfs/src/imfs/imfs_mount.c +++ b/cpukit/libfs/src/imfs/imfs_mount.c @@ -1,16 +1,12 @@ /* * IMFS_mount * - * This routine will look at a mount table entry that we are going to - * add to the mount table. If the mount point rtems_filesystem - * location_info_t struct refers to a node that is a directory, - * the node will be marked as a mount point by setting its directory.mt_fs - * pointer to point to the mount table entry that we are about to add - * to the mount table chain. - * * COPYRIGHT (c) 1989-1999. * On-Line Applications Research Corporation (OAR). * + * Modifications to support reference counting in the file system are + * Copyright (c) 2012 embedded brains GmbH. + * * The license and distribution terms for this file may be * found in the file LICENSE in this distribution or at * http://www.rtems.com/license/LICENSE. @@ -19,35 +15,27 @@ */ #if HAVE_CONFIG_H -#include "config.h" + #include "config.h" #endif -#include <errno.h> - #include "imfs.h" -#include <rtems/libio_.h> -#include <rtems/seterr.h> -int IMFS_mount( - rtems_filesystem_mount_table_entry_t *mt_entry -) +int IMFS_mount( rtems_filesystem_mount_table_entry_t *mt_entry ) { - IMFS_jnode_t *node; - - node = mt_entry->mt_point_node.node_access; - - /* - * Is the node that we are mounting onto a directory node ? - */ - - if ( node->type != IMFS_DIRECTORY ) - rtems_set_errno_and_return_minus_one( ENOTDIR ); - - /* - * Set mt_fs pointer to point to the mount table entry for - * the mounted file system. - */ - - node->info.directory.mt_fs = mt_entry; - return 0; + int rv = 0; + IMFS_jnode_t *node = mt_entry->mt_point_node->location.node_access; + + if ( node->type == IMFS_DIRECTORY ) { + if ( node->info.directory.mt_fs == NULL ) { + node->info.directory.mt_fs = mt_entry; + } else { + errno = EBUSY; + rv = -1; + } + } else { + errno = ENOTDIR; + rv = -1; + } + + return rv; } diff --git a/cpukit/libfs/src/imfs/imfs_ntype.c b/cpukit/libfs/src/imfs/imfs_ntype.c index f80182b144..f399707c0c 100644 --- a/cpukit/libfs/src/imfs/imfs_ntype.c +++ b/cpukit/libfs/src/imfs/imfs_ntype.c @@ -7,6 +7,9 @@ * COPYRIGHT (c) 1989-1999. * On-Line Applications Research Corporation (OAR). * + * Modifications to support reference counting in the file system are + * Copyright (c) 2012 embedded brains GmbH. + * * The license and distribution terms for this file may be * found in the file LICENSE in this distribution or at * http://www.rtems.com/license/LICENSE. @@ -15,18 +18,30 @@ */ #if HAVE_CONFIG_H -#include "config.h" + #include "config.h" #endif -#include <errno.h> #include "imfs.h" rtems_filesystem_node_types_t IMFS_node_type( - rtems_filesystem_location_info_t *pathloc /* IN */ + const rtems_filesystem_location_info_t *loc ) { - IMFS_jnode_t *node; + const IMFS_jnode_t *node = loc->node_access; + IMFS_jnode_types_t imfs_type = node->type; + rtems_filesystem_node_types_t type; + + switch ( imfs_type ) { + case IMFS_HARD_LINK: + type = node->info.hard_link.link_node->type; + break; + case IMFS_LINEAR_FILE: + type = RTEMS_FILESYSTEM_MEMORY_FILE; + break; + default: + type = imfs_type; + break; + } - node = pathloc->node_access; - return node->type; + return type; } diff --git a/cpukit/libfs/src/imfs/imfs_readlink.c b/cpukit/libfs/src/imfs/imfs_readlink.c index b598fcf2c1..6786806abd 100644 --- a/cpukit/libfs/src/imfs/imfs_readlink.c +++ b/cpukit/libfs/src/imfs/imfs_readlink.c @@ -15,18 +15,15 @@ */ #if HAVE_CONFIG_H -#include "config.h" + #include "config.h" #endif -#include <errno.h> #include "imfs.h" -#include <rtems/libio_.h> -#include <rtems/seterr.h> ssize_t IMFS_readlink( - rtems_filesystem_location_info_t *loc, - char *buf, /* OUT */ - size_t bufsize + const rtems_filesystem_location_info_t *loc, + char *buf, + size_t bufsize ) { IMFS_jnode_t *node; diff --git a/cpukit/libfs/src/imfs/imfs_rename.c b/cpukit/libfs/src/imfs/imfs_rename.c index 95c27fa9fd..855d026c36 100644 --- a/cpukit/libfs/src/imfs/imfs_rename.c +++ b/cpukit/libfs/src/imfs/imfs_rename.c @@ -15,40 +15,50 @@ */ #if HAVE_CONFIG_H -#include "config.h" + #include "config.h" #endif -#include <errno.h> #include "imfs.h" -#include <rtems/libio_.h> -#include <rtems/seterr.h> int IMFS_rename( - rtems_filesystem_location_info_t *old_parent_loc, /* IN */ - rtems_filesystem_location_info_t *old_loc, /* IN */ - rtems_filesystem_location_info_t *new_parent_loc, /* IN */ - const char *new_name /* IN */ + const rtems_filesystem_location_info_t *oldparentloc, + const rtems_filesystem_location_info_t *oldloc, + const rtems_filesystem_location_info_t *newparentloc, + const char *name, + size_t namelen ) { - IMFS_jnode_t *the_jnode; - IMFS_jnode_t *new_parent; + int rv = 0; + IMFS_jnode_t *node = oldloc->node_access; + IMFS_jnode_t *new_parent = newparentloc->node_access; - the_jnode = old_loc->node_access; - - strncpy( the_jnode->name, new_name, IMFS_NAME_MAX ); + /* + * FIXME: Due to insufficient checks we can create inaccessible nodes with + * this operation. + */ - if ( the_jnode->Parent != NULL ) - rtems_chain_extract( (rtems_chain_node *) the_jnode ); + if ( node->Parent != NULL ) { + if ( namelen < IMFS_NAME_MAX ) { + memcpy( node->name, name, namelen ); + node->name [namelen] = '\0'; - new_parent = new_parent_loc->node_access; - the_jnode->Parent = new_parent; + rtems_chain_extract( &node->Node ); - rtems_chain_append( &new_parent->info.directory.Entries, &the_jnode->Node ); + node->Parent = new_parent; + rtems_chain_append( + &new_parent->info.directory.Entries, + &node->Node + ); - /* - * Update the time. - */ - IMFS_update_ctime( the_jnode ); + IMFS_update_ctime( node ); + } else { + errno = ENAMETOOLONG; + rv = -1; + } + } else { + errno = EINVAL; + rv = -1; + } - return 0; + return rv; } diff --git a/cpukit/libfs/src/imfs/imfs_rmnod.c b/cpukit/libfs/src/imfs/imfs_rmnod.c index 25c7cde084..c50041942f 100644 --- a/cpukit/libfs/src/imfs/imfs_rmnod.c +++ b/cpukit/libfs/src/imfs/imfs_rmnod.c @@ -7,6 +7,9 @@ * COPYRIGHT (c) 1989-1999. * On-Line Applications Research Corporation (OAR). * + * Modifications to support reference counting in the file system are + * Copyright (c) 2012 embedded brains GmbH. + * * The license and distribution terms for this file may be * found in the file LICENSE in this distribution or at * http://www.rtems.com/license/LICENSE. @@ -15,17 +18,13 @@ */ #if HAVE_CONFIG_H -#include "config.h" + #include "config.h" #endif -#include <stdlib.h> - -#include <rtems.h> -#include <rtems/libio.h> -#include <rtems/libio_.h> - #include "imfs.h" +#include <stdlib.h> + void IMFS_create_orphan( IMFS_jnode_t *jnode ) { if ( jnode->Parent != NULL ) { @@ -40,10 +39,7 @@ void IMFS_create_orphan( IMFS_jnode_t *jnode ) void IMFS_check_node_remove( IMFS_jnode_t *jnode ) { - if ( !rtems_libio_is_file_open( jnode ) && jnode->st_nlink < 1 ) { - if ( rtems_filesystem_current.node_access == jnode ) - rtems_filesystem_current.node_access = NULL; - + if ( jnode->st_nlink < 1 ) { switch ( jnode->type ) { case IMFS_MEMORY_FILE: IMFS_memfile_remove( jnode ); @@ -59,19 +55,75 @@ void IMFS_check_node_remove( IMFS_jnode_t *jnode ) } } -/* - * IMFS_rmnod - */ +static int IMFS_rmnod_directory( + const rtems_filesystem_location_info_t *parentloc, + const rtems_filesystem_location_info_t *loc +) +{ + IMFS_jnode_t *node = loc->node_access; + int rv = 0; + + if ( !rtems_chain_is_empty( &node->info.directory.Entries ) ) { + errno = ENOTEMPTY; + rv = -1; + } else if ( + rtems_filesystem_location_is_root( loc ) + || node->info.directory.mt_fs != NULL + ) { + errno = EBUSY; + rv = -1; + } + + return rv; +} + +static int IMFS_rmnod_hard_link( + const rtems_filesystem_location_info_t *parentloc, + const rtems_filesystem_location_info_t *loc +) +{ + int rv = 0; + IMFS_jnode_t *node = loc->node_access; + IMFS_jnode_t *target = node->info.hard_link.link_node; + + if ( target->st_nlink == 1) { + rtems_filesystem_location_info_t target_loc = *loc; + + target_loc.node_access = target; + IMFS_Set_handlers( &target_loc ); + + rv = (*target_loc.ops->rmnod_h)( parentloc, &target_loc ); + } else { + --target->st_nlink; + IMFS_update_ctime( target ); + } + + return rv; +} int IMFS_rmnod( - rtems_filesystem_location_info_t *parent_pathloc, /* IN */ - rtems_filesystem_location_info_t *pathloc /* IN */ + const rtems_filesystem_location_info_t *parentloc, + const rtems_filesystem_location_info_t *loc ) { - IMFS_jnode_t *jnode = (IMFS_jnode_t *) pathloc->node_access; + int rv = 0; + IMFS_jnode_t *node = loc->node_access; - IMFS_create_orphan( jnode ); - IMFS_check_node_remove( jnode ); + switch ( node->type ) { + case IMFS_DIRECTORY: + rv = IMFS_rmnod_directory( parentloc, loc ); + break; + case IMFS_HARD_LINK: + rv = IMFS_rmnod_hard_link( parentloc, loc ); + break; + default: + break; + } + + if ( rv == 0 ) { + IMFS_create_orphan( node ); + IMFS_check_node_remove( node ); + } - return 0; + return rv; } diff --git a/cpukit/libfs/src/imfs/imfs_stat.c b/cpukit/libfs/src/imfs/imfs_stat.c index 5bc1eae579..66d1ca2ba9 100644 --- a/cpukit/libfs/src/imfs/imfs_stat.c +++ b/cpukit/libfs/src/imfs/imfs_stat.c @@ -6,6 +6,9 @@ * COPYRIGHT (c) 1989-1999. * On-Line Applications Research Corporation (OAR). * + * Modifications to support reference counting in the file system are + * Copyright (c) 2012 embedded brains GmbH. + * * The license and distribution terms for this file may be * found in the file LICENSE in this distribution or at * http://www.rtems.com/license/LICENSE. @@ -14,31 +17,45 @@ */ #if HAVE_CONFIG_H -#include "config.h" + #include "config.h" #endif -#include <errno.h> -#include <string.h> #include "imfs.h" -#include <rtems/libio_.h> -#include <rtems/seterr.h> + +#include <dirent.h> +#include <string.h> + +static size_t IMFS_directory_size( const IMFS_jnode_t *the_jnode ) +{ + size_t size = 0; + const rtems_chain_control *chain = &the_jnode->info.directory.Entries; + const rtems_chain_node *current = rtems_chain_immutable_first( chain ); + const rtems_chain_node *tail = rtems_chain_immutable_tail( chain ); + + while ( current != tail ) { + size += sizeof(struct dirent); + current = rtems_chain_immutable_next( current ); + } + + return size; +} int IMFS_stat( - rtems_filesystem_location_info_t *loc, - struct stat *buf + const rtems_filesystem_location_info_t *loc, + struct stat *buf ) { - IMFS_fs_info_t *fs_info; - IMFS_jnode_t *the_jnode; - IMFS_device_t *io; - - the_jnode = loc->node_access; + IMFS_fs_info_t *fs_info = loc->mt_entry->fs_info; + IMFS_jnode_t *the_jnode = loc->node_access; + IMFS_device_t *io = &the_jnode->info.device; + if ( the_jnode->type == IMFS_HARD_LINK ) { + the_jnode = the_jnode->info.hard_link.link_node; + } switch ( the_jnode->type ) { case IMFS_DEVICE: - io = &the_jnode->info.device; buf->st_rdev = rtems_filesystem_make_dev_t( io->major, io->minor ); break; @@ -47,12 +64,15 @@ int IMFS_stat( buf->st_size = the_jnode->info.file.size; break; + case IMFS_DIRECTORY: + buf->st_size = IMFS_directory_size( the_jnode ); + break; + case IMFS_SYM_LINK: buf->st_size = strlen( the_jnode->info.sym_link.name ); break; case IMFS_FIFO: - buf->st_size = 0; break; default: @@ -64,7 +84,6 @@ int IMFS_stat( * The device number of the IMFS is the major number and the minor is the * instance. */ - fs_info = loc->mt_entry->fs_info; buf->st_dev = rtems_filesystem_make_dev_t( IMFS_DEVICE_MAJOR_NUMBER, fs_info->instance ); @@ -78,7 +97,9 @@ int IMFS_stat( buf->st_mtime = the_jnode->stat_mtime; buf->st_ctime = the_jnode->stat_ctime; - buf->st_blksize = imfs_rq_memfile_bytes_per_block; + if ( the_jnode->type != IMFS_DIRECTORY ) { + buf->st_blksize = imfs_rq_memfile_bytes_per_block; + } return 0; } diff --git a/cpukit/libfs/src/imfs/imfs_symlink.c b/cpukit/libfs/src/imfs/imfs_symlink.c index 863ad23510..5a1d06ad19 100644 --- a/cpukit/libfs/src/imfs/imfs_symlink.c +++ b/cpukit/libfs/src/imfs/imfs_symlink.c @@ -16,54 +16,39 @@ */ #if HAVE_CONFIG_H -#include "config.h" + #include "config.h" #endif -#include <errno.h> -#include <string.h> -#include <stdlib.h> #include "imfs.h" -#include <rtems/libio_.h> -#include <rtems/seterr.h> + +#include <stdlib.h> int IMFS_symlink( - rtems_filesystem_location_info_t *parent_loc, - const char *link_name, - const char *node_name + const rtems_filesystem_location_info_t *parentloc, + const char *name, + size_t namelen, + const char *target ) { IMFS_types_union info; IMFS_jnode_t *new_node; - char new_name[ IMFS_NAME_MAX + 1 ]; - int i; - - /* - * Remove any separators at the end of the string. - */ - IMFS_get_token( node_name, strlen( node_name ), new_name, &i ); /* * Duplicate link name */ - info.sym_link.name = strdup(link_name); + info.sym_link.name = strdup(target); if (info.sym_link.name == NULL) { rtems_set_errno_and_return_minus_one(ENOMEM); } /* * Create a new link node. - * - * NOTE: Coverity CID 22 notes this as a resource leak. - * While technically not a leak, it indicated that IMFS_create_node - * was ONLY passed a NULL when we created the root node. We - * added a new IMFS_create_root_node() so this path no longer - * existed. The result was simpler code which should not have - * this path. */ new_node = IMFS_create_node( - parent_loc, + parentloc, IMFS_SYM_LINK, - new_name, + name, + namelen, ( S_IFLNK | ( S_IRWXU | S_IRWXG | S_IRWXO )), &info ); diff --git a/cpukit/libfs/src/imfs/imfs_unlink.c b/cpukit/libfs/src/imfs/imfs_unlink.c deleted file mode 100644 index 0ec176ed03..0000000000 --- a/cpukit/libfs/src/imfs/imfs_unlink.c +++ /dev/null @@ -1,82 +0,0 @@ -/* - * IMFS_unlink - * - * Routine to remove a link node from the tree. - * - * COPYRIGHT (c) 1989-1999. - * On-Line Applications Research Corporation (OAR). - * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rtems.com/license/LICENSE. - * - * $Id$ - */ - -#if HAVE_CONFIG_H -#include "config.h" -#endif - -#include <errno.h> -#include <stdlib.h> - -#include "imfs.h" -#include <rtems/libio_.h> -#include <rtems/seterr.h> - -int IMFS_unlink( - rtems_filesystem_location_info_t *parentloc, /* IN */ - rtems_filesystem_location_info_t *loc /* IN */ -) -{ - IMFS_jnode_t *node; - rtems_filesystem_location_info_t the_link; - int result = 0; - - node = loc->node_access; - - /* - * Decrement the link counter of node pointed to and free the - * space. - */ - - /* - * If this is the last last pointer to the node - * free the node. - */ - - if ( node->type == IMFS_HARD_LINK ) { - - if ( !node->info.hard_link.link_node ) - rtems_set_errno_and_return_minus_one( EINVAL ); - - the_link = *loc; - the_link.node_access = node->info.hard_link.link_node; - IMFS_Set_handlers( &the_link ); - - /* - * If removing the last hard link to a node, then we need - * to remove the node that is a link and the node itself. - */ - - if ( node->info.hard_link.link_node->st_nlink == 1) - { - result = (*the_link.handlers->rmnod_h)( parentloc, &the_link ); - if ( result != 0 ) - return -1; - } - else - { - node->info.hard_link.link_node->st_nlink --; - IMFS_update_ctime( node->info.hard_link.link_node ); - } - } - - /* - * Now actually free the node we were asked to free. - */ - - result = (*loc->handlers->rmnod_h)( parentloc, loc ); - - return result; -} diff --git a/cpukit/libfs/src/imfs/imfs_unmount.c b/cpukit/libfs/src/imfs/imfs_unmount.c index ee1482bfa5..47acec9320 100644 --- a/cpukit/libfs/src/imfs/imfs_unmount.c +++ b/cpukit/libfs/src/imfs/imfs_unmount.c @@ -1,17 +1,12 @@ /* * IMFS_unmount * - * This routine will look at a mount table entry that we are going to - * add to the mount table. If the mount point - * rtems_filesystem_location_info_t struct refers to a node that is a - * directory that has a file system mounted on it, the node will be - * marked as a mount point by * setting its directory.mt_fs pointer - * to NULL. This indicates that a directory is no longer mounted on - * this node. - * * COPYRIGHT (c) 1989-1999. * On-Line Applications Research Corporation (OAR). * + * Modifications to support reference counting in the file system are + * Copyright (c) 2012 embedded brains GmbH. + * * The license and distribution terms for this file may be * found in the file LICENSE in this distribution or at * http://www.rtems.com/license/LICENSE. @@ -20,43 +15,27 @@ */ #if HAVE_CONFIG_H -#include "config.h" + #include "config.h" #endif -#include <errno.h> - #include "imfs.h" -#include <rtems/libio_.h> -#include <rtems/seterr.h> -int IMFS_unmount( - rtems_filesystem_mount_table_entry_t *mt_entry -) +int IMFS_unmount( rtems_filesystem_mount_table_entry_t *mt_entry ) { - IMFS_jnode_t *node; - - node = mt_entry->mt_point_node.node_access; - - /* - * Is the node that we are mounting onto a directory node ? - */ - - if ( node->type != IMFS_DIRECTORY ) - rtems_set_errno_and_return_minus_one( ENOTDIR ); - - /* - * Did the node indicate that there was a directory mounted here? - */ - - if ( node->info.directory.mt_fs == NULL ) - rtems_set_errno_and_return_minus_one( EINVAL ); /* XXX */ - - /* - * Set the mt_fs pointer to indicate that there is no longer - * a file system mounted to this point. - */ - - node->info.directory.mt_fs = NULL; - - return 0; + int rv = 0; + IMFS_jnode_t *node = mt_entry->mt_point_node->location.node_access; + + if ( node->type == IMFS_DIRECTORY ) { + if ( node->info.directory.mt_fs == mt_entry ) { + node->info.directory.mt_fs = NULL; + } else { + errno = EINVAL; + rv = -1; + } + } else { + errno = ENOTDIR; + rv = -1; + } + + return rv; } diff --git a/cpukit/libfs/src/imfs/imfs_utime.c b/cpukit/libfs/src/imfs/imfs_utime.c index 2867e13ed6..b16af11b30 100644 --- a/cpukit/libfs/src/imfs/imfs_utime.c +++ b/cpukit/libfs/src/imfs/imfs_utime.c @@ -15,24 +15,22 @@ */ #if HAVE_CONFIG_H -#include "config.h" + #include "config.h" #endif -#include <errno.h> -#include <sys/time.h> - -#include <rtems/libio_.h> #include "imfs.h" +#include <sys/time.h> + int IMFS_utime( - rtems_filesystem_location_info_t *pathloc, /* IN */ - time_t actime, /* IN */ - time_t modtime /* IN */ + const rtems_filesystem_location_info_t *loc, + time_t actime, + time_t modtime ) { IMFS_jnode_t *the_jnode; - the_jnode = (IMFS_jnode_t *) pathloc->node_access; + the_jnode = (IMFS_jnode_t *) loc->node_access; the_jnode->stat_atime = actime; the_jnode->stat_mtime = modtime; diff --git a/cpukit/libfs/src/imfs/ioman.c b/cpukit/libfs/src/imfs/ioman.c index 0dce7e7239..c0dbee5d05 100644 --- a/cpukit/libfs/src/imfs/ioman.c +++ b/cpukit/libfs/src/imfs/ioman.c @@ -5,6 +5,9 @@ * COPYRIGHT (c) 1989-1999. * On-Line Applications Research Corporation (OAR). * + * Modifications to support reference counting in the file system are + * Copyright (c) 2012 embedded brains GmbH. + * * The license and distribution terms for this file may be * found in the file LICENSE in this distribution or at * http://www.rtems.com/license/LICENSE. @@ -13,19 +16,13 @@ */ #if HAVE_CONFIG_H -#include "config.h" + #include "config.h" #endif -#include <sys/types.h> #include <sys/stat.h> -#include <fcntl.h> -#include <unistd.h> #include <string.h> -#include <rtems.h> #include <rtems/libio_.h> -#include <rtems/seterr.h> -#include "imfs.h" /* * rtems_io_register_name @@ -52,42 +49,23 @@ rtems_status_code rtems_io_register_name( return RTEMS_SUCCESSFUL; } -/* - * rtems_io_lookup_name - * - * This version is reentrant. - * - * XXX - This is dependent upon IMFS and should not be. - * Suggest adding a filesystem routine to fill in the device_info. - */ - rtems_status_code rtems_io_lookup_name( const char *name, rtems_driver_name_t *device_info ) { - IMFS_jnode_t *the_jnode; - rtems_filesystem_location_info_t loc; - int result; - rtems_filesystem_node_types_t node_type; - - result = rtems_filesystem_evaluate_path( - name, strlen( name ), 0x00, &loc, true ); - the_jnode = loc.node_access; - - node_type = (*loc.ops->node_type_h)( &loc ); - - if ( (result != 0) || node_type != RTEMS_FILESYSTEM_DEVICE ) { - rtems_filesystem_freenode( &loc ); - return RTEMS_UNSATISFIED; + rtems_status_code sc = RTEMS_SUCCESSFUL; + struct stat st; + int rv = stat( name, &st ); + + if ( rv == 0 && S_ISCHR( st.st_mode ) ) { + device_info->device_name = name; + device_info->device_name_length = strlen( name ); + device_info->major = rtems_filesystem_dev_major_t( st.st_rdev ); + device_info->minor = rtems_filesystem_dev_minor_t( st.st_rdev ); + } else { + sc = RTEMS_UNSATISFIED; } - device_info->device_name = name; - device_info->device_name_length = strlen( name ); - device_info->major = the_jnode->info.device.major; - device_info->minor = the_jnode->info.device.minor; - - rtems_filesystem_freenode( &loc ); - - return RTEMS_SUCCESSFUL; + return sc; } diff --git a/cpukit/libfs/src/imfs/memfile.c b/cpukit/libfs/src/imfs/memfile.c index 35c1eee0ec..65810c0bca 100644 --- a/cpukit/libfs/src/imfs/memfile.c +++ b/cpukit/libfs/src/imfs/memfile.c @@ -18,18 +18,13 @@ */ #if HAVE_CONFIG_H -#include "config.h" + #include "config.h" #endif +#include "imfs.h" + #include <stdlib.h> #include <string.h> -#include <errno.h> - -#include <rtems.h> -#include <rtems/libio.h> -#include "imfs.h" -#include <rtems/libio_.h> -#include <rtems/seterr.h> #define MEMFILE_STATIC @@ -86,8 +81,8 @@ void memfile_free_block( int memfile_open( rtems_libio_t *iop, const char *pathname, - uint32_t flag, - uint32_t mode + int oflag, + mode_t mode ) { IMFS_jnode_t *the_jnode; diff --git a/cpukit/libfs/src/imfs/miniimfs_init.c b/cpukit/libfs/src/imfs/miniimfs_init.c index b43a5318e8..a4db968e3c 100644 --- a/cpukit/libfs/src/imfs/miniimfs_init.c +++ b/cpukit/libfs/src/imfs/miniimfs_init.c @@ -18,28 +18,29 @@ */ #if HAVE_CONFIG_H -#include "config.h" + #include "config.h" #endif -#include <rtems/libio_.h> - #include "imfs.h" static const rtems_filesystem_operations_table miniIMFS_ops = { - .evalpath_h = IMFS_eval_path, - .evalformake_h = IMFS_evaluate_for_make, + .lock_h = rtems_filesystem_default_lock, + .unlock_h = rtems_filesystem_default_unlock, + .eval_path_h = IMFS_eval_path, .link_h = rtems_filesystem_default_link, - .unlink_h = rtems_filesystem_default_unlink, + .are_nodes_equal_h = rtems_filesystem_default_are_nodes_equal, .node_type_h = IMFS_node_type, .mknod_h = IMFS_mknod, + .rmnod_h = IMFS_rmnod, + .fchmod_h = rtems_filesystem_default_fchmod, .chown_h = rtems_filesystem_default_chown, + .clonenod_h = rtems_filesystem_default_clonenode, .freenod_h = rtems_filesystem_default_freenode, .mount_h = IMFS_mount, .fsmount_me_h = miniIMFS_initialize, .unmount_h = rtems_filesystem_default_unmount, - .fsunmount_me_h = rtems_filesystem_default_unmount, + .fsunmount_me_h = rtems_filesystem_default_fsunmount, .utime_h = rtems_filesystem_default_utime, - .eval_link_h = rtems_filesystem_default_evaluate_link, .symlink_h = rtems_filesystem_default_symlink, .readlink_h = rtems_filesystem_default_readlink, .rename_h = rtems_filesystem_default_rename, @@ -54,8 +55,7 @@ int miniIMFS_initialize( return IMFS_initialize_support( mt_entry, &miniIMFS_ops, - &rtems_filesystem_handlers_default, /* for memfiles */ - &rtems_filesystem_handlers_default, /* for directories */ + &rtems_filesystem_handlers_default, /* for links */ &rtems_filesystem_handlers_default /* for fifos */ ); } |