summaryrefslogtreecommitdiffstats
path: root/cpukit/libfs/src/imfs/imfs.h
diff options
context:
space:
mode:
Diffstat (limited to 'cpukit/libfs/src/imfs/imfs.h')
-rw-r--r--cpukit/libfs/src/imfs/imfs.h291
1 files changed, 171 insertions, 120 deletions
diff --git a/cpukit/libfs/src/imfs/imfs.h b/cpukit/libfs/src/imfs/imfs.h
index c34f89fd15..fe99493530 100644
--- a/cpukit/libfs/src/imfs/imfs.h
+++ b/cpukit/libfs/src/imfs/imfs.h
@@ -41,32 +41,6 @@ extern "C" {
struct IMFS_jnode_tt;
typedef struct IMFS_jnode_tt IMFS_jnode_t;
-typedef struct {
- rtems_chain_control Entries;
- rtems_filesystem_mount_table_entry_t *mt_fs;
-} IMFS_directory_t;
-
-typedef struct {
- rtems_device_major_number major;
- rtems_device_minor_number minor;
-} IMFS_device_t;
-
-typedef struct {
- IMFS_jnode_t *link_node;
-} IMFS_link_t;
-
-typedef struct {
- char *name;
-} IMFS_sym_link_t;
-
-typedef struct {
- pipe_control_t *pipe;
-} IMFS_fifo_t;
-
-typedef struct {
- void *context;
-} IMFS_generic_t;
-
/**
* IMFS "memfile" information
*
@@ -100,18 +74,6 @@ typedef struct {
typedef uint8_t *block_p;
typedef block_p *block_ptr;
-typedef struct {
- off_t size; /* size of file in bytes */
- 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 {
- off_t size; /* size of file in bytes */
- block_p direct; /* pointer to file image */
-} IMFS_linearfile_t;
-
/*
* Important block numbers for "memfiles"
*/
@@ -142,25 +104,11 @@ typedef enum {
IMFS_SYM_LINK,
IMFS_MEMORY_FILE,
IMFS_LINEAR_FILE,
- IMFS_FIFO,
- IMFS_GENERIC,
- IMFS_INVALID_NODE
+ IMFS_FIFO
} IMFS_jnode_types_t;
-/* The IMFS_GENERIC does not count */
#define IMFS_TYPE_COUNT (IMFS_FIFO + 1)
-typedef union {
- IMFS_directory_t directory;
- IMFS_device_t device;
- IMFS_link_t hard_link;
- IMFS_sym_link_t sym_link;
- IMFS_memfile_t file;
- IMFS_linearfile_t linearfile;
- IMFS_fifo_t fifo;
- IMFS_generic_t generic;
-} IMFS_types_union;
-
/** @} */
/**
@@ -171,8 +119,9 @@ typedef union {
/**
* @brief Initializes an IMFS node.
*
- * @param[in,out] node The IMFS node.
- * @param[in] info The IMFS type information.
+ * @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
@@ -183,14 +132,14 @@ typedef union {
*/
typedef IMFS_jnode_t *(*IMFS_node_control_initialize)(
IMFS_jnode_t *node,
- const IMFS_types_union *info
+ void *arg
);
/**
* @brief Returns the node and does nothing else.
*
- * @param[in,out] node The IMFS node.
- * @param[in] info The IMFS type information.
+ * @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.
*
@@ -198,14 +147,15 @@ typedef IMFS_jnode_t *(*IMFS_node_control_initialize)(
*/
IMFS_jnode_t *IMFS_node_initialize_default(
IMFS_jnode_t *node,
- const IMFS_types_union *info
+ void *arg
);
/**
* @brief Returns the node and sets the generic node context.
*
- * @param[in,out] node The IMFS node.
- * @param[in] info The IMFS type information.
+ * @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.
*
@@ -213,13 +163,13 @@ IMFS_jnode_t *IMFS_node_initialize_default(
*/
IMFS_jnode_t *IMFS_node_initialize_generic(
IMFS_jnode_t *node,
- const IMFS_types_union *info
+ void *arg
);
/**
* @brief Prepares the removal of an IMFS node from its parent directory.
*
- * @param[in,out] node The IMFS node.
+ * @param[in] node The IMFS node.
*
* @retval node Successful operation.
* @retval NULL An error occurred. The @c errno indicates the error. This
@@ -234,7 +184,7 @@ typedef IMFS_jnode_t *(*IMFS_node_control_remove)(
/**
* @brief Returns the node and does nothing else.
*
- * @param[in,out] node The IMFS node.
+ * @param[in] node The IMFS node.
*
* @retval node Returns always the node passed as parameter.
*
@@ -247,31 +197,27 @@ IMFS_jnode_t *IMFS_node_remove_default(
/**
* @brief Destroys an IMFS node.
*
- * @param[in,out] node The IMFS node.
- *
- * @retval node Returns always the node passed as parameter.
+ * @param[in] node The IMFS node.
*
* @see IMFS_node_control and IMFS_node_destroy_default().
*/
-typedef IMFS_jnode_t *(*IMFS_node_control_destroy)( IMFS_jnode_t *node );
+typedef void (*IMFS_node_control_destroy)( IMFS_jnode_t *node );
/**
- * @brief Returns the node and does nothing else.
- *
- * @param[in,out] node The IMFS node.
+ * @brief Frees the node.
*
- * @retval node Returns always the node passed as parameter.
+ * @param[in] node The IMFS node.
*
* @see IMFS_node_control.
*/
-IMFS_jnode_t *IMFS_node_destroy_default( IMFS_jnode_t *node );
+void IMFS_node_destroy_default( IMFS_jnode_t *node );
/**
* @brief IMFS node control.
*/
typedef struct {
- IMFS_jnode_types_t imfs_type;
const rtems_filesystem_file_handlers_r *handlers;
+ size_t node_size;
IMFS_node_control_initialize node_initialize;
IMFS_node_control_remove node_remove;
IMFS_node_control_destroy node_destroy;
@@ -323,9 +269,87 @@ struct IMFS_jnode_tt {
time_t stat_mtime; /* Time of last modification */
time_t stat_ctime; /* Time of last status change */
const IMFS_node_control *control;
- IMFS_types_union info;
};
+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;
@@ -480,26 +504,6 @@ extern int rtems_tarfs_load(
);
/**
- * @brief Dump the entire IMFS.
- *
- * This routine dumps the entire IMFS that is mounted at the root
- * directory.
- *
- * NOTE: Assuming the "/" directory is bad.
- * Not checking that the starting directory is in an IMFS is bad.
- */
-extern void IMFS_dump( void );
-
-/**
- * @brief Get the size of the largest file which can be created
- * using the IMFS memory file type.
- *
- * Return the size of the largest file which can be created
- * using the IMFS memory file type.
- */
-extern int IMFS_memfile_maximum_size( void );
-
-/**
* @brief Destroy an IMFS node.
*/
extern void IMFS_node_destroy( IMFS_jnode_t *node );
@@ -581,7 +585,7 @@ extern IMFS_jnode_t *IMFS_allocate_node(
const char *name,
size_t namelen,
mode_t mode,
- const IMFS_types_union *info
+ void *arg
);
/**
@@ -596,7 +600,7 @@ extern IMFS_jnode_t *IMFS_create_node_with_control(
const char *name,
size_t namelen,
mode_t mode,
- const IMFS_types_union *info
+ void *arg
);
extern bool IMFS_is_imfs_instance(
@@ -617,8 +621,25 @@ extern bool IMFS_is_imfs_instance(
* 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 ), \
+ sizeof( IMFS_generic_t ), \
+ ( init ), \
+ IMFS_node_remove_default, \
+ ( destroy ) \
+ }
/**
* @brief Makes a generic IMFS node.
@@ -638,14 +659,33 @@ extern bool IMFS_is_imfs_instance(
*
* #include <rtems/imfs.h>
*
- * static const IMFS_node_control some_node_control = {
- * .imfs_type = IMFS_GENERIC,
- * .handlers = &some_node_handlers,
- * .node_initialize = IMFS_node_initialize_generic,
- * .node_remove = IMFS_node_remove_default,
- * .node_destroy = some_node_destroy
+ * 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;
@@ -688,7 +728,7 @@ extern int IMFS_unmount(
rtems_filesystem_mount_table_entry_t *mt_entry /* IN */
);
-extern IMFS_jnode_t *IMFS_memfile_remove(
+extern void IMFS_memfile_remove(
IMFS_jnode_t *the_jnode /* IN/OUT */
);
@@ -734,18 +774,23 @@ extern ssize_t imfs_dir_read(
/**@{*/
/**
- * @brief Open a memory file.
+ * @brief Open a linear file.
*
- * This routine processes the open() system call. Note that there is
- * nothing special to be done at open() time.
+ * Transforms the file into a memfile if opened for writing.
*/
-extern int memfile_open(
+extern int IMFS_linfile_open(
rtems_libio_t *iop, /* IN */
const char *pathname, /* IN */
int oflag, /* IN */
mode_t mode /* IN */
);
+extern ssize_t IMFS_linfile_read(
+ rtems_libio_t *iop,
+ void *buffer,
+ size_t count
+);
+
/**
* @brief Read a memory file.
*
@@ -905,12 +950,14 @@ static inline void IMFS_Set_handlers( rtems_filesystem_location_info_t *loc )
}
static inline void IMFS_add_to_directory(
- IMFS_jnode_t *dir,
- IMFS_jnode_t *node
+ IMFS_jnode_t *dir_node,
+ IMFS_jnode_t *entry_node
)
{
- node->Parent = dir;
- rtems_chain_append_unprotected( &dir->info.directory.Entries, &node->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 )
@@ -920,14 +967,16 @@ static inline void IMFS_remove_from_directory( IMFS_jnode_t *node )
rtems_chain_extract_unprotected( &node->Node );
}
-static inline IMFS_jnode_types_t IMFS_type( const IMFS_jnode_t *node )
+static inline bool IMFS_is_directory( const IMFS_jnode_t *node )
{
- return node->control->imfs_type;
+ return S_ISDIR( node->st_mode );
}
-static inline bool IMFS_is_directory( const IMFS_jnode_t *node )
+#define IMFS_STAT_FMT_HARD_LINK 0
+
+static inline bool IMFS_is_hard_link( mode_t mode )
{
- return node->control->imfs_type == IMFS_DIRECTORY;
+ return ( mode & S_IFMT ) == IMFS_STAT_FMT_HARD_LINK;
}
static inline IMFS_jnode_t *IMFS_create_node(
@@ -936,7 +985,7 @@ static inline IMFS_jnode_t *IMFS_create_node(
const char *name,
size_t namelen,
mode_t mode,
- const IMFS_types_union *info
+ void *arg
)
{
const IMFS_fs_info_t *fs_info =
@@ -948,7 +997,7 @@ static inline IMFS_jnode_t *IMFS_create_node(
name,
namelen,
mode,
- info
+ arg
);
}
@@ -963,7 +1012,9 @@ static inline void *IMFS_generic_get_context_by_node(
const IMFS_jnode_t *node
)
{
- return node->info.generic.context;
+ const IMFS_generic_t *generic = (const IMFS_generic_t *) node;
+
+ return generic->context;
}
static inline void *IMFS_generic_get_context_by_location(