From 699ac7c08f8e0f7f1a37144e9c316c0dd7a16175 Mon Sep 17 00:00:00 2001 From: Sebastian Huber Date: Fri, 24 Feb 2012 17:08:06 +0100 Subject: IMFS: Add and use node control Add and use structure IMFS_node_control with support functions. This helps to make high level functions independent of the node type and reduces the number of branches in the code. --- cpukit/libfs/src/imfs/fifoimfs_init.c | 14 ++- cpukit/libfs/src/imfs/imfs.h | 138 +++++++++++++++++------- cpukit/libfs/src/imfs/imfs_creat.c | 138 ++++++++---------------- cpukit/libfs/src/imfs/imfs_eval.c | 32 ------ cpukit/libfs/src/imfs/imfs_fifo.c | 14 ++- cpukit/libfs/src/imfs/imfs_handlers_device.c | 25 ++++- cpukit/libfs/src/imfs/imfs_handlers_directory.c | 45 +++++++- cpukit/libfs/src/imfs/imfs_handlers_link.c | 69 +++++++++++- cpukit/libfs/src/imfs/imfs_handlers_memfile.c | 22 +++- cpukit/libfs/src/imfs/imfs_init.c | 14 ++- cpukit/libfs/src/imfs/imfs_initsupp.c | 136 +++++++++++++---------- cpukit/libfs/src/imfs/imfs_rmnod.c | 65 ++--------- cpukit/libfs/src/imfs/memfile.c | 6 +- cpukit/libfs/src/imfs/miniimfs_init.c | 16 ++- 14 files changed, 419 insertions(+), 315 deletions(-) diff --git a/cpukit/libfs/src/imfs/fifoimfs_init.c b/cpukit/libfs/src/imfs/fifoimfs_init.c index 966e9e1dde..8ebdca3416 100644 --- a/cpukit/libfs/src/imfs/fifoimfs_init.c +++ b/cpukit/libfs/src/imfs/fifoimfs_init.c @@ -49,6 +49,17 @@ const rtems_filesystem_operations_table fifoIMFS_ops = { .statvfs_h = rtems_filesystem_default_statvfs }; +static const IMFS_node_control *const + IMFS_fifo_node_controls [IMFS_TYPE_COUNT] = { + [IMFS_DIRECTORY] = &IMFS_node_control_directory, + [IMFS_DEVICE] = &IMFS_node_control_device, + [IMFS_HARD_LINK] = &IMFS_node_control_hard_link, + [IMFS_SYM_LINK] = &IMFS_node_control_sym_link, + [IMFS_MEMORY_FILE] = &IMFS_node_control_memfile, + [IMFS_LINEAR_FILE] = &IMFS_node_control_linfile, + [IMFS_FIFO] = &IMFS_node_control_fifo +}; + int fifoIMFS_initialize( rtems_filesystem_mount_table_entry_t *mt_entry, const void *data @@ -57,7 +68,6 @@ int fifoIMFS_initialize( return IMFS_initialize_support( mt_entry, &fifoIMFS_ops, - &IMFS_link_handlers, - &IMFS_fifo_handlers + IMFS_fifo_node_controls ); } diff --git a/cpukit/libfs/src/imfs/imfs.h b/cpukit/libfs/src/imfs/imfs.h index 7c926a854e..ae247c5833 100644 --- a/cpukit/libfs/src/imfs/imfs.h +++ b/cpukit/libfs/src/imfs/imfs.h @@ -132,9 +132,12 @@ typedef enum { IMFS_SYM_LINK = RTEMS_FILESYSTEM_SYM_LINK, IMFS_MEMORY_FILE = RTEMS_FILESYSTEM_MEMORY_FILE, IMFS_LINEAR_FILE, - IMFS_FIFO + IMFS_FIFO, + IMFS_INVALID_NODE } IMFS_jnode_types_t; +#define IMFS_TYPE_COUNT (IMFS_FIFO + 1) + typedef union { IMFS_directory_t directory; IMFS_device_t device; @@ -145,6 +148,38 @@ typedef union { IMFS_fifo_t fifo; } IMFS_types_union; +typedef IMFS_jnode_t *(*IMFS_node_control_initialize)( + IMFS_jnode_t *node, + const IMFS_types_union *info +); + +IMFS_jnode_t *IMFS_node_initialize_default( + IMFS_jnode_t *node, + const IMFS_types_union *info +); + +typedef IMFS_jnode_t *(*IMFS_node_control_remove)( + IMFS_jnode_t *node, + const IMFS_jnode_t *root_node +); + +IMFS_jnode_t *IMFS_node_remove_default( + IMFS_jnode_t *node, + const IMFS_jnode_t *root_node +); + +typedef IMFS_jnode_t *(*IMFS_node_control_destroy)( IMFS_jnode_t *node ); + +IMFS_jnode_t *IMFS_node_destroy_default( IMFS_jnode_t *node ); + +typedef struct { + IMFS_jnode_types_t imfs_type; + const rtems_filesystem_file_handlers_r *handlers; + IMFS_node_control_initialize node_initialize; + IMFS_node_control_remove node_remove; + IMFS_node_control_destroy node_destroy; +} IMFS_node_control; + /* * Major device number for the IMFS. This is not a real device number because * the IMFS is just a file system and does not have a driver. @@ -176,7 +211,7 @@ struct IMFS_jnode_tt { time_t stat_atime; /* Time of last access */ time_t stat_mtime; /* Time of last modification */ time_t stat_ctime; /* Time of last status change */ - IMFS_jnode_types_t type; /* Type of this entry */ + const IMFS_node_control *control; IMFS_types_union info; }; @@ -210,25 +245,28 @@ struct IMFS_jnode_tt { } while (0) typedef struct { - int instance; - 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; + int instance; + ino_t ino_count; + const IMFS_node_control *node_controls [IMFS_TYPE_COUNT]; } IMFS_fs_info_t; /* * Shared Data */ -extern const rtems_filesystem_file_handlers_r IMFS_directory_handlers; -extern const rtems_filesystem_file_handlers_r IMFS_device_handlers; -extern const rtems_filesystem_file_handlers_r IMFS_link_handlers; -extern const rtems_filesystem_file_handlers_r IMFS_memfile_handlers; -extern const rtems_filesystem_file_handlers_r IMFS_fifo_handlers; -extern const rtems_filesystem_operations_table IMFS_ops; -extern const rtems_filesystem_operations_table fifoIMFS_ops; +extern const IMFS_node_control IMFS_node_control_directory; +extern const IMFS_node_control IMFS_node_control_device; +extern const IMFS_node_control IMFS_node_control_hard_link; +extern const IMFS_node_control IMFS_node_control_sym_link; +extern const IMFS_node_control IMFS_node_control_memfile; +extern const IMFS_node_control IMFS_node_control_linfile; +extern const IMFS_node_control IMFS_node_control_fifo; +extern const IMFS_node_control IMFS_node_control_default; + +extern const rtems_filesystem_operations_table miniIMFS_ops; +extern const rtems_filesystem_operations_table IMFS_ops; +extern const rtems_filesystem_operations_table fifoIMFS_ops; + extern const rtems_filesystem_limits_and_options_t IMFS_LIMITS_AND_OPTIONS; /* @@ -251,10 +289,9 @@ 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 *link_handlers, - const rtems_filesystem_file_handlers_r *fifo_handlers + rtems_filesystem_mount_table_entry_t *mt_entry, + const rtems_filesystem_operations_table *op_table, + const IMFS_node_control *const node_controls [IMFS_TYPE_COUNT] ); extern void IMFS_fsunmount( @@ -290,8 +327,6 @@ extern int IMFS_stat( struct stat *buf ); -extern void IMFS_Set_handlers( rtems_filesystem_location_info_t *loc ); - extern void IMFS_eval_path( rtems_filesystem_eval_path_context_t *ctx ); @@ -318,21 +353,21 @@ extern int IMFS_mknod( ); 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 */ + IMFS_fs_info_t *fs_info, + const IMFS_node_control *node_control, + const char *name, + size_t namelen, + mode_t mode, + const IMFS_types_union *info ); -extern IMFS_jnode_t *IMFS_create_root_node(void); - -extern IMFS_jnode_t *IMFS_create_node( - 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 IMFS_jnode_t *IMFS_create_node_with_control( + const rtems_filesystem_location_info_t *parentloc, + const IMFS_node_control *node_control, + const char *name, + size_t namelen, + mode_t mode, + const IMFS_types_union *info ); extern int IMFS_mount( @@ -343,7 +378,7 @@ extern int IMFS_unmount( rtems_filesystem_mount_table_entry_t *mt_entry /* IN */ ); -extern int IMFS_memfile_remove( +extern IMFS_jnode_t *IMFS_memfile_remove( IMFS_jnode_t *the_jnode /* IN/OUT */ ); @@ -483,6 +518,13 @@ extern int IMFS_rmnod( #define IMFS_assert(_x) #endif +static inline void IMFS_Set_handlers( rtems_filesystem_location_info_t *loc ) +{ + IMFS_jnode_t *node = (IMFS_jnode_t *) loc->node_access; + + loc->handlers = node->control->handlers; +} + static inline void IMFS_add_to_directory( IMFS_jnode_t *dir, IMFS_jnode_t *node @@ -501,12 +543,34 @@ static inline void IMFS_remove_from_directory( IMFS_jnode_t *node ) static inline IMFS_jnode_types_t IMFS_type( const IMFS_jnode_t *node ) { - return node->type; + return node->control->imfs_type; } static inline bool IMFS_is_directory( const IMFS_jnode_t *node ) { - return node->type == IMFS_DIRECTORY; + return node->control->imfs_type == IMFS_DIRECTORY; +} + +static inline IMFS_jnode_t *IMFS_create_node( + const rtems_filesystem_location_info_t *parentloc, + IMFS_jnode_types_t type, + const char *name, + size_t namelen, + mode_t mode, + const IMFS_types_union *info +) +{ + const IMFS_fs_info_t *fs_info = + (const IMFS_fs_info_t *) parentloc->mt_entry->fs_info; + + return IMFS_create_node_with_control( + parentloc, + fs_info->node_controls [type], + name, + namelen, + mode, + info + ); } #ifdef __cplusplus diff --git a/cpukit/libfs/src/imfs/imfs_creat.c b/cpukit/libfs/src/imfs/imfs_creat.c index 2fe3c7dba1..103320fe85 100644 --- a/cpukit/libfs/src/imfs/imfs_creat.c +++ b/cpukit/libfs/src/imfs/imfs_creat.c @@ -22,83 +22,13 @@ #include #include -static void IMFS_initialize_directory( IMFS_jnode_t *dir ) -{ - rtems_chain_initialize_empty( &dir->info.directory.Entries ); -} - -/* - * Create an IMFS filesystem node of an arbitrary type that is NOT - * the root directory node. - */ -IMFS_jnode_t *IMFS_create_node( - 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; - - parent = parent_loc->node_access; - fs_info = parent_loc->mt_entry->fs_info; - - /* - * Allocate filesystem node and fill in basic information - */ - node = IMFS_allocate_node( type, name, namelen, mode ); - if ( !node ) - return NULL; - - /* - * Set the type specific information - */ - if ( type == IMFS_DIRECTORY ) { - IMFS_initialize_directory( node ); - } else if ( type == IMFS_HARD_LINK ) { - node->info.hard_link.link_node = info->hard_link.link_node; - } else if ( type == IMFS_SYM_LINK ) { - node->info.sym_link.name = info->sym_link.name; - } else if ( type == IMFS_DEVICE ) { - node->info.device.major = info->device.major; - node->info.device.minor = info->device.minor; - } else if ( type == IMFS_LINEAR_FILE ) { - node->info.linearfile.size = 0; - node->info.linearfile.direct = 0; - } else if ( type == IMFS_MEMORY_FILE ) { - node->info.file.size = 0; - node->info.file.indirect = 0; - node->info.file.doubly_indirect = 0; - node->info.file.triply_indirect = 0; - } else if ( type == IMFS_FIFO ) { - node->info.fifo.pipe = NULL; - } else { - IMFS_assert(0); - } - - /* - * This node MUST have a parent, so put it in that directory list. - */ - IMFS_assert( parent != NULL ); - IMFS_add_to_directory( parent, node ); - - node->st_ino = ++fs_info->ino_count; - - return node; -} - -/* - * Allocate filesystem node and fill in basic information - */ IMFS_jnode_t *IMFS_allocate_node( - IMFS_jnode_types_t type, - const char *name, - size_t namelen, - mode_t mode + IMFS_fs_info_t *fs_info, + const IMFS_node_control *node_control, + const char *name, + size_t namelen, + mode_t mode, + const IMFS_types_union *info ) { IMFS_jnode_t *node; @@ -110,6 +40,8 @@ IMFS_jnode_t *IMFS_allocate_node( return NULL; } + gettimeofday( &tv, 0 ); + /* * Allocate an IMFS jnode */ @@ -125,9 +57,9 @@ IMFS_jnode_t *IMFS_allocate_node( */ node->reference_count = 1; node->st_nlink = 1; - node->type = type; memcpy( node->name, name, namelen ); node->name [namelen] = '\0'; + node->control = node_control; /* * Fill in the mode and permission information for the jnode structure. @@ -144,32 +76,48 @@ IMFS_jnode_t *IMFS_allocate_node( /* * Now set all the times. */ - gettimeofday( &tv, 0 ); node->stat_atime = (time_t) tv.tv_sec; node->stat_mtime = (time_t) tv.tv_sec; node->stat_ctime = (time_t) tv.tv_sec; + node->st_ino = ++fs_info->ino_count; - return node; + return (*node->control->node_initialize)( node, info ); } -IMFS_jnode_t *IMFS_create_root_node(void) +/* + * Create an IMFS filesystem node of an arbitrary type that is NOT + * the root directory node. + */ +IMFS_jnode_t *IMFS_create_node_with_control( + const rtems_filesystem_location_info_t *parentloc, + const IMFS_node_control *node_control, + const char *name, + size_t namelen, + mode_t mode, + const IMFS_types_union *info +) { - IMFS_jnode_t *node; - - /* - * Allocate filesystem node and fill in basic information - */ - node = IMFS_allocate_node( IMFS_DIRECTORY, "", 0, (S_IFDIR | 0755) ); - if ( !node ) - return NULL; - - /* - * Set the type specific information - * - * NOTE: Root node is always a directory. - */ - IMFS_initialize_directory( node ); + IMFS_fs_info_t *fs_info = parentloc->mt_entry->fs_info; + IMFS_jnode_t *node = IMFS_allocate_node( + fs_info, + node_control, + name, + namelen, + mode, + info + ); + + if ( node != NULL ) { + IMFS_jnode_t *parent = parentloc->node_access; + + /* + * This node MUST have a parent, so put it in that directory list. + */ + IMFS_assert( parent != NULL ); + IMFS_add_to_directory( parent, node ); + } return node; } + diff --git a/cpukit/libfs/src/imfs/imfs_eval.c b/cpukit/libfs/src/imfs/imfs_eval.c index a65569a470..4fcfd67ee9 100644 --- a/cpukit/libfs/src/imfs/imfs_eval.c +++ b/cpukit/libfs/src/imfs/imfs_eval.c @@ -18,38 +18,6 @@ #include "imfs.h" -void IMFS_Set_handlers( rtems_filesystem_location_info_t *loc ) -{ - 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; - - switch ( node->type ) { - case IMFS_DIRECTORY: - handlers = &IMFS_directory_handlers; - break; - case IMFS_DEVICE: - handlers = &IMFS_device_handlers; - break; - case IMFS_HARD_LINK: - case IMFS_SYM_LINK: - handlers = fs_info->link_handlers; - break; - case IMFS_MEMORY_FILE: - case IMFS_LINEAR_FILE: - handlers = &IMFS_memfile_handlers; - break; - case IMFS_FIFO: - handlers = fs_info->fifo_handlers; - break; - default: - IMFS_assert( 0 ); - break; - } - - loc->handlers = handlers; -} - static bool IMFS_eval_is_directory( rtems_filesystem_eval_path_context_t *ctx, void *arg diff --git a/cpukit/libfs/src/imfs/imfs_fifo.c b/cpukit/libfs/src/imfs/imfs_fifo.c index dc623629b6..616025669a 100644 --- a/cpukit/libfs/src/imfs/imfs_fifo.c +++ b/cpukit/libfs/src/imfs/imfs_fifo.c @@ -119,11 +119,7 @@ static off_t IMFS_fifo_lseek( IMFS_FIFO_RETURN(err); } -/* - * Handler table for IMFS FIFO nodes - */ - -const rtems_filesystem_file_handlers_r IMFS_fifo_handlers = { +static const rtems_filesystem_file_handlers_r IMFS_fifo_handlers = { IMFS_fifo_open, IMFS_fifo_close, IMFS_fifo_read, @@ -136,3 +132,11 @@ const rtems_filesystem_file_handlers_r IMFS_fifo_handlers = { rtems_filesystem_default_fsync_or_fdatasync, rtems_filesystem_default_fcntl }; + +const IMFS_node_control IMFS_node_control_fifo = { + .imfs_type = IMFS_FIFO, + .handlers = &IMFS_fifo_handlers, + .node_initialize = IMFS_node_initialize_default, + .node_remove = IMFS_node_remove_default, + .node_destroy = IMFS_node_destroy_default +}; diff --git a/cpukit/libfs/src/imfs/imfs_handlers_device.c b/cpukit/libfs/src/imfs/imfs_handlers_device.c index df9ea1ae70..625bc39884 100644 --- a/cpukit/libfs/src/imfs/imfs_handlers_device.c +++ b/cpukit/libfs/src/imfs/imfs_handlers_device.c @@ -17,11 +17,7 @@ #include "imfs.h" -/* - * Handler table for IMFS device nodes - */ - -const rtems_filesystem_file_handlers_r IMFS_device_handlers = { +static const rtems_filesystem_file_handlers_r IMFS_device_handlers = { device_open, device_close, device_read, @@ -34,3 +30,22 @@ const rtems_filesystem_file_handlers_r IMFS_device_handlers = { rtems_filesystem_default_fsync_or_fdatasync, rtems_filesystem_default_fcntl }; + +static IMFS_jnode_t *IMFS_node_initialize_device( + IMFS_jnode_t *node, + const IMFS_types_union *info +) +{ + node->info.device.major = info->device.major; + node->info.device.minor = info->device.minor; + + return node; +} + +const IMFS_node_control IMFS_node_control_device = { + .imfs_type = IMFS_DEVICE, + .handlers = &IMFS_device_handlers, + .node_initialize = IMFS_node_initialize_device, + .node_remove = IMFS_node_remove_default, + .node_destroy = IMFS_node_destroy_default +}; diff --git a/cpukit/libfs/src/imfs/imfs_handlers_directory.c b/cpukit/libfs/src/imfs/imfs_handlers_directory.c index 842f098fc8..56b1461648 100644 --- a/cpukit/libfs/src/imfs/imfs_handlers_directory.c +++ b/cpukit/libfs/src/imfs/imfs_handlers_directory.c @@ -17,11 +17,7 @@ #include "imfs.h" -/* - * Set of operations handlers for operations on directories. - */ - -const rtems_filesystem_file_handlers_r IMFS_directory_handlers = { +static const rtems_filesystem_file_handlers_r IMFS_directory_handlers = { rtems_filesystem_default_open, rtems_filesystem_default_close, imfs_dir_read, @@ -34,3 +30,42 @@ const rtems_filesystem_file_handlers_r IMFS_directory_handlers = { rtems_filesystem_default_fsync_or_fdatasync_success, rtems_filesystem_default_fcntl }; + +static IMFS_jnode_t *IMFS_node_initialize_directory( + IMFS_jnode_t *node, + const IMFS_types_union *info +) +{ + rtems_chain_initialize_empty( &node->info.directory.Entries ); + + return node; +} + +static bool IMFS_is_mount_point( const IMFS_jnode_t *node ) +{ + return node->info.directory.mt_fs != NULL; +} + +static IMFS_jnode_t *IMFS_node_remove_directory( + IMFS_jnode_t *node, + const IMFS_jnode_t *root_node +) +{ + if ( !rtems_chain_is_empty( &node->info.directory.Entries ) ) { + errno = ENOTEMPTY; + node = NULL; + } else if ( node == root_node || IMFS_is_mount_point( node ) ) { + errno = EBUSY; + node = NULL; + } + + return node; +} + +const IMFS_node_control IMFS_node_control_directory = { + .imfs_type = IMFS_DIRECTORY, + .handlers = &IMFS_directory_handlers, + .node_initialize = IMFS_node_initialize_directory, + .node_remove = IMFS_node_remove_directory, + .node_destroy = IMFS_node_destroy_default +}; diff --git a/cpukit/libfs/src/imfs/imfs_handlers_link.c b/cpukit/libfs/src/imfs/imfs_handlers_link.c index fd68f77eef..08dddb701d 100644 --- a/cpukit/libfs/src/imfs/imfs_handlers_link.c +++ b/cpukit/libfs/src/imfs/imfs_handlers_link.c @@ -17,11 +17,9 @@ #include "imfs.h" -/* - * Handler table for IMFS device nodes - */ +#include -const rtems_filesystem_file_handlers_r IMFS_link_handlers = { +static const rtems_filesystem_file_handlers_r IMFS_link_handlers = { rtems_filesystem_default_open, rtems_filesystem_default_close, rtems_filesystem_default_read, @@ -34,3 +32,66 @@ const rtems_filesystem_file_handlers_r IMFS_link_handlers = { rtems_filesystem_default_fsync_or_fdatasync, rtems_filesystem_default_fcntl }; + +static IMFS_jnode_t *IMFS_node_initialize_hard_link( + IMFS_jnode_t *node, + const IMFS_types_union *info +) +{ + node->info.hard_link.link_node = info->hard_link.link_node; + + return node; +} + +static IMFS_jnode_t *IMFS_node_remove_hard_link( + IMFS_jnode_t *node, + const IMFS_jnode_t *root_node +) +{ + IMFS_jnode_t *target = node->info.hard_link.link_node; + + if ( target->st_nlink == 1) { + target = (*target->control->node_remove)( target, root_node ); + if ( target == NULL ) { + node = NULL; + } + } else { + --target->st_nlink; + IMFS_update_ctime( target ); + } + + return node; +} + +const IMFS_node_control IMFS_node_control_hard_link = { + .imfs_type = IMFS_HARD_LINK, + .handlers = &IMFS_link_handlers, + .node_initialize = IMFS_node_initialize_hard_link, + .node_remove = IMFS_node_remove_hard_link, + .node_destroy = IMFS_node_destroy_default +}; + +static IMFS_jnode_t *IMFS_node_initialize_sym_link( + IMFS_jnode_t *node, + const IMFS_types_union *info +) +{ + node->info.sym_link.name = info->sym_link.name; + + return node; +} + +static IMFS_jnode_t *IMFS_node_destroy_sym_link( IMFS_jnode_t *node ) +{ + free( node->info.sym_link.name ); + + return node; +} + +const IMFS_node_control IMFS_node_control_sym_link = { + .imfs_type = IMFS_SYM_LINK, + .handlers = &IMFS_link_handlers, + .node_initialize = IMFS_node_initialize_sym_link, + .node_remove = IMFS_node_remove_default, + .node_destroy = IMFS_node_destroy_sym_link +}; diff --git a/cpukit/libfs/src/imfs/imfs_handlers_memfile.c b/cpukit/libfs/src/imfs/imfs_handlers_memfile.c index 10cba9477b..0e32291533 100644 --- a/cpukit/libfs/src/imfs/imfs_handlers_memfile.c +++ b/cpukit/libfs/src/imfs/imfs_handlers_memfile.c @@ -17,11 +17,7 @@ #include "imfs.h" -/* - * Set of operations handlers for operations on memfile entities. - */ - -const rtems_filesystem_file_handlers_r IMFS_memfile_handlers = { +static const rtems_filesystem_file_handlers_r IMFS_memfile_handlers = { memfile_open, rtems_filesystem_default_close, memfile_read, @@ -34,3 +30,19 @@ const rtems_filesystem_file_handlers_r IMFS_memfile_handlers = { rtems_filesystem_default_fsync_or_fdatasync_success, rtems_filesystem_default_fcntl }; + +const IMFS_node_control IMFS_node_control_memfile = { + .imfs_type = IMFS_MEMORY_FILE, + .handlers = &IMFS_memfile_handlers, + .node_initialize = IMFS_node_initialize_default, + .node_remove = IMFS_node_remove_default, + .node_destroy = IMFS_memfile_remove +}; + +const IMFS_node_control IMFS_node_control_linfile = { + .imfs_type = IMFS_LINEAR_FILE, + .handlers = &IMFS_memfile_handlers, + .node_initialize = IMFS_node_initialize_default, + .node_remove = IMFS_node_remove_default, + .node_destroy = IMFS_node_destroy_default +}; diff --git a/cpukit/libfs/src/imfs/imfs_init.c b/cpukit/libfs/src/imfs/imfs_init.c index 8b4db45019..6b2524e5d3 100644 --- a/cpukit/libfs/src/imfs/imfs_init.c +++ b/cpukit/libfs/src/imfs/imfs_init.c @@ -47,6 +47,17 @@ const rtems_filesystem_operations_table IMFS_ops = { .statvfs_h = rtems_filesystem_default_statvfs }; +static const IMFS_node_control *const + IMFS_node_controls [IMFS_TYPE_COUNT] = { + [IMFS_DIRECTORY] = &IMFS_node_control_directory, + [IMFS_DEVICE] = &IMFS_node_control_device, + [IMFS_HARD_LINK] = &IMFS_node_control_hard_link, + [IMFS_SYM_LINK] = &IMFS_node_control_sym_link, + [IMFS_MEMORY_FILE] = &IMFS_node_control_memfile, + [IMFS_LINEAR_FILE] = &IMFS_node_control_linfile, + [IMFS_FIFO] = &IMFS_node_control_default +}; + int IMFS_initialize( rtems_filesystem_mount_table_entry_t *mt_entry, const void *data @@ -55,7 +66,6 @@ int IMFS_initialize( return IMFS_initialize_support( mt_entry, &IMFS_ops, - &IMFS_link_handlers, - &rtems_filesystem_handlers_default /* for fifos */ + IMFS_node_controls ); } diff --git a/cpukit/libfs/src/imfs/imfs_initsupp.c b/cpukit/libfs/src/imfs/imfs_initsupp.c index 042995b878..d480b13480 100644 --- a/cpukit/libfs/src/imfs/imfs_initsupp.c +++ b/cpukit/libfs/src/imfs/imfs_initsupp.c @@ -50,61 +50,59 @@ static int IMFS_determine_bytes_per_block( return 0; } - -/* - * IMFS_initialize - */ 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 *link_handlers, - const rtems_filesystem_file_handlers_r *fifo_handlers + rtems_filesystem_mount_table_entry_t *mt_entry, + const rtems_filesystem_operations_table *op_table, + const IMFS_node_control *const node_controls [IMFS_TYPE_COUNT] ) { - static int imfs_instance; - IMFS_fs_info_t *fs_info; - IMFS_jnode_t *jnode; - - /* - * determine/check value for imfs_memfile_bytes_per_block - */ - IMFS_determine_bytes_per_block(&imfs_memfile_bytes_per_block, - imfs_rq_memfile_bytes_per_block, - IMFS_MEMFILE_DEFAULT_BYTES_PER_BLOCK); - - /* - * Create the root node - * - * NOTE: UNIX root is 755 and owned by root/root (0/0). - */ - 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; - - /* - * Create custom file system data. - */ - fs_info = calloc( 1, sizeof( IMFS_fs_info_t ) ); - if ( !fs_info ) { - free(temp_mt_entry->mt_fs_root->location.node_access); - rtems_set_errno_and_return_minus_one(ENOMEM); + static int imfs_instance; + + int rv = 0; + IMFS_fs_info_t *fs_info = calloc( 1, sizeof( *fs_info ) ); + + if ( fs_info != NULL ) { + IMFS_jnode_t *root_node; + + fs_info->instance = imfs_instance++; + memcpy( + fs_info->node_controls, + node_controls, + sizeof( fs_info->node_controls ) + ); + + root_node = IMFS_allocate_node( + fs_info, + fs_info->node_controls [IMFS_DIRECTORY], + "", + 0, + (S_IFDIR | 0755), + NULL + ); + if ( root_node != NULL ) { + mt_entry->fs_info = fs_info; + mt_entry->pathconf_limits_and_options = IMFS_LIMITS_AND_OPTIONS; + mt_entry->mt_fs_root->location.node_access = root_node; + mt_entry->mt_fs_root->location.ops = op_table; + IMFS_Set_handlers( &mt_entry->mt_fs_root->location ); + } else { + errno = ENOMEM; + rv = -1; + } + } else { + errno = ENOMEM; + rv = -1; } - temp_mt_entry->fs_info = fs_info; - - /* - * Set st_ino for the root to 1. - */ - - fs_info->instance = imfs_instance++; - fs_info->ino_count = 1; - fs_info->link_handlers = link_handlers; - fs_info->fifo_handlers = fifo_handlers; - jnode = temp_mt_entry->mt_fs_root->location.node_access; - jnode->st_ino = fs_info->ino_count; + if ( rv == 0 ) { + IMFS_determine_bytes_per_block( + &imfs_memfile_bytes_per_block, + imfs_rq_memfile_bytes_per_block, + IMFS_MEMFILE_DEFAULT_BYTES_PER_BLOCK + ); + } - return 0; + return rv; } int IMFS_node_clone( rtems_filesystem_location_info_t *loc ) @@ -120,16 +118,7 @@ void IMFS_node_destroy( IMFS_jnode_t *node ) { IMFS_assert( node->reference_count == 0 ); - switch ( node->type ) { - case IMFS_MEMORY_FILE: - IMFS_memfile_remove( node ); - break; - case IMFS_SYM_LINK: - free( node->info.sym_link.name ); - break; - default: - break; - } + node = (*node->control->node_destroy)( node ); free( node ); } @@ -144,3 +133,32 @@ void IMFS_node_free( const rtems_filesystem_location_info_t *loc ) --node->reference_count; } } + +IMFS_jnode_t *IMFS_node_initialize_default( + IMFS_jnode_t *node, + const IMFS_types_union *info +) +{ + return node; +} + +IMFS_jnode_t *IMFS_node_remove_default( + IMFS_jnode_t *node, + const IMFS_jnode_t *root_node +) +{ + return node; +} + +IMFS_jnode_t *IMFS_node_destroy_default( IMFS_jnode_t *node ) +{ + return node; +} + +const IMFS_node_control IMFS_node_control_default = { + .imfs_type = IMFS_INVALID_NODE, + .handlers = &rtems_filesystem_handlers_default, + .node_initialize = IMFS_node_initialize_default, + .node_remove = IMFS_node_remove_default, + .node_destroy = IMFS_node_destroy_default +}; diff --git a/cpukit/libfs/src/imfs/imfs_rmnod.c b/cpukit/libfs/src/imfs/imfs_rmnod.c index 748a6f7365..2d7041e341 100644 --- a/cpukit/libfs/src/imfs/imfs_rmnod.c +++ b/cpukit/libfs/src/imfs/imfs_rmnod.c @@ -23,52 +23,6 @@ #include "imfs.h" -static int IMFS_rmnod_directory( - const rtems_filesystem_location_info_t *parentloc, - const rtems_filesystem_location_info_t *loc -) -{ - int rv = 0; - IMFS_jnode_t *node = loc->node_access; - - 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( const rtems_filesystem_location_info_t *parentloc, const rtems_filesystem_location_info_t *loc @@ -77,23 +31,18 @@ int IMFS_rmnod( int rv = 0; IMFS_jnode_t *node = loc->node_access; - 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 ) { + node = (*node->control->node_remove)( + node, + loc->mt_entry->mt_fs_root->location.node_access + ); + if ( node != NULL ) { --node->reference_count; --node->st_nlink; if ( node->Parent != NULL ) { IMFS_remove_from_directory( node ); } + } else { + rv = -1; } return rv; diff --git a/cpukit/libfs/src/imfs/memfile.c b/cpukit/libfs/src/imfs/memfile.c index aa3f8a71b4..d2cff01517 100644 --- a/cpukit/libfs/src/imfs/memfile.c +++ b/cpukit/libfs/src/imfs/memfile.c @@ -97,7 +97,7 @@ int memfile_open( uint32_t count = the_jnode->info.linearfile.size; const unsigned char *buffer = the_jnode->info.linearfile.direct; - the_jnode->type = IMFS_MEMORY_FILE; + the_jnode->control = &IMFS_node_control_memfile; the_jnode->info.file.size = 0; the_jnode->info.file.indirect = 0; the_jnode->info.file.doubly_indirect = 0; @@ -420,7 +420,7 @@ static void memfile_free_blocks_in_table( * Regardless until the IMFS implementation is proven, it * is better to stick to simple, easy to understand algorithms. */ -int IMFS_memfile_remove( +IMFS_jnode_t *IMFS_memfile_remove( IMFS_jnode_t *the_jnode ) { @@ -482,7 +482,7 @@ int IMFS_memfile_remove( (block_p **)&info->triply_indirect, to_free ); } - return 0; + return the_jnode; } /* diff --git a/cpukit/libfs/src/imfs/miniimfs_init.c b/cpukit/libfs/src/imfs/miniimfs_init.c index af791f5a31..d70f4db6ce 100644 --- a/cpukit/libfs/src/imfs/miniimfs_init.c +++ b/cpukit/libfs/src/imfs/miniimfs_init.c @@ -23,7 +23,7 @@ #include "imfs.h" -static const rtems_filesystem_operations_table miniIMFS_ops = { +const rtems_filesystem_operations_table miniIMFS_ops = { .lock_h = rtems_filesystem_default_lock, .unlock_h = rtems_filesystem_default_unlock, .eval_path_h = IMFS_eval_path, @@ -47,6 +47,17 @@ static const rtems_filesystem_operations_table miniIMFS_ops = { .statvfs_h = rtems_filesystem_default_statvfs }; +static const IMFS_node_control *const + IMFS_mini_node_controls [IMFS_TYPE_COUNT] = { + [IMFS_DIRECTORY] = &IMFS_node_control_directory, + [IMFS_DEVICE] = &IMFS_node_control_device, + [IMFS_HARD_LINK] = &IMFS_node_control_default, + [IMFS_SYM_LINK] = &IMFS_node_control_default, + [IMFS_MEMORY_FILE] = &IMFS_node_control_memfile, + [IMFS_LINEAR_FILE] = &IMFS_node_control_linfile, + [IMFS_FIFO] = &IMFS_node_control_default +}; + int miniIMFS_initialize( rtems_filesystem_mount_table_entry_t *mt_entry, const void *data @@ -55,7 +66,6 @@ int miniIMFS_initialize( return IMFS_initialize_support( mt_entry, &miniIMFS_ops, - &rtems_filesystem_handlers_default, /* for links */ - &rtems_filesystem_handlers_default /* for fifos */ + IMFS_mini_node_controls ); } -- cgit v1.2.3