mirror of
https://gitlab.rtems.org/rtems/rtos/rtems.git
synced 2026-09-27 16:28:34 +08:00
IMFS: Replace node union with individual struct
This reduces the average node size. Add and use IMFS_GENERIC_INITIALIZER().
This commit is contained in:
@@ -42,7 +42,7 @@ libimfs_a_SOURCES =
|
||||
|
||||
libimfs_a_SOURCES += src/imfs/deviceio.c \
|
||||
src/imfs/fifoimfs_init.c src/imfs/imfs_chown.c src/imfs/imfs_config.c \
|
||||
src/imfs/imfs_creat.c src/imfs/imfs_debug.c src/imfs/imfs_directory.c \
|
||||
src/imfs/imfs_creat.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 \
|
||||
|
||||
@@ -29,17 +29,15 @@ int device_open(
|
||||
mode_t mode
|
||||
)
|
||||
{
|
||||
IMFS_jnode_t *the_jnode;
|
||||
|
||||
the_jnode = iop->pathinfo.node_access;
|
||||
const IMFS_device_t *device = IMFS_iop_to_device( iop );
|
||||
|
||||
return rtems_deviceio_open(
|
||||
iop,
|
||||
pathname,
|
||||
oflag,
|
||||
mode,
|
||||
the_jnode->info.device.major,
|
||||
the_jnode->info.device.minor
|
||||
device->major,
|
||||
device->minor
|
||||
);
|
||||
}
|
||||
|
||||
@@ -47,14 +45,12 @@ int device_close(
|
||||
rtems_libio_t *iop
|
||||
)
|
||||
{
|
||||
IMFS_jnode_t *the_jnode;
|
||||
|
||||
the_jnode = iop->pathinfo.node_access;
|
||||
const IMFS_device_t *device = IMFS_iop_to_device( iop );
|
||||
|
||||
return rtems_deviceio_close(
|
||||
iop,
|
||||
the_jnode->info.device.major,
|
||||
the_jnode->info.device.minor
|
||||
device->major,
|
||||
device->minor
|
||||
);
|
||||
}
|
||||
|
||||
@@ -64,16 +60,14 @@ ssize_t device_read(
|
||||
size_t count
|
||||
)
|
||||
{
|
||||
IMFS_jnode_t *the_jnode;
|
||||
|
||||
the_jnode = iop->pathinfo.node_access;
|
||||
const IMFS_device_t *device = IMFS_iop_to_device( iop );
|
||||
|
||||
return rtems_deviceio_read(
|
||||
iop,
|
||||
buffer,
|
||||
count,
|
||||
the_jnode->info.device.major,
|
||||
the_jnode->info.device.minor
|
||||
device->major,
|
||||
device->minor
|
||||
);
|
||||
}
|
||||
|
||||
@@ -83,16 +77,14 @@ ssize_t device_write(
|
||||
size_t count
|
||||
)
|
||||
{
|
||||
IMFS_jnode_t *the_jnode;
|
||||
|
||||
the_jnode = iop->pathinfo.node_access;
|
||||
const IMFS_device_t *device = IMFS_iop_to_device( iop );
|
||||
|
||||
return rtems_deviceio_write(
|
||||
iop,
|
||||
buffer,
|
||||
count,
|
||||
the_jnode->info.device.major,
|
||||
the_jnode->info.device.minor
|
||||
device->major,
|
||||
device->minor
|
||||
);
|
||||
}
|
||||
|
||||
@@ -102,16 +94,14 @@ int device_ioctl(
|
||||
void *buffer
|
||||
)
|
||||
{
|
||||
IMFS_jnode_t *the_jnode;
|
||||
|
||||
the_jnode = iop->pathinfo.node_access;
|
||||
const IMFS_device_t *device = IMFS_iop_to_device( iop );
|
||||
|
||||
return rtems_deviceio_control(
|
||||
iop,
|
||||
command,
|
||||
buffer,
|
||||
the_jnode->info.device.major,
|
||||
the_jnode->info.device.minor
|
||||
device->major,
|
||||
device->minor
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
+173
-122
@@ -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.
|
||||
* @brief Frees the 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.
|
||||
*/
|
||||
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;
|
||||
@@ -479,26 +503,6 @@ extern int rtems_tarfs_load(
|
||||
size_t tar_size
|
||||
);
|
||||
|
||||
/**
|
||||
* @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.
|
||||
*/
|
||||
@@ -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 )
|
||||
{
|
||||
return node->control->imfs_type;
|
||||
}
|
||||
|
||||
static inline bool IMFS_is_directory( const IMFS_jnode_t *node )
|
||||
{
|
||||
return node->control->imfs_type == IMFS_DIRECTORY;
|
||||
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 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(
|
||||
|
||||
@@ -28,7 +28,7 @@ IMFS_jnode_t *IMFS_allocate_node(
|
||||
const char *name,
|
||||
size_t namelen,
|
||||
mode_t mode,
|
||||
const IMFS_types_union *info
|
||||
void *arg
|
||||
)
|
||||
{
|
||||
IMFS_jnode_t *node;
|
||||
@@ -46,7 +46,7 @@ IMFS_jnode_t *IMFS_allocate_node(
|
||||
/*
|
||||
* Allocate an IMFS jnode
|
||||
*/
|
||||
node = calloc( 1, sizeof( IMFS_jnode_t ) );
|
||||
node = calloc( 1, node_control->node_size );
|
||||
if ( !node ) {
|
||||
errno = ENOMEM;
|
||||
|
||||
@@ -78,7 +78,7 @@ IMFS_jnode_t *IMFS_allocate_node(
|
||||
node->stat_ctime = (time_t) tv.tv_sec;
|
||||
node->st_ino = ++fs_info->ino_count;
|
||||
|
||||
initialized_node = (*node->control->node_initialize)( node, info );
|
||||
initialized_node = (*node->control->node_initialize)( node, arg );
|
||||
if ( initialized_node == NULL ) {
|
||||
free( node );
|
||||
}
|
||||
@@ -92,7 +92,7 @@ IMFS_jnode_t *IMFS_create_node_with_control(
|
||||
const char *name,
|
||||
size_t namelen,
|
||||
mode_t mode,
|
||||
const IMFS_types_union *info
|
||||
void *arg
|
||||
)
|
||||
{
|
||||
IMFS_fs_info_t *fs_info = parentloc->mt_entry->fs_info;
|
||||
@@ -102,7 +102,7 @@ IMFS_jnode_t *IMFS_create_node_with_control(
|
||||
name,
|
||||
namelen,
|
||||
mode,
|
||||
info
|
||||
arg
|
||||
);
|
||||
|
||||
if ( node != NULL ) {
|
||||
|
||||
@@ -1,138 +0,0 @@
|
||||
/**
|
||||
* @file
|
||||
*
|
||||
* @brief IMFS Debug Support
|
||||
* @ingroup IMFS
|
||||
*/
|
||||
|
||||
/*
|
||||
* COPYRIGHT (c) 1989-1999.
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#if HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include "imfs.h"
|
||||
|
||||
#include <inttypes.h>
|
||||
#include <unistd.h>
|
||||
#include <stdio.h>
|
||||
|
||||
/*
|
||||
* IMFS_print_jnode
|
||||
*
|
||||
* This routine prints the contents of the specified jnode.
|
||||
*/
|
||||
static void IMFS_print_jnode(
|
||||
IMFS_jnode_t *the_jnode
|
||||
)
|
||||
{
|
||||
IMFS_assert( the_jnode );
|
||||
|
||||
fprintf(stdout, "%s", the_jnode->name );
|
||||
switch( IMFS_type( the_jnode ) ) {
|
||||
case IMFS_DIRECTORY:
|
||||
fprintf(stdout, "/" );
|
||||
break;
|
||||
|
||||
case IMFS_DEVICE:
|
||||
fprintf(stdout, " (device %" PRId32 ", %" PRId32 ")",
|
||||
the_jnode->info.device.major, the_jnode->info.device.minor );
|
||||
break;
|
||||
|
||||
case IMFS_LINEAR_FILE:
|
||||
fprintf(stdout, " (file %" PRId32 " %p)",
|
||||
(uint32_t)the_jnode->info.linearfile.size,
|
||||
the_jnode->info.linearfile.direct
|
||||
);
|
||||
break;
|
||||
|
||||
case IMFS_MEMORY_FILE:
|
||||
/* Useful when debugging .. varies between targets */
|
||||
#if 0
|
||||
fprintf(stdout, " (file %" PRId32 " %p %p %p)",
|
||||
(uint32_t)the_jnode->info.file.size,
|
||||
the_jnode->info.file.indirect,
|
||||
the_jnode->info.file.doubly_indirect,
|
||||
the_jnode->info.file.triply_indirect
|
||||
);
|
||||
#else
|
||||
fprintf(stdout, " (file %" PRId32 ")",
|
||||
(uint32_t)the_jnode->info.file.size );
|
||||
#endif
|
||||
break;
|
||||
|
||||
case IMFS_HARD_LINK:
|
||||
fprintf(stdout, " links not printed\n" );
|
||||
return;
|
||||
|
||||
case IMFS_SYM_LINK:
|
||||
fprintf(stdout, " links not printed\n" );
|
||||
return;
|
||||
|
||||
case IMFS_FIFO:
|
||||
fprintf(stdout, " FIFO not printed\n" );
|
||||
return;
|
||||
|
||||
default:
|
||||
fprintf(stdout, " bad type %d\n", IMFS_type( the_jnode ) );
|
||||
return;
|
||||
}
|
||||
puts("");
|
||||
}
|
||||
|
||||
/*
|
||||
* IMFS_dump_directory
|
||||
*
|
||||
* This routine prints the contents of a directory in the IMFS. If a
|
||||
* directory is encountered, then this routine will recurse to process
|
||||
* the subdirectory.
|
||||
*/
|
||||
static void IMFS_dump_directory(
|
||||
IMFS_jnode_t *the_directory,
|
||||
int level
|
||||
)
|
||||
{
|
||||
rtems_chain_node *the_node;
|
||||
rtems_chain_control *the_chain;
|
||||
IMFS_jnode_t *the_jnode;
|
||||
int i;
|
||||
|
||||
IMFS_assert( the_directory );
|
||||
IMFS_assert( level >= 0 );
|
||||
IMFS_assert( IMFS_is_directory( the_directory ) );
|
||||
|
||||
the_chain = &the_directory->info.directory.Entries;
|
||||
|
||||
for ( the_node = rtems_chain_first( the_chain );
|
||||
!rtems_chain_is_tail( the_chain, the_node );
|
||||
the_node = the_node->next ) {
|
||||
|
||||
the_jnode = (IMFS_jnode_t *) the_node;
|
||||
|
||||
for ( i=0 ; i<=level ; i++ )
|
||||
fprintf(stdout, "...." );
|
||||
IMFS_print_jnode( the_jnode );
|
||||
if ( IMFS_is_directory( the_jnode ) )
|
||||
IMFS_dump_directory( the_jnode, level + 1 );
|
||||
}
|
||||
}
|
||||
|
||||
void IMFS_dump( void )
|
||||
{
|
||||
fprintf(stdout, "*************** Dump of Entire IMFS ***************\n" );
|
||||
fprintf(stdout, "/\n" );
|
||||
IMFS_dump_directory( rtems_filesystem_root->location.node_access, 0 );
|
||||
fprintf(stdout, "*************** End of Dump ***************\n" );
|
||||
}
|
||||
|
||||
int IMFS_memfile_maximum_size( void )
|
||||
{
|
||||
return IMFS_MEMFILE_MAXIMUM_SIZE;
|
||||
}
|
||||
@@ -33,19 +33,19 @@ ssize_t imfs_dir_read(
|
||||
* Read up to element iop->offset in the directory chain of the
|
||||
* imfs_jnode_t struct for this file descriptor.
|
||||
*/
|
||||
rtems_chain_node *the_node;
|
||||
rtems_chain_control *the_chain;
|
||||
IMFS_jnode_t *the_jnode;
|
||||
int bytes_transferred;
|
||||
int current_entry;
|
||||
int first_entry;
|
||||
int last_entry;
|
||||
struct dirent tmp_dirent;
|
||||
const IMFS_directory_t *dir;
|
||||
const rtems_chain_node *node;
|
||||
const rtems_chain_control *entries;
|
||||
struct dirent *dir_ent;
|
||||
ssize_t bytes_transferred;
|
||||
off_t current_entry;
|
||||
off_t first_entry;
|
||||
off_t last_entry;
|
||||
|
||||
rtems_filesystem_instance_lock( &iop->pathinfo );
|
||||
|
||||
the_jnode = (IMFS_jnode_t *)iop->pathinfo.node_access;
|
||||
the_chain = &the_jnode->info.directory.Entries;
|
||||
dir = IMFS_iop_to_directory( iop );
|
||||
entries = &dir->Entries;
|
||||
|
||||
/* Move to the first of the desired directory entries */
|
||||
|
||||
@@ -54,32 +54,31 @@ ssize_t imfs_dir_read(
|
||||
/* protect against using sizes that are not exact multiples of the */
|
||||
/* -dirent- size. These could result in unexpected results */
|
||||
last_entry = first_entry
|
||||
+ (count / sizeof( struct dirent )) * sizeof( struct dirent );
|
||||
+ (count / sizeof( *dir_ent )) * sizeof( *dir_ent );
|
||||
|
||||
/* The directory was not empty so try to move to the desired entry in chain*/
|
||||
for (
|
||||
current_entry = 0,
|
||||
the_node = rtems_chain_first( the_chain );
|
||||
node = rtems_chain_immutable_first( entries );
|
||||
current_entry < last_entry
|
||||
&& !rtems_chain_is_tail( the_chain, the_node );
|
||||
current_entry += sizeof( struct dirent ),
|
||||
the_node = rtems_chain_next( the_node )
|
||||
&& !rtems_chain_is_tail( entries, node );
|
||||
current_entry += sizeof( *dir_ent ),
|
||||
node = rtems_chain_immutable_next( node )
|
||||
) {
|
||||
if( current_entry >= first_entry ) {
|
||||
const IMFS_jnode_t *imfs_node = (const IMFS_jnode_t *) node;
|
||||
|
||||
dir_ent = (struct dirent *) ((char *) buffer + bytes_transferred);
|
||||
|
||||
/* Move the entry to the return buffer */
|
||||
tmp_dirent.d_off = current_entry;
|
||||
tmp_dirent.d_reclen = sizeof( struct dirent );
|
||||
the_jnode = (IMFS_jnode_t *) the_node;
|
||||
tmp_dirent.d_ino = the_jnode->st_ino;
|
||||
tmp_dirent.d_namlen = strlen( the_jnode->name );
|
||||
strcpy( tmp_dirent.d_name, the_jnode->name );
|
||||
memcpy(
|
||||
buffer + bytes_transferred,
|
||||
(void *)&tmp_dirent,
|
||||
sizeof( struct dirent )
|
||||
);
|
||||
iop->offset += sizeof( struct dirent );
|
||||
bytes_transferred += sizeof( struct dirent );
|
||||
dir_ent->d_off = current_entry;
|
||||
dir_ent->d_reclen = sizeof( *dir_ent );
|
||||
dir_ent->d_ino = imfs_node->st_ino;
|
||||
dir_ent->d_namlen = strlen( imfs_node->name );
|
||||
memcpy( dir_ent->d_name, imfs_node->name, dir_ent->d_namlen + 1 );
|
||||
|
||||
iop->offset += sizeof( *dir_ent );
|
||||
bytes_transferred += (ssize_t) sizeof( *dir_ent );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -38,18 +38,18 @@ static bool IMFS_eval_is_directory(
|
||||
}
|
||||
|
||||
static IMFS_jnode_t *IMFS_search_in_directory(
|
||||
IMFS_jnode_t *dir,
|
||||
IMFS_directory_t *dir,
|
||||
const char *token,
|
||||
size_t tokenlen
|
||||
)
|
||||
{
|
||||
if ( rtems_filesystem_is_current_directory( token, tokenlen ) ) {
|
||||
return dir;
|
||||
return &dir->Node;
|
||||
} else {
|
||||
if ( rtems_filesystem_is_parent_directory( token, tokenlen ) ) {
|
||||
return dir->Parent;
|
||||
return dir->Node.Parent;
|
||||
} else {
|
||||
rtems_chain_control *entries = &dir->info.directory.Entries;
|
||||
rtems_chain_control *entries = &dir->Entries;
|
||||
rtems_chain_node *current = rtems_chain_first( entries );
|
||||
rtems_chain_node *tail = rtems_chain_tail( entries );
|
||||
|
||||
@@ -72,14 +72,16 @@ static IMFS_jnode_t *IMFS_search_in_directory(
|
||||
|
||||
static rtems_filesystem_global_location_t **IMFS_is_mount_point(
|
||||
IMFS_jnode_t *node,
|
||||
IMFS_jnode_types_t type
|
||||
mode_t mode
|
||||
)
|
||||
{
|
||||
rtems_filesystem_global_location_t **fs_root_ptr = NULL;
|
||||
|
||||
if ( type == IMFS_DIRECTORY ) {
|
||||
if ( node->info.directory.mt_fs != NULL ) {
|
||||
fs_root_ptr = &node->info.directory.mt_fs->mt_fs_root;
|
||||
if ( S_ISDIR( mode ) ) {
|
||||
IMFS_directory_t *dir = (IMFS_directory_t *) node;
|
||||
|
||||
if ( dir->mt_fs != NULL ) {
|
||||
fs_root_ptr = &dir->mt_fs->mt_fs_root;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -97,13 +99,13 @@ static rtems_filesystem_eval_path_generic_status IMFS_eval_token(
|
||||
RTEMS_FILESYSTEM_EVAL_PATH_GENERIC_DONE;
|
||||
rtems_filesystem_location_info_t *currentloc =
|
||||
rtems_filesystem_eval_path_get_currentloc( ctx );
|
||||
IMFS_jnode_t *dir = currentloc->node_access;
|
||||
IMFS_directory_t *dir = currentloc->node_access;
|
||||
bool access_ok = rtems_filesystem_eval_path_check_access(
|
||||
ctx,
|
||||
RTEMS_FS_PERMS_EXEC,
|
||||
dir->st_mode,
|
||||
dir->st_uid,
|
||||
dir->st_gid
|
||||
dir->Node.st_mode,
|
||||
dir->Node.st_uid,
|
||||
dir->Node.st_gid
|
||||
);
|
||||
|
||||
if ( access_ok ) {
|
||||
@@ -114,24 +116,27 @@ static rtems_filesystem_eval_path_generic_status IMFS_eval_token(
|
||||
int eval_flags = rtems_filesystem_eval_path_get_flags( ctx );
|
||||
bool follow_hard_link = (eval_flags & RTEMS_FS_FOLLOW_HARD_LINK) != 0;
|
||||
bool follow_sym_link = (eval_flags & RTEMS_FS_FOLLOW_SYM_LINK) != 0;
|
||||
IMFS_jnode_types_t type = IMFS_type( entry );
|
||||
mode_t mode = entry->st_mode;
|
||||
|
||||
rtems_filesystem_eval_path_clear_token( ctx );
|
||||
|
||||
if ( type == IMFS_HARD_LINK && (follow_hard_link || !terminal)) {
|
||||
entry = entry->info.hard_link.link_node;
|
||||
if ( IMFS_is_hard_link( mode ) && ( follow_hard_link || !terminal ) ) {
|
||||
const IMFS_link_t *hard_link = (const IMFS_link_t *) entry;
|
||||
|
||||
entry = hard_link->link_node;
|
||||
}
|
||||
|
||||
if ( type == IMFS_SYM_LINK && (follow_sym_link || !terminal)) {
|
||||
const char *target = entry->info.sym_link.name;
|
||||
if ( S_ISLNK( mode ) && ( follow_sym_link || !terminal ) ) {
|
||||
const IMFS_sym_link_t *sym_link = (const IMFS_sym_link_t *) entry;
|
||||
const char *target = sym_link->name;
|
||||
|
||||
rtems_filesystem_eval_path_recursive( ctx, target, strlen( target ) );
|
||||
} else {
|
||||
rtems_filesystem_global_location_t **fs_root_ptr =
|
||||
IMFS_is_mount_point( entry, type );
|
||||
IMFS_is_mount_point( entry, mode );
|
||||
|
||||
if ( fs_root_ptr == NULL ) {
|
||||
--dir->reference_count;
|
||||
--dir->Node.reference_count;
|
||||
++entry->reference_count;
|
||||
currentloc->node_access = entry;
|
||||
currentloc->node_access_2 =
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
|
||||
#include "imfs.h"
|
||||
|
||||
#define JNODE2PIPE(_jnode) ( (_jnode)->info.fifo.pipe )
|
||||
#define JNODE2PIPE(_jnode) ( ((IMFS_fifo_t *)(_jnode))->pipe )
|
||||
|
||||
#define LIBIO2PIPE(_iop) ( JNODE2PIPE((IMFS_jnode_t *)(_iop)->pathinfo.node_access) )
|
||||
|
||||
@@ -131,8 +131,8 @@ static const rtems_filesystem_file_handlers_r IMFS_fifo_handlers = {
|
||||
};
|
||||
|
||||
const IMFS_node_control IMFS_node_control_fifo = {
|
||||
.imfs_type = IMFS_FIFO,
|
||||
.handlers = &IMFS_fifo_handlers,
|
||||
.node_size = sizeof(IMFS_fifo_t),
|
||||
.node_initialize = IMFS_node_initialize_default,
|
||||
.node_remove = IMFS_node_remove_default,
|
||||
.node_destroy = IMFS_node_destroy_default
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
#include "imfs.h"
|
||||
|
||||
#define jnode_get_control( jnode ) \
|
||||
(&jnode->info.directory.Entries)
|
||||
(&((IMFS_directory_t *) jnode)->Entries)
|
||||
|
||||
#define jnode_has_no_children( jnode ) \
|
||||
rtems_chain_is_empty( jnode_get_control( jnode ) )
|
||||
|
||||
@@ -25,10 +25,9 @@ static int IMFS_stat_device(
|
||||
struct stat *buf
|
||||
)
|
||||
{
|
||||
const IMFS_jnode_t *node = loc->node_access;
|
||||
const IMFS_device_t *io = &node->info.device;
|
||||
const IMFS_device_t *device = loc->node_access;
|
||||
|
||||
buf->st_rdev = rtems_filesystem_make_dev_t( io->major, io->minor );
|
||||
buf->st_rdev = rtems_filesystem_make_dev_t( device->major, device->minor );
|
||||
|
||||
return IMFS_stat( loc, buf );
|
||||
}
|
||||
@@ -53,18 +52,20 @@ static const rtems_filesystem_file_handlers_r IMFS_device_handlers = {
|
||||
|
||||
static IMFS_jnode_t *IMFS_node_initialize_device(
|
||||
IMFS_jnode_t *node,
|
||||
const IMFS_types_union *info
|
||||
void *arg
|
||||
)
|
||||
{
|
||||
node->info.device.major = info->device.major;
|
||||
node->info.device.minor = info->device.minor;
|
||||
IMFS_device_t *device = (IMFS_device_t *) node;
|
||||
dev_t *dev = arg;
|
||||
|
||||
rtems_filesystem_split_dev_t( *dev, device->major, device->minor );
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
const IMFS_node_control IMFS_node_control_device = {
|
||||
.imfs_type = IMFS_DEVICE,
|
||||
.handlers = &IMFS_device_handlers,
|
||||
.node_size = sizeof(IMFS_device_t),
|
||||
.node_initialize = IMFS_node_initialize_device,
|
||||
.node_remove = IMFS_node_remove_default,
|
||||
.node_destroy = IMFS_node_destroy_default
|
||||
|
||||
@@ -25,7 +25,8 @@
|
||||
static size_t IMFS_directory_size( const IMFS_jnode_t *node )
|
||||
{
|
||||
size_t size = 0;
|
||||
const rtems_chain_control *chain = &node->info.directory.Entries;
|
||||
const IMFS_directory_t *dir = (const IMFS_directory_t *) node;
|
||||
const rtems_chain_control *chain = &dir->Entries;
|
||||
const rtems_chain_node *current = rtems_chain_immutable_first( chain );
|
||||
const rtems_chain_node *tail = rtems_chain_immutable_tail( chain );
|
||||
|
||||
@@ -69,37 +70,41 @@ static const rtems_filesystem_file_handlers_r IMFS_directory_handlers = {
|
||||
|
||||
static IMFS_jnode_t *IMFS_node_initialize_directory(
|
||||
IMFS_jnode_t *node,
|
||||
const IMFS_types_union *info
|
||||
void *arg
|
||||
)
|
||||
{
|
||||
rtems_chain_initialize_empty( &node->info.directory.Entries );
|
||||
IMFS_directory_t *dir = (IMFS_directory_t *) node;
|
||||
|
||||
rtems_chain_initialize_empty( &dir->Entries );
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
static bool IMFS_is_mount_point( const IMFS_jnode_t *node )
|
||||
static bool IMFS_is_mount_point( const IMFS_directory_t *dir )
|
||||
{
|
||||
return node->info.directory.mt_fs != NULL;
|
||||
return dir->mt_fs != NULL;
|
||||
}
|
||||
|
||||
static IMFS_jnode_t *IMFS_node_remove_directory(
|
||||
IMFS_jnode_t *node
|
||||
)
|
||||
{
|
||||
if ( !rtems_chain_is_empty( &node->info.directory.Entries ) ) {
|
||||
IMFS_directory_t *dir = (IMFS_directory_t *) node;
|
||||
|
||||
if ( !rtems_chain_is_empty( &dir->Entries ) ) {
|
||||
errno = ENOTEMPTY;
|
||||
node = NULL;
|
||||
} else if ( IMFS_is_mount_point( node ) ) {
|
||||
dir = NULL;
|
||||
} else if ( IMFS_is_mount_point( dir ) ) {
|
||||
errno = EBUSY;
|
||||
node = NULL;
|
||||
dir = NULL;
|
||||
}
|
||||
|
||||
return node;
|
||||
return &dir->Node;
|
||||
}
|
||||
|
||||
const IMFS_node_control IMFS_node_control_directory = {
|
||||
.imfs_type = IMFS_DIRECTORY,
|
||||
.handlers = &IMFS_directory_handlers,
|
||||
.node_size = sizeof(IMFS_directory_t),
|
||||
.node_initialize = IMFS_node_initialize_directory,
|
||||
.node_remove = IMFS_node_remove_directory,
|
||||
.node_destroy = IMFS_node_destroy_default
|
||||
|
||||
@@ -30,14 +30,17 @@ static int IMFS_stat_link(
|
||||
{
|
||||
const IMFS_jnode_t *node = loc->node_access;
|
||||
|
||||
if ( IMFS_type( node ) != IMFS_HARD_LINK ) {
|
||||
buf->st_size = strlen( node->info.sym_link.name );
|
||||
if ( !IMFS_is_hard_link( node->st_mode ) ) {
|
||||
const IMFS_sym_link_t *sym_link = (const IMFS_sym_link_t *) node;
|
||||
|
||||
buf->st_size = strlen( sym_link->name );
|
||||
|
||||
return IMFS_stat( loc, buf );
|
||||
} else {
|
||||
const IMFS_link_t *hard_link = (const IMFS_link_t *) node;
|
||||
rtems_filesystem_location_info_t targetloc = *loc;
|
||||
|
||||
targetloc.node_access = node->info.hard_link.link_node;
|
||||
targetloc.node_access = hard_link->link_node;
|
||||
IMFS_Set_handlers( &targetloc );
|
||||
|
||||
return (targetloc.handlers->fstat_h)( &targetloc, buf );
|
||||
@@ -64,10 +67,12 @@ static const rtems_filesystem_file_handlers_r IMFS_link_handlers = {
|
||||
|
||||
static IMFS_jnode_t *IMFS_node_initialize_hard_link(
|
||||
IMFS_jnode_t *node,
|
||||
const IMFS_types_union *info
|
||||
void *arg
|
||||
)
|
||||
{
|
||||
node->info.hard_link.link_node = info->hard_link.link_node;
|
||||
IMFS_link_t *hard_link = (IMFS_link_t *) node;
|
||||
|
||||
hard_link->link_node = arg;
|
||||
|
||||
return node;
|
||||
}
|
||||
@@ -76,7 +81,8 @@ static IMFS_jnode_t *IMFS_node_remove_hard_link(
|
||||
IMFS_jnode_t *node
|
||||
)
|
||||
{
|
||||
IMFS_jnode_t *target = node->info.hard_link.link_node;
|
||||
IMFS_link_t *hard_link = (IMFS_link_t *) node;
|
||||
IMFS_jnode_t *target = hard_link->link_node;
|
||||
|
||||
_Assert( target != NULL );
|
||||
|
||||
@@ -94,8 +100,8 @@ static IMFS_jnode_t *IMFS_node_remove_hard_link(
|
||||
}
|
||||
|
||||
const IMFS_node_control IMFS_node_control_hard_link = {
|
||||
.imfs_type = IMFS_HARD_LINK,
|
||||
.handlers = &IMFS_link_handlers,
|
||||
.node_size = sizeof(IMFS_link_t),
|
||||
.node_initialize = IMFS_node_initialize_hard_link,
|
||||
.node_remove = IMFS_node_remove_hard_link,
|
||||
.node_destroy = IMFS_node_destroy_default
|
||||
@@ -103,24 +109,28 @@ const IMFS_node_control IMFS_node_control_hard_link = {
|
||||
|
||||
static IMFS_jnode_t *IMFS_node_initialize_sym_link(
|
||||
IMFS_jnode_t *node,
|
||||
const IMFS_types_union *info
|
||||
void *arg
|
||||
)
|
||||
{
|
||||
node->info.sym_link.name = info->sym_link.name;
|
||||
IMFS_sym_link_t *sym_link = (IMFS_sym_link_t *) node;
|
||||
|
||||
sym_link->name = arg;
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
static IMFS_jnode_t *IMFS_node_destroy_sym_link( IMFS_jnode_t *node )
|
||||
static void IMFS_node_destroy_sym_link( IMFS_jnode_t *node )
|
||||
{
|
||||
free( node->info.sym_link.name );
|
||||
IMFS_sym_link_t *sym_link = (IMFS_sym_link_t *) node;
|
||||
|
||||
return node;
|
||||
free( sym_link->name );
|
||||
|
||||
IMFS_node_destroy_default( node );
|
||||
}
|
||||
|
||||
const IMFS_node_control IMFS_node_control_sym_link = {
|
||||
.imfs_type = IMFS_SYM_LINK,
|
||||
.handlers = &IMFS_link_handlers,
|
||||
.node_size = sizeof(IMFS_sym_link_t),
|
||||
.node_initialize = IMFS_node_initialize_sym_link,
|
||||
.node_remove = IMFS_node_remove_default,
|
||||
.node_destroy = IMFS_node_destroy_sym_link
|
||||
|
||||
@@ -25,16 +25,16 @@ static int IMFS_stat_file(
|
||||
struct stat *buf
|
||||
)
|
||||
{
|
||||
const IMFS_jnode_t *node = loc->node_access;
|
||||
const IMFS_file_t *file = loc->node_access;
|
||||
|
||||
buf->st_size = node->info.file.size;
|
||||
buf->st_size = file->File.size;
|
||||
buf->st_blksize = imfs_rq_memfile_bytes_per_block;
|
||||
|
||||
return IMFS_stat( loc, buf );
|
||||
}
|
||||
|
||||
static const rtems_filesystem_file_handlers_r IMFS_memfile_handlers = {
|
||||
.open_h = memfile_open,
|
||||
.open_h = rtems_filesystem_default_open,
|
||||
.close_h = rtems_filesystem_default_close,
|
||||
.read_h = memfile_read,
|
||||
.write_h = memfile_write,
|
||||
@@ -51,17 +51,35 @@ static const rtems_filesystem_file_handlers_r IMFS_memfile_handlers = {
|
||||
.writev_h = rtems_filesystem_default_writev
|
||||
};
|
||||
|
||||
static const rtems_filesystem_file_handlers_r IMFS_linfile_handlers = {
|
||||
.open_h = IMFS_linfile_open,
|
||||
.close_h = rtems_filesystem_default_close,
|
||||
.read_h = IMFS_linfile_read,
|
||||
.write_h = rtems_filesystem_default_write,
|
||||
.ioctl_h = rtems_filesystem_default_ioctl,
|
||||
.lseek_h = rtems_filesystem_default_lseek_file,
|
||||
.fstat_h = IMFS_stat_file,
|
||||
.ftruncate_h = rtems_filesystem_default_ftruncate,
|
||||
.fsync_h = rtems_filesystem_default_fsync_or_fdatasync_success,
|
||||
.fdatasync_h = rtems_filesystem_default_fsync_or_fdatasync_success,
|
||||
.fcntl_h = rtems_filesystem_default_fcntl,
|
||||
.kqfilter_h = rtems_filesystem_default_kqfilter,
|
||||
.poll_h = rtems_filesystem_default_poll,
|
||||
.readv_h = rtems_filesystem_default_readv,
|
||||
.writev_h = rtems_filesystem_default_writev
|
||||
};
|
||||
|
||||
const IMFS_node_control IMFS_node_control_memfile = {
|
||||
.imfs_type = IMFS_MEMORY_FILE,
|
||||
.handlers = &IMFS_memfile_handlers,
|
||||
.node_size = sizeof(IMFS_file_t),
|
||||
.node_initialize = IMFS_node_initialize_default,
|
||||
.node_remove = IMFS_node_remove_default,
|
||||
.node_destroy = IMFS_memfile_remove
|
||||
};
|
||||
|
||||
const IMFS_node_control IMFS_node_control_linfile = {
|
||||
.imfs_type = IMFS_LINEAR_FILE,
|
||||
.handlers = &IMFS_memfile_handlers,
|
||||
.handlers = &IMFS_linfile_handlers,
|
||||
.node_size = sizeof(IMFS_file_t),
|
||||
.node_initialize = IMFS_node_initialize_default,
|
||||
.node_remove = IMFS_node_remove_default,
|
||||
.node_destroy = IMFS_node_destroy_default
|
||||
|
||||
@@ -124,9 +124,7 @@ void IMFS_node_destroy( IMFS_jnode_t *node )
|
||||
{
|
||||
IMFS_assert( node->reference_count == 0 );
|
||||
|
||||
node = (*node->control->node_destroy)( node );
|
||||
|
||||
free( node );
|
||||
(*node->control->node_destroy)( node );
|
||||
}
|
||||
|
||||
void IMFS_node_free( const rtems_filesystem_location_info_t *loc )
|
||||
@@ -142,7 +140,7 @@ void IMFS_node_free( const rtems_filesystem_location_info_t *loc )
|
||||
|
||||
static IMFS_jnode_t *IMFS_node_initialize_enosys(
|
||||
IMFS_jnode_t *node,
|
||||
const IMFS_types_union *info
|
||||
void *arg
|
||||
)
|
||||
{
|
||||
errno = ENOSYS;
|
||||
@@ -152,7 +150,7 @@ static IMFS_jnode_t *IMFS_node_initialize_enosys(
|
||||
|
||||
IMFS_jnode_t *IMFS_node_initialize_default(
|
||||
IMFS_jnode_t *node,
|
||||
const IMFS_types_union *info
|
||||
void *arg
|
||||
)
|
||||
{
|
||||
return node;
|
||||
@@ -165,14 +163,14 @@ IMFS_jnode_t *IMFS_node_remove_default(
|
||||
return node;
|
||||
}
|
||||
|
||||
IMFS_jnode_t *IMFS_node_destroy_default( IMFS_jnode_t *node )
|
||||
void IMFS_node_destroy_default( IMFS_jnode_t *node )
|
||||
{
|
||||
return node;
|
||||
free( node );
|
||||
}
|
||||
|
||||
const IMFS_node_control IMFS_node_control_enosys = {
|
||||
.imfs_type = IMFS_INVALID_NODE,
|
||||
.handlers = &rtems_filesystem_handlers_default,
|
||||
.node_size = sizeof(IMFS_jnode_t),
|
||||
.node_initialize = IMFS_node_initialize_enosys,
|
||||
.node_remove = IMFS_node_remove_default,
|
||||
.node_destroy = IMFS_node_destroy_default
|
||||
|
||||
@@ -27,12 +27,10 @@ int IMFS_link(
|
||||
size_t namelen
|
||||
)
|
||||
{
|
||||
IMFS_types_union info;
|
||||
IMFS_jnode_t *new_node;
|
||||
IMFS_jnode_t *target;
|
||||
IMFS_jnode_t *new_node;
|
||||
IMFS_jnode_t *target;
|
||||
|
||||
target = targetloc->node_access;
|
||||
info.hard_link.link_node = target;
|
||||
|
||||
/*
|
||||
* Verify this node can be linked to.
|
||||
@@ -48,8 +46,8 @@ int IMFS_link(
|
||||
IMFS_HARD_LINK,
|
||||
name,
|
||||
namelen,
|
||||
( S_IFLNK | ( S_IRWXU | S_IRWXG | S_IRWXO )),
|
||||
&info
|
||||
IMFS_STAT_FMT_HARD_LINK | ( S_IRWXU | S_IRWXG | S_IRWXO ),
|
||||
target
|
||||
);
|
||||
|
||||
if ( !new_node )
|
||||
|
||||
@@ -45,7 +45,6 @@ int rtems_tarfs_load(
|
||||
unsigned long file_mode;
|
||||
int offset;
|
||||
unsigned long nblocks;
|
||||
IMFS_jnode_t *node;
|
||||
int rv = 0;
|
||||
int eval_flags = RTEMS_FS_FOLLOW_LINK;
|
||||
rtems_filesystem_eval_path_context_t ctx;
|
||||
@@ -123,16 +122,20 @@ int rtems_tarfs_load(
|
||||
rtems_filesystem_eval_path_continue( &ctx );
|
||||
|
||||
if ( !rtems_filesystem_location_is_null( currentloc ) ) {
|
||||
node = IMFS_create_node(
|
||||
currentloc,
|
||||
IMFS_LINEAR_FILE,
|
||||
rtems_filesystem_eval_path_get_token( &ctx ),
|
||||
rtems_filesystem_eval_path_get_tokenlen( &ctx ),
|
||||
(file_mode & (S_IRWXU | S_IRWXG | S_IRWXO)) | S_IFREG,
|
||||
NULL
|
||||
);
|
||||
node->info.linearfile.size = file_size;
|
||||
node->info.linearfile.direct = &tar_image[offset];
|
||||
IMFS_linearfile_t *linfile = (IMFS_linearfile_t *)
|
||||
IMFS_create_node(
|
||||
currentloc,
|
||||
IMFS_LINEAR_FILE,
|
||||
rtems_filesystem_eval_path_get_token( &ctx ),
|
||||
rtems_filesystem_eval_path_get_tokenlen( &ctx ),
|
||||
(file_mode & (S_IRWXU | S_IRWXG | S_IRWXO)) | S_IFREG,
|
||||
NULL
|
||||
);
|
||||
|
||||
if ( linfile != NULL ) {
|
||||
linfile->File.size = file_size;
|
||||
linfile->direct = &tar_image[offset];
|
||||
}
|
||||
}
|
||||
|
||||
nblocks = (((file_size) + 511) & ~511) / 512;
|
||||
|
||||
@@ -29,10 +29,12 @@
|
||||
|
||||
IMFS_jnode_t *IMFS_node_initialize_generic(
|
||||
IMFS_jnode_t *node,
|
||||
const IMFS_types_union *info
|
||||
void *arg
|
||||
)
|
||||
{
|
||||
node->info.generic.context = info->generic.context;
|
||||
IMFS_generic_t *generic = (IMFS_generic_t *) node;
|
||||
|
||||
generic->context = arg;
|
||||
|
||||
return node;
|
||||
}
|
||||
@@ -72,45 +74,36 @@ int IMFS_make_generic_node(
|
||||
}
|
||||
|
||||
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 );
|
||||
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;
|
||||
if ( IMFS_is_imfs_instance( currentloc ) ) {
|
||||
IMFS_jnode_t *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,
|
||||
context
|
||||
);
|
||||
|
||||
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;
|
||||
|
||||
if ( new_node != NULL ) {
|
||||
IMFS_jnode_t *parent = currentloc->node_access;
|
||||
|
||||
IMFS_mtime_ctime_update( parent );
|
||||
} else {
|
||||
rv = -1;
|
||||
}
|
||||
IMFS_mtime_ctime_update( parent );
|
||||
} else {
|
||||
rtems_filesystem_eval_path_error( &ctx, ENOTSUP );
|
||||
rv = -1;
|
||||
}
|
||||
|
||||
rtems_filesystem_eval_path_cleanup( &ctx );
|
||||
} else {
|
||||
errno = EINVAL;
|
||||
rtems_filesystem_eval_path_error( &ctx, ENOTSUP );
|
||||
rv = -1;
|
||||
}
|
||||
|
||||
rtems_filesystem_eval_path_cleanup( &ctx );
|
||||
}
|
||||
|
||||
return rv;
|
||||
|
||||
@@ -23,27 +23,17 @@
|
||||
|
||||
#include "imfs.h"
|
||||
|
||||
static void get_type_and_info_by_mode_and_dev(
|
||||
mode_t mode,
|
||||
dev_t dev,
|
||||
IMFS_jnode_types_t *type,
|
||||
IMFS_types_union *info
|
||||
)
|
||||
static IMFS_jnode_types_t get_type( mode_t mode )
|
||||
{
|
||||
if ( S_ISDIR( mode ) ) {
|
||||
*type = IMFS_DIRECTORY;
|
||||
return IMFS_DIRECTORY;
|
||||
} else if ( S_ISBLK( mode ) || S_ISCHR( mode ) ) {
|
||||
*type = IMFS_DEVICE;
|
||||
rtems_filesystem_split_dev_t(
|
||||
dev,
|
||||
info->device.major,
|
||||
info->device.minor
|
||||
);
|
||||
return IMFS_DEVICE;
|
||||
} else if (S_ISFIFO( mode )) {
|
||||
*type = IMFS_FIFO;
|
||||
return IMFS_FIFO;
|
||||
} else {
|
||||
IMFS_assert( S_ISREG( mode ) );
|
||||
*type = IMFS_MEMORY_FILE;
|
||||
return IMFS_MEMORY_FILE;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -57,12 +47,11 @@ int IMFS_mknod(
|
||||
{
|
||||
int rv = 0;
|
||||
IMFS_jnode_types_t type;
|
||||
IMFS_types_union info;
|
||||
IMFS_jnode_t *new_node;
|
||||
|
||||
get_type_and_info_by_mode_and_dev( mode, dev, &type, &info );
|
||||
type = get_type( mode );
|
||||
|
||||
new_node = IMFS_create_node( parentloc, type, name, namelen, mode, &info );
|
||||
new_node = IMFS_create_node( parentloc, type, name, namelen, mode, &dev );
|
||||
if ( new_node != NULL ) {
|
||||
IMFS_jnode_t *parent = parentloc->node_access;
|
||||
|
||||
|
||||
@@ -29,8 +29,10 @@ int IMFS_mount( rtems_filesystem_mount_table_entry_t *mt_entry )
|
||||
IMFS_jnode_t *node = mt_entry->mt_point_node->location.node_access;
|
||||
|
||||
if ( IMFS_is_directory( node ) ) {
|
||||
if ( node->info.directory.mt_fs == NULL ) {
|
||||
node->info.directory.mt_fs = mt_entry;
|
||||
IMFS_directory_t *dir = (IMFS_directory_t *) node;
|
||||
|
||||
if ( dir->mt_fs == NULL ) {
|
||||
dir->mt_fs = mt_entry;
|
||||
} else {
|
||||
errno = EBUSY;
|
||||
rv = -1;
|
||||
|
||||
@@ -26,15 +26,13 @@ ssize_t IMFS_readlink(
|
||||
size_t bufsize
|
||||
)
|
||||
{
|
||||
IMFS_jnode_t *node;
|
||||
IMFS_sym_link_t *sym_link;
|
||||
ssize_t i;
|
||||
|
||||
node = loc->node_access;
|
||||
sym_link = loc->node_access;
|
||||
|
||||
IMFS_assert( node->control->imfs_type == IMFS_SYM_LINK );
|
||||
|
||||
for( i=0; ((i<bufsize) && (node->info.sym_link.name[i] != '\0')); i++ )
|
||||
buf[i] = node->info.sym_link.name[i];
|
||||
for( i=0; ((i<bufsize) && (sym_link->name[i] != '\0')); i++ )
|
||||
buf[i] = sym_link->name[i];
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
@@ -30,14 +30,14 @@ int IMFS_symlink(
|
||||
const char *target
|
||||
)
|
||||
{
|
||||
IMFS_types_union info;
|
||||
IMFS_jnode_t *new_node;
|
||||
char *dup_target;
|
||||
IMFS_jnode_t *new_node;
|
||||
|
||||
/*
|
||||
* Duplicate link name
|
||||
*/
|
||||
info.sym_link.name = strdup(target);
|
||||
if (info.sym_link.name == NULL) {
|
||||
dup_target = strdup(target);
|
||||
if (dup_target == NULL) {
|
||||
rtems_set_errno_and_return_minus_one(ENOMEM);
|
||||
}
|
||||
|
||||
@@ -50,11 +50,11 @@ int IMFS_symlink(
|
||||
name,
|
||||
namelen,
|
||||
( S_IFLNK | ( S_IRWXU | S_IRWXG | S_IRWXO )),
|
||||
&info
|
||||
dup_target
|
||||
);
|
||||
|
||||
if (new_node == NULL) {
|
||||
free(info.sym_link.name);
|
||||
free(dup_target);
|
||||
rtems_set_errno_and_return_minus_one(ENOMEM);
|
||||
}
|
||||
|
||||
|
||||
@@ -29,8 +29,10 @@ int IMFS_unmount( rtems_filesystem_mount_table_entry_t *mt_entry )
|
||||
IMFS_jnode_t *node = mt_entry->mt_point_node->location.node_access;
|
||||
|
||||
if ( IMFS_is_directory( node ) ) {
|
||||
if ( node->info.directory.mt_fs == mt_entry ) {
|
||||
node->info.directory.mt_fs = NULL;
|
||||
IMFS_directory_t *dir = (IMFS_directory_t *) node;
|
||||
|
||||
if ( dir->mt_fs == mt_entry ) {
|
||||
dir->mt_fs = NULL;
|
||||
} else {
|
||||
errno = EINVAL;
|
||||
rv = -1;
|
||||
|
||||
+118
-126
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user