summaryrefslogtreecommitdiffstats
path: root/cpukit/libfs
diff options
context:
space:
mode:
authorSebastian Huber <sebastian.huber@embedded-brains.de>2012-03-01 11:51:34 +0100
committerSebastian Huber <sebastian.huber@embedded-brains.de>2012-03-13 12:24:16 +0100
commitc5392ef924c0d6f024012f294f39fdb5c6ac2da8 (patch)
treeb69b8ab632efc02eb1336c054e4c33428decb2fb /cpukit/libfs
parentIMFS: Add and use node control (diff)
downloadrtems-c5392ef924c0d6f024012f294f39fdb5c6ac2da8.tar.bz2
IMFS: Add make generic node support
Generic nodes are an alternative to standard drivers in RTEMS. The handlers of a generic node are called with less overhead compared to the standard driver operations. The usage of file system node handlers enable more features like support for fsync() and fdatasync(). The generic nodes use the reference counting of the IMFS. This provides automatic node destruction when the last reference vanishes. Extend type IMFS_types_union by new type IMFS_generic_t. Extend enum IMFS_jnode_types_t by IMFS_GENERIC. Add functions o IMFS_make_generic_node(), o IMFS_is_imfs_instance(), o IMFS_generic_get_context_by_node(), o IMFS_generic_get_context_by_location(), and o IMFS_generic_get_context_by_iop(). New test fstests/fsimfsgeneric01.
Diffstat (limited to 'cpukit/libfs')
-rw-r--r--cpukit/libfs/Makefile.am1
-rw-r--r--cpukit/libfs/src/imfs/imfs.h46
-rw-r--r--cpukit/libfs/src/imfs/imfs_make_generic_node.c108
3 files changed, 155 insertions, 0 deletions
diff --git a/cpukit/libfs/Makefile.am b/cpukit/libfs/Makefile.am
index 342f5eb063..c629bc99a1 100644
--- a/cpukit/libfs/Makefile.am
+++ b/cpukit/libfs/Makefile.am
@@ -45,6 +45,7 @@ libimfs_a_SOURCES += src/imfs/deviceerrno.c src/imfs/deviceio.c \
src/imfs/imfs_creat.c src/imfs/imfs_debug.c src/imfs/imfs_directory.c \
src/imfs/imfs_eval.c src/imfs/imfs_fchmod.c \
src/imfs/imfs_fifo.c \
+ src/imfs/imfs_make_generic_node.c \
src/imfs/imfs_fsunmount.c \
src/imfs/imfs_handlers_device.c \
src/imfs/imfs_handlers_directory.c src/imfs/imfs_handlers_link.c \
diff --git a/cpukit/libfs/src/imfs/imfs.h b/cpukit/libfs/src/imfs/imfs.h
index ae247c5833..eca8824ca3 100644
--- a/cpukit/libfs/src/imfs/imfs.h
+++ b/cpukit/libfs/src/imfs/imfs.h
@@ -56,6 +56,10 @@ typedef struct {
pipe_control_t *pipe;
} IMFS_fifo_t;
+typedef struct {
+ void *context;
+} IMFS_generic_t;
+
/*
* IMFS "memfile" information
*
@@ -133,9 +137,11 @@ typedef enum {
IMFS_MEMORY_FILE = RTEMS_FILESYSTEM_MEMORY_FILE,
IMFS_LINEAR_FILE,
IMFS_FIFO,
+ IMFS_GENERIC,
IMFS_INVALID_NODE
} IMFS_jnode_types_t;
+/* The IMFS_GENERIC does not count */
#define IMFS_TYPE_COUNT (IMFS_FIFO + 1)
typedef union {
@@ -146,6 +152,7 @@ typedef union {
IMFS_memfile_t file;
IMFS_linearfile_t linearfile;
IMFS_fifo_t fifo;
+ IMFS_generic_t generic;
} IMFS_types_union;
typedef IMFS_jnode_t *(*IMFS_node_control_initialize)(
@@ -158,6 +165,11 @@ IMFS_jnode_t *IMFS_node_initialize_default(
const IMFS_types_union *info
);
+IMFS_jnode_t *IMFS_node_initialize_generic(
+ 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
@@ -370,6 +382,17 @@ extern IMFS_jnode_t *IMFS_create_node_with_control(
const IMFS_types_union *info
);
+extern bool IMFS_is_imfs_instance(
+ const rtems_filesystem_location_info_t *loc
+);
+
+extern int IMFS_make_generic_node(
+ const char *path,
+ mode_t mode,
+ const IMFS_node_control *node_control,
+ void *context
+);
+
extern int IMFS_mount(
rtems_filesystem_mount_table_entry_t *mt_entry /* IN */
);
@@ -573,6 +596,29 @@ static inline IMFS_jnode_t *IMFS_create_node(
);
}
+static inline void *IMFS_generic_get_context_by_node(
+ const IMFS_jnode_t *node
+)
+{
+ return node->info.generic.context;
+}
+
+static inline void *IMFS_generic_get_context_by_location(
+ const rtems_filesystem_location_info_t *loc
+)
+{
+ const IMFS_jnode_t *node = (const IMFS_jnode_t *) loc->node_access;
+
+ return IMFS_generic_get_context_by_node( node );
+}
+
+static inline void *IMFS_generic_get_context_by_iop(
+ const rtems_libio_t *iop
+)
+{
+ return IMFS_generic_get_context_by_location( &iop->pathinfo );
+}
+
#ifdef __cplusplus
}
#endif
diff --git a/cpukit/libfs/src/imfs/imfs_make_generic_node.c b/cpukit/libfs/src/imfs/imfs_make_generic_node.c
new file mode 100644
index 0000000000..5b7a7d9cec
--- /dev/null
+++ b/cpukit/libfs/src/imfs/imfs_make_generic_node.c
@@ -0,0 +1,108 @@
+/*
+ * Copyright (c) 2012 embedded brains GmbH. All rights reserved.
+ *
+ * embedded brains GmbH
+ * Obere Lagerstr. 30
+ * 82178 Puchheim
+ * Germany
+ * <rtems@embedded-brains.de>
+ *
+ * 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.
+ */
+
+#if HAVE_CONFIG_H
+ #include "config.h"
+#endif
+
+#include "imfs.h"
+
+IMFS_jnode_t *IMFS_node_initialize_generic(
+ IMFS_jnode_t *node,
+ const IMFS_types_union *info
+)
+{
+ node->info.generic.context = info->generic.context;
+
+ return node;
+}
+
+bool IMFS_is_imfs_instance(
+ const rtems_filesystem_location_info_t *loc
+)
+{
+ const char *type = loc->mt_entry->type;
+
+ return strcmp(type, RTEMS_FILESYSTEM_TYPE_IMFS) == 0
+ || strcmp(type, RTEMS_FILESYSTEM_TYPE_MINIIMFS) == 0;
+}
+
+int IMFS_make_generic_node(
+ const char *path,
+ mode_t mode,
+ const IMFS_node_control *node_control,
+ void *context
+)
+{
+ int rv = 0;
+
+ mode &= ~rtems_filesystem_umask;
+
+ switch (mode & S_IFMT) {
+ case S_IFBLK:
+ case S_IFCHR:
+ case S_IFIFO:
+ case S_IFREG:
+ break;
+ default:
+ errno = EINVAL;
+ rv = -1;
+ break;
+ }
+
+ if ( rv == 0 ) {
+ if ( node_control->imfs_type == IMFS_GENERIC ) {
+ rtems_filesystem_eval_path_context_t ctx;
+ int eval_flags = RTEMS_FS_FOLLOW_LINK
+ | RTEMS_FS_MAKE
+ | RTEMS_FS_EXCLUSIVE;
+ const rtems_filesystem_location_info_t *currentloc =
+ rtems_filesystem_eval_path_start( &ctx, path, eval_flags );
+
+ if ( IMFS_is_imfs_instance( currentloc ) ) {
+ IMFS_types_union info;
+ IMFS_jnode_t *new_node;
+
+ info.generic.context = context;
+ new_node = IMFS_create_node_with_control(
+ currentloc,
+ node_control,
+ rtems_filesystem_eval_path_get_token( &ctx ),
+ rtems_filesystem_eval_path_get_tokenlen( &ctx ),
+ mode,
+ &info
+ );
+
+ if ( new_node != NULL ) {
+ IMFS_jnode_t *parent = currentloc->node_access;
+
+ IMFS_update_ctime( parent );
+ IMFS_update_mtime( parent );
+ } else {
+ rv = -1;
+ }
+ } else {
+ rtems_filesystem_eval_path_error( &ctx, ENOTSUP );
+ rv = -1;
+ }
+
+ rtems_filesystem_eval_path_cleanup( &ctx );
+ } else {
+ errno = EINVAL;
+ rv = -1;
+ }
+ }
+
+ return rv;
+}