summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSebastian Huber <sebastian.huber@embedded-brains.de>2012-02-24 17:08:06 +0100
committerSebastian Huber <sebastian.huber@embedded-brains.de>2012-03-13 12:24:16 +0100
commit699ac7c08f8e0f7f1a37144e9c316c0dd7a16175 (patch)
treef07bb6097b312586f45c0803c8d4a8464f8068a1
parentIMFS: New support functions (diff)
downloadrtems-699ac7c08f8e0f7f1a37144e9c316c0dd7a16175.tar.bz2
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.
-rw-r--r--cpukit/libfs/src/imfs/fifoimfs_init.c14
-rw-r--r--cpukit/libfs/src/imfs/imfs.h138
-rw-r--r--cpukit/libfs/src/imfs/imfs_creat.c138
-rw-r--r--cpukit/libfs/src/imfs/imfs_eval.c32
-rw-r--r--cpukit/libfs/src/imfs/imfs_fifo.c14
-rw-r--r--cpukit/libfs/src/imfs/imfs_handlers_device.c25
-rw-r--r--cpukit/libfs/src/imfs/imfs_handlers_directory.c45
-rw-r--r--cpukit/libfs/src/imfs/imfs_handlers_link.c69
-rw-r--r--cpukit/libfs/src/imfs/imfs_handlers_memfile.c22
-rw-r--r--cpukit/libfs/src/imfs/imfs_init.c14
-rw-r--r--cpukit/libfs/src/imfs/imfs_initsupp.c136
-rw-r--r--cpukit/libfs/src/imfs/imfs_rmnod.c65
-rw-r--r--cpukit/libfs/src/imfs/memfile.c6
-rw-r--r--cpukit/libfs/src/imfs/miniimfs_init.c16
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 <stdlib.h>
#include <string.h>
-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 <stdlib.h>
-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
);
}