summaryrefslogtreecommitdiffstats
path: root/cpukit/include/rtems/imfs.h
diff options
context:
space:
mode:
Diffstat (limited to 'cpukit/include/rtems/imfs.h')
-rw-r--r--cpukit/include/rtems/imfs.h946
1 files changed, 946 insertions, 0 deletions
diff --git a/cpukit/include/rtems/imfs.h b/cpukit/include/rtems/imfs.h
new file mode 100644
index 0000000000..fe3c5b12a9
--- /dev/null
+++ b/cpukit/include/rtems/imfs.h
@@ -0,0 +1,946 @@
+/**
+ * @file
+ *
+ * @brief Header File for the In-Memory File System
+ */
+
+/*
+ * COPYRIGHT (c) 1989-2011.
+ * 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.org/license/LICENSE.
+ */
+
+#ifndef _RTEMS_IMFS_H
+#define _RTEMS_IMFS_H
+
+#include <limits.h>
+
+#include <rtems/libio_.h>
+#include <rtems/pipe.h>
+
+/**
+ * @brief In-Memory File System Support.
+ *
+ * @defgroup IMFS In-Memory File System Support
+ *
+ * @ingroup FileSystemTypesAndMount
+ */
+/**@{*/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * Data types
+ */
+
+struct IMFS_jnode_tt;
+typedef struct IMFS_jnode_tt IMFS_jnode_t;
+
+/**
+ * IMFS "memfile" information
+ *
+ * The data structure for the in-memory "memfiles" is based on classic UNIX.
+ *
+ * block_ptr is a pointer to a block of IMFS_MEMFILE_BYTES_PER_BLOCK in
+ * length which could be data or a table of pointers to blocks.
+ *
+ * Setting IMFS_MEMFILE_BYTES_PER_BLOCK to different values has a significant
+ * impact on the maximum file size supported as well as the amount of
+ * memory wasted due to internal file fragmentation. The following
+ * is a list of maximum file sizes based on various settings
+ *
+ * @code
+ * max_filesize with blocks of 16 is 1,328
+ * max_filesize with blocks of 32 is 18,656
+ * max_filesize with blocks of 64 is 279,488
+ * max_filesize with blocks of 128 is 4,329,344
+ * max_filesize with blocks of 256 is 68,173,568
+ * max_filesize with blocks of 512 is 1,082,195,456
+ * @endcode
+ */
+#define IMFS_MEMFILE_DEFAULT_BYTES_PER_BLOCK 128
+ extern int imfs_rq_memfile_bytes_per_block;
+ extern int imfs_memfile_bytes_per_block;
+
+#define IMFS_MEMFILE_BYTES_PER_BLOCK imfs_memfile_bytes_per_block
+#define IMFS_MEMFILE_BLOCK_SLOTS \
+ (IMFS_MEMFILE_BYTES_PER_BLOCK / sizeof(void *))
+
+typedef uint8_t *block_p;
+typedef block_p *block_ptr;
+
+/*
+ * Important block numbers for "memfiles"
+ */
+#define FIRST_INDIRECT (0)
+#define LAST_INDIRECT (IMFS_MEMFILE_BLOCK_SLOTS - 1)
+
+#define FIRST_DOUBLY_INDIRECT (LAST_INDIRECT + 1)
+#define LAST_DOUBLY_INDIRECT \
+ (LAST_INDIRECT + \
+ (IMFS_MEMFILE_BLOCK_SLOTS * IMFS_MEMFILE_BLOCK_SLOTS))
+
+#define FIRST_TRIPLY_INDIRECT (LAST_DOUBLY_INDIRECT + 1)
+#define LAST_TRIPLY_INDIRECT \
+ (LAST_DOUBLY_INDIRECT +\
+ (IMFS_MEMFILE_BLOCK_SLOTS * \
+ IMFS_MEMFILE_BLOCK_SLOTS * IMFS_MEMFILE_BLOCK_SLOTS))
+
+#define IMFS_MEMFILE_MAXIMUM_SIZE \
+ (LAST_TRIPLY_INDIRECT * IMFS_MEMFILE_BYTES_PER_BLOCK)
+
+/** @} */
+
+/**
+ * @addtogroup IMFSGenericNodes
+ */
+/**@{*/
+
+/**
+ * @brief Initializes an IMFS node.
+ *
+ * @param[in] node The IMFS node.
+ * @param[in] arg The user provided argument pointer. It may contain node
+ * specific initialization information.
+ *
+ * @retval node Successful operation.
+ * @retval NULL An error occurred. The @c errno indicates the error. This
+ * will abort the make operation.
+ *
+ * @see IMFS_node_control, IMFS_node_initialize_default(), and
+ * IMFS_node_initialize_generic().
+ */
+typedef IMFS_jnode_t *(*IMFS_node_control_initialize)(
+ IMFS_jnode_t *node,
+ void *arg
+);
+
+/**
+ * @brief Returns the node and does nothing else.
+ *
+ * @param[in] node The IMFS node.
+ * @param[in] arg The user provided argument pointer. It is not used.
+ *
+ * @retval node Returns always the node passed as parameter.
+ *
+ * @see IMFS_node_control.
+ */
+IMFS_jnode_t *IMFS_node_initialize_default(
+ IMFS_jnode_t *node,
+ void *arg
+);
+
+IMFS_jnode_t *IMFS_node_initialize_directory(
+ IMFS_jnode_t *node,
+ void *arg
+);
+
+/**
+ * @brief Returns the node and sets the generic node context.
+ *
+ * @param[in] node The IMFS node.
+ * @param[in] arg The user provided argument pointer. It must contain the
+ * generic context.
+ *
+ * @retval node Returns always the node passed as parameter.
+ *
+ * @see IMFS_node_control.
+ */
+IMFS_jnode_t *IMFS_node_initialize_generic(
+ IMFS_jnode_t *node,
+ void *arg
+);
+
+/**
+ * @brief Prepares the removal of an IMFS node from its parent directory.
+ *
+ * @param[in] node The IMFS node.
+ *
+ * @retval node Successful operation.
+ * @retval NULL An error occurred. The @c errno indicates the error. This
+ * will abort the removal operation.
+ *
+ * @see IMFS_node_control and IMFS_node_remove_default().
+ */
+typedef IMFS_jnode_t *(*IMFS_node_control_remove)(
+ IMFS_jnode_t *node
+);
+
+/**
+ * @brief Returns the node and does nothing else.
+ *
+ * @param[in] node The IMFS node.
+ *
+ * @retval node Returns always the node passed as parameter.
+ *
+ * @see IMFS_node_control.
+ */
+IMFS_jnode_t *IMFS_node_remove_default(
+ IMFS_jnode_t *node
+);
+
+IMFS_jnode_t *IMFS_node_remove_directory( IMFS_jnode_t *node );
+
+/**
+ * @brief Destroys an IMFS node.
+ *
+ * @param[in] node The IMFS node.
+ *
+ * @see IMFS_node_control and IMFS_node_destroy_default().
+ */
+typedef void (*IMFS_node_control_destroy)( IMFS_jnode_t *node );
+
+/**
+ * @brief Frees the node.
+ *
+ * @param[in] node The IMFS node.
+ *
+ * @see IMFS_node_control.
+ */
+void IMFS_node_destroy_default( IMFS_jnode_t *node );
+
+/**
+ * @brief IMFS node control.
+ */
+typedef struct {
+ 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;
+
+typedef struct {
+ IMFS_node_control node_control;
+ size_t node_size;
+} IMFS_mknod_control;
+
+/** @} */
+
+/**
+ * @addtogroup IMFS
+ */
+/**@{*/
+
+/*
+ * Maximum length of a "basename" of an IMFS file/node.
+ */
+
+#define IMFS_NAME_MAX _POSIX_NAME_MAX
+
+/*
+
+ * The control structure for an IMFS jnode.
+ */
+
+struct IMFS_jnode_tt {
+ rtems_chain_node Node; /* for chaining them together */
+ IMFS_jnode_t *Parent; /* Parent node */
+ const char *name; /* "basename" (not \0 terminated) */
+ uint16_t namelen; /* Length of "basename" */
+ uint16_t flags; /* Node flags */
+ mode_t st_mode; /* File mode */
+ unsigned short reference_count;
+ nlink_t st_nlink; /* Link count */
+
+ uid_t st_uid; /* User ID of owner */
+ gid_t st_gid; /* Group ID of owner */
+
+ 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 */
+ const IMFS_node_control *control;
+};
+
+#define IMFS_NODE_FLAG_NAME_ALLOCATED 0x1
+
+typedef struct {
+ IMFS_jnode_t Node;
+ rtems_chain_control Entries;
+ rtems_filesystem_mount_table_entry_t *mt_fs;
+} IMFS_directory_t;
+
+typedef struct {
+ IMFS_jnode_t Node;
+ rtems_device_major_number major;
+ rtems_device_minor_number minor;
+} IMFS_device_t;
+
+typedef struct {
+ IMFS_jnode_t Node;
+ IMFS_jnode_t *link_node;
+} IMFS_link_t;
+
+typedef struct {
+ IMFS_jnode_t Node;
+ char *name;
+} IMFS_sym_link_t;
+
+typedef struct {
+ IMFS_jnode_t Node;
+ size_t size; /* size of file in bytes */
+} IMFS_filebase_t;
+
+typedef struct {
+ IMFS_filebase_t File;
+ block_ptr indirect; /* array of 128 data blocks pointers */
+ block_ptr doubly_indirect; /* 128 indirect blocks */
+ block_ptr triply_indirect; /* 128 doubly indirect blocks */
+} IMFS_memfile_t;
+
+typedef struct {
+ IMFS_filebase_t File;
+ block_p direct; /* pointer to file image */
+} IMFS_linearfile_t;
+
+/* Support copy on write for linear files */
+typedef union {
+ IMFS_jnode_t Node;
+ IMFS_filebase_t File;
+ IMFS_memfile_t Memfile;
+ IMFS_linearfile_t Linearfile;
+} IMFS_file_t;
+
+typedef struct {
+ IMFS_jnode_t Node;
+ pipe_control_t *pipe;
+} IMFS_fifo_t;
+
+typedef struct {
+ IMFS_jnode_t Node;
+ void *context;
+} IMFS_generic_t;
+
+static inline IMFS_directory_t *IMFS_iop_to_directory(
+ const rtems_libio_t *iop
+)
+{
+ return (IMFS_directory_t *) iop->pathinfo.node_access;
+}
+
+static inline IMFS_device_t *IMFS_iop_to_device( const rtems_libio_t *iop )
+{
+ return (IMFS_device_t *) iop->pathinfo.node_access;
+}
+
+static inline IMFS_file_t *IMFS_iop_to_file( const rtems_libio_t *iop )
+{
+ return (IMFS_file_t *) iop->pathinfo.node_access;
+}
+
+static inline IMFS_memfile_t *IMFS_iop_to_memfile( const rtems_libio_t *iop )
+{
+ return (IMFS_memfile_t *) iop->pathinfo.node_access;
+}
+
+static inline void IMFS_update_atime( IMFS_jnode_t *jnode )
+{
+ struct timeval now;
+
+ gettimeofday( &now, 0 );
+
+ jnode->stat_atime = now.tv_sec;
+}
+
+static inline void IMFS_update_mtime( IMFS_jnode_t *jnode )
+{
+ struct timeval now;
+
+ gettimeofday( &now, 0 );
+
+ jnode->stat_mtime = now.tv_sec;
+}
+
+static inline void IMFS_update_ctime( IMFS_jnode_t *jnode )
+{
+ struct timeval now;
+
+ gettimeofday( &now, 0 );
+
+ jnode->stat_ctime = now.tv_sec;
+}
+
+static inline void IMFS_mtime_ctime_update( IMFS_jnode_t *jnode )
+{
+ struct timeval now;
+
+ gettimeofday( &now, 0 );
+
+ jnode->stat_mtime = now.tv_sec;
+ jnode->stat_ctime = now.tv_sec;
+}
+
+typedef struct {
+ const IMFS_mknod_control *directory;
+ const IMFS_mknod_control *device;
+ const IMFS_mknod_control *file;
+ const IMFS_mknod_control *fifo;
+} IMFS_mknod_controls;
+
+typedef struct {
+ IMFS_directory_t Root_directory;
+ const IMFS_mknod_controls *mknod_controls;
+} IMFS_fs_info_t;
+
+typedef struct {
+ IMFS_fs_info_t *fs_info;
+ const rtems_filesystem_operations_table *ops;
+ const IMFS_mknod_controls *mknod_controls;
+} IMFS_mount_data;
+
+/*
+ * Shared Data
+ */
+
+extern const IMFS_mknod_control IMFS_mknod_control_dir_default;
+extern const IMFS_mknod_control IMFS_mknod_control_dir_minimal;
+extern const IMFS_mknod_control IMFS_mknod_control_device;
+extern const IMFS_mknod_control IMFS_mknod_control_memfile;
+extern const IMFS_node_control IMFS_node_control_linfile;
+extern const IMFS_mknod_control IMFS_mknod_control_fifo;
+extern const IMFS_mknod_control IMFS_mknod_control_enosys;
+
+extern const rtems_filesystem_limits_and_options_t IMFS_LIMITS_AND_OPTIONS;
+
+/*
+ * Routines
+ */
+
+extern int IMFS_initialize(
+ rtems_filesystem_mount_table_entry_t *mt_entry,
+ const void *data
+);
+
+extern int IMFS_initialize_support(
+ rtems_filesystem_mount_table_entry_t *mt_entry,
+ const void *data
+);
+
+/**
+ * @brief Unmount this instance of IMFS.
+ */
+extern void IMFS_fsunmount(
+ rtems_filesystem_mount_table_entry_t *mt_entry
+);
+
+/**
+ * @brief RTEMS load tarfs.
+ *
+ * This file implements the "mount" procedure for tar-based IMFS
+ * extensions. The TAR is not actually mounted under the IMFS.
+ * Directories from the TAR file are created as usual in the IMFS.
+ * File entries are created as IMFS_LINEAR_FILE nodes with their nods
+ * pointing to addresses in the TAR image.
+ *
+ * Here we create the mountpoint directory and load the tarfs at
+ * that node. Once the IMFS has been mounted, we work through the
+ * tar image and perform as follows:
+ * - For directories, simply call mkdir(). The IMFS creates nodes as
+ * needed.
+ * - For files, we make our own calls to IMFS eval_for_make and
+ * create_node.
+ *
+ * TAR file format:
+ *
+ * @code
+ * Offset Length Contents
+ * 0 100 bytes File name ('\0' terminated, 99 maxmum length)
+ * 100 8 bytes File mode (in octal ascii)
+ * 108 8 bytes User ID (in octal ascii)
+ * 116 8 bytes Group ID (in octal ascii)
+ * 124 12 bytes File size (s) (in octal ascii)
+ * 136 12 bytes Modify time (in octal ascii)
+ * 148 8 bytes Header checksum (in octal ascii)
+ * 156 1 bytes Link flag
+ * 157 100 bytes Linkname ('\0' terminated, 99 maxmum length)
+ * 257 8 bytes Magic PAX ("ustar\0" + 2 bytes padding)
+ * 257 8 bytes Magic GNU tar ("ustar \0")
+ * 265 32 bytes User name ('\0' terminated, 31 maxmum length)
+ * 297 32 bytes Group name ('\0' terminated, 31 maxmum length)
+ * 329 8 bytes Major device ID (in octal ascii)
+ * 337 8 bytes Minor device ID (in octal ascii)
+ * 345 167 bytes Padding
+ * 512 (s+p) bytes File contents (s+p) := (((s) + 511) & ~511),
+ * round up to 512 bytes
+ * @endcode
+ *
+ * Checksum:
+ * @code
+ * int i, sum;
+ * char *header = tar_header_pointer;
+ *
+ * sum = 0;
+ * for (i = 0; i < 512; i++)
+ * sum += 0xFF & header[i];
+ * @endcode
+ */
+extern int rtems_tarfs_load(
+ const char *mountpoint,
+ uint8_t *tar_image,
+ size_t tar_size
+);
+
+/**
+ * @brief Destroy an IMFS node.
+ */
+extern void IMFS_node_destroy( IMFS_jnode_t *node );
+
+/**
+ * @brief Clone an IMFS node.
+ */
+extern int IMFS_node_clone( rtems_filesystem_location_info_t *loc );
+
+/**
+ * @brief Free an IMFS node.
+ */
+extern void IMFS_node_free( const rtems_filesystem_location_info_t *loc );
+
+/**
+ * @brief Perform a status processing for the IMFS.
+ *
+ * This routine provides a stat for the IMFS file system.
+ */
+extern int IMFS_stat(
+ const rtems_filesystem_location_info_t *loc,
+ struct stat *buf
+);
+
+extern int IMFS_stat_file(
+ const rtems_filesystem_location_info_t *loc,
+ struct stat *buf
+);
+
+/**
+ * @brief IMFS evaluation node support.
+ */
+extern void IMFS_eval_path(
+ rtems_filesystem_eval_path_context_t *ctx
+);
+
+/**
+ * @brief Create a new IMFS link node.
+ *
+ * The following rouine creates a new link node under parent with the
+ * name given in name. The link node is set to point to the node at
+ * to_loc.
+ */
+extern int IMFS_link(
+ const rtems_filesystem_location_info_t *parentloc,
+ const rtems_filesystem_location_info_t *targetloc,
+ const char *name,
+ size_t namelen
+);
+
+/**
+ * @brief Change the owner of IMFS.
+ *
+ * This routine is the implementation of the chown() system
+ * call for the IMFS.
+ */
+extern int IMFS_chown(
+ const rtems_filesystem_location_info_t *loc,
+ uid_t owner,
+ gid_t group
+);
+
+/**
+ * @brief Create an IMFS node.
+ *
+ * Routine to create a node in the IMFS file system.
+ */
+extern int IMFS_mknod(
+ const rtems_filesystem_location_info_t *parentloc,
+ const char *name,
+ size_t namelen,
+ mode_t mode,
+ dev_t dev
+);
+
+extern IMFS_jnode_t *IMFS_initialize_node(
+ IMFS_jnode_t *node,
+ const IMFS_node_control *node_control,
+ const char *name,
+ size_t namelen,
+ mode_t mode,
+ void *arg
+);
+
+/**
+ * @brief Create an IMFS node.
+ *
+ * Create an IMFS filesystem node of an arbitrary type that is NOT
+ * the root directory node.
+ */
+extern IMFS_jnode_t *IMFS_create_node(
+ const rtems_filesystem_location_info_t *parentloc,
+ const IMFS_node_control *node_control,
+ size_t node_size,
+ const char *name,
+ size_t namelen,
+ mode_t mode,
+ void *arg
+);
+
+static inline bool IMFS_is_imfs_instance(
+ const rtems_filesystem_location_info_t *loc
+)
+{
+ return loc->mt_entry->ops->clonenod_h == IMFS_node_clone;
+}
+
+/** @} */
+
+/**
+ * @defgroup IMFSGenericNodes IMFS Generic Nodes
+ *
+ * @ingroup LibIO
+ *
+ * @brief 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.
+ *
+ * @{
+ */
+
+/**
+ * @brief Initializer for a generic node control.
+ *
+ * @param[in] handlers The file system node handlers.
+ * @param[in] init The node initialization method.
+ * @param[in] destroy The node destruction method.
+ */
+#define IMFS_GENERIC_INITIALIZER( handlers, init, destroy ) \
+ { \
+ ( handlers ), \
+ ( init ), \
+ IMFS_node_remove_default, \
+ ( destroy ) \
+ }
+
+/**
+ * @brief Makes a generic IMFS node.
+ *
+ * @param[in] path The path to the new generic IMFS node.
+ * @param[in] mode The node mode.
+ * @param[in] node_control The node control.
+ * @param[in] context The node control handler context.
+ *
+ * @retval 0 Successful operation.
+ * @retval -1 An error occurred. The @c errno indicates the error.
+ *
+ * @code
+ * #include <sys/stat.h>
+ * #include <assert.h>
+ * #include <fcntl.h>
+ *
+ * #include <rtems/imfs.h>
+ *
+ * static const rtems_filesystem_file_handlers_r some_node_handlers = {
+ * ...
+ * };
+ *
+ * static IMFS_jnode_t *some_node_init(IMFS_jnode_t *node, void *arg)
+ * {
+ * void *context;
+ *
+ * node = IMFS_node_initialize_generic(node, arg);
+ * context = IMFS_generic_get_context_by_node(node);
+ *
+ * return node;
+ * }
+ *
+ * static void some_node_destroy(IMFS_jnode_t *node)
+ * {
+ * void *context = IMFS_generic_get_context_by_node(node);
+ *
+ * IMFS_node_destroy_default(node);
+ * }
+ *
+ * static const IMFS_node_control some_node_control = IMFS_GENERIC_INITIALIZER(
+ * &some_node_handlers,
+ * some_node_init,
+ * some_node_destroy
+ * );
+ *
+ * void example(void *some_node_context)
+ * {
+ * int rv;
+ *
+ * rv = IMFS_make_generic_node(
+ * "/path/to/some/generic/node",
+ * S_IFCHR | S_IRWXU | S_IRWXG | S_IRWXO,
+ * &some_node_control,
+ * some_node_context
+ * );
+ * assert(rv == 0);
+ * }
+ * @endcode
+ */
+extern int IMFS_make_generic_node(
+ const char *path,
+ mode_t mode,
+ const IMFS_node_control *node_control,
+ void *context
+);
+
+/** @} */
+
+/**
+ * @addtogroup IMFS
+ */
+/**@{*/
+
+/**
+ * @brief Mount an IMFS.
+ */
+extern int IMFS_mount(
+ rtems_filesystem_mount_table_entry_t *mt_entry /* IN */
+);
+
+/**
+ * @brief Unmount an IMFS.
+ */
+extern int IMFS_unmount(
+ rtems_filesystem_mount_table_entry_t *mt_entry /* IN */
+);
+
+/**
+ * @name IMFS Memory File Handlers
+ *
+ * This section contains the set of handlers used to process operations on
+ * IMFS memory file nodes. The memory files are created in memory using
+ * malloc'ed memory. Thus any data stored in one of these files is lost
+ * at system shutdown unless special arrangements to copy the data to
+ * some type of non-volailte storage are made by the application.
+ */
+/**@{*/
+
+extern ssize_t IMFS_memfile_write(
+ IMFS_memfile_t *memfile,
+ off_t start,
+ const unsigned char *source,
+ unsigned int length
+);
+
+/** @} */
+
+/**
+ * @name IMFS Device Node Handlers
+ *
+ * This section contains the set of handlers used to map operations on
+ * IMFS device nodes onto calls to the RTEMS Classic API IO Manager.
+ */
+/**@{*/
+
+extern int device_open(
+ rtems_libio_t *iop, /* IN */
+ const char *pathname, /* IN */
+ int oflag, /* IN */
+ mode_t mode /* IN */
+);
+
+extern int device_close(
+ rtems_libio_t *iop /* IN */
+);
+
+extern ssize_t device_read(
+ rtems_libio_t *iop, /* IN */
+ void *buffer, /* IN */
+ size_t count /* IN */
+);
+
+extern ssize_t device_write(
+ rtems_libio_t *iop, /* IN */
+ const void *buffer, /* IN */
+ size_t count /* IN */
+);
+
+extern int device_ioctl(
+ rtems_libio_t *iop,
+ ioctl_command_t command,
+ void *buffer
+);
+
+extern int device_ftruncate(
+ rtems_libio_t *iop, /* IN */
+ off_t length /* IN */
+);
+
+/** @} */
+
+/**
+ * @brief Set IMFS file access and modification times.
+ *
+ *
+ * This routine is the implementation of the utime() system
+ * call for the IMFS.
+ */
+extern int IMFS_utime(
+ const rtems_filesystem_location_info_t *loc,
+ time_t actime,
+ time_t modtime
+);
+
+/**
+ * @brief Change the IMFS file mode.
+ */
+extern int IMFS_fchmod(
+ const rtems_filesystem_location_info_t *loc,
+ mode_t mode
+);
+
+/**
+ * @brief Create a new IMFS symbolic link node.
+ *
+ * The following rouine creates a new symbolic link node under parent
+ * with the name given in name. The node is set to point to the node at
+ * to_loc.
+ */
+extern int IMFS_symlink(
+ const rtems_filesystem_location_info_t *parentloc,
+ const char *name,
+ size_t namelen,
+ const char *target
+);
+
+/**
+ * @brief Put IMFS symbolic link into buffer.
+ *
+ * The following rouine puts the symbolic links destination name into
+ * buff.
+ *
+ */
+extern ssize_t IMFS_readlink(
+ const rtems_filesystem_location_info_t *loc,
+ char *buf,
+ size_t bufsize
+);
+
+/**
+ * @brief Rename the IMFS.
+ *
+ * The following rouine creates a new link node under parent with the
+ * name given in name and removes the old.
+ */
+extern int IMFS_rename(
+ 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
+);
+/**
+ * @brief IMFS node removal handler.
+ *
+ * This file contains the handler used to remove a node when a file type
+ * does not require special actions.
+ */
+extern int IMFS_rmnod(
+ const rtems_filesystem_location_info_t *parentloc,
+ const rtems_filesystem_location_info_t *loc
+);
+
+/*
+ * Turn on IMFS assertions when RTEMS_DEBUG is defined.
+ */
+#ifdef RTEMS_DEBUG
+ #include <assert.h>
+
+ #define IMFS_assert(_x) assert(_x)
+#else
+ #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_node,
+ IMFS_jnode_t *entry_node
+)
+{
+ IMFS_directory_t *dir = (IMFS_directory_t *) dir_node;
+
+ entry_node->Parent = dir_node;
+ rtems_chain_append_unprotected( &dir->Entries, &entry_node->Node );
+}
+
+static inline void IMFS_remove_from_directory( IMFS_jnode_t *node )
+{
+ IMFS_assert( node->Parent != NULL );
+ node->Parent = NULL;
+ rtems_chain_extract_unprotected( &node->Node );
+}
+
+static inline bool IMFS_is_directory( const IMFS_jnode_t *node )
+{
+ return S_ISDIR( node->st_mode );
+}
+
+#define IMFS_STAT_FMT_HARD_LINK 0
+
+static inline bool IMFS_is_hard_link( mode_t mode )
+{
+ return ( mode & S_IFMT ) == IMFS_STAT_FMT_HARD_LINK;
+}
+
+static inline ino_t IMFS_node_to_ino( const IMFS_jnode_t *node )
+{
+ return (ino_t) ((uintptr_t) node);
+}
+
+/** @} */
+
+/**
+ * @addtogroup IMFSGenericNodes
+ */
+/**@{*/
+
+static inline void *IMFS_generic_get_context_by_node(
+ const IMFS_jnode_t *node
+)
+{
+ const IMFS_generic_t *generic = (const IMFS_generic_t *) node;
+
+ return generic->context;
+}
+
+static inline void *IMFS_generic_get_context_by_location(
+ const rtems_filesystem_location_info_t *loc
+)
+{
+ return loc->node_access_2;
+}
+
+static inline void *IMFS_generic_get_context_by_iop(
+ const rtems_libio_t *iop
+)
+{
+ return IMFS_generic_get_context_by_location( &iop->pathinfo );
+}
+
+static inline dev_t IMFS_generic_get_device_identifier_by_node(
+ const IMFS_jnode_t *node
+)
+{
+ return rtems_filesystem_make_dev_t_from_pointer( node );
+}
+
+#ifdef __cplusplus
+}
+#endif
+/** @} */
+#endif
+/* end of include file */