diff options
Diffstat (limited to 'cpukit/libfs/src/imfs/imfs.h')
-rw-r--r-- | cpukit/libfs/src/imfs/imfs.h | 291 |
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( |