diff options
Diffstat (limited to 'cpukit/libfs/src')
-rw-r--r-- | cpukit/libfs/src/imfs/imfs.h | 46 | ||||
-rw-r--r-- | cpukit/libfs/src/imfs/imfs_make_generic_node.c | 108 |
2 files changed, 154 insertions, 0 deletions
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; +} |