forked from Imagelibrary/rtems
IMFS: Replace node union with individual struct
This reduces the average node size. Add and use IMFS_GENERIC_INITIALIZER().
This commit is contained in:
@@ -223,23 +223,21 @@ static const rtems_filesystem_file_handlers_r i2c_bus_handler = {
|
||||
.writev_h = rtems_filesystem_default_writev
|
||||
};
|
||||
|
||||
static IMFS_jnode_t *i2c_bus_node_destroy(IMFS_jnode_t *node)
|
||||
static void i2c_bus_node_destroy(IMFS_jnode_t *node)
|
||||
{
|
||||
i2c_bus *bus;
|
||||
|
||||
bus = IMFS_generic_get_context_by_node(node);
|
||||
(*bus->destroy)(bus);
|
||||
|
||||
return node;
|
||||
IMFS_node_destroy_default(node);
|
||||
}
|
||||
|
||||
static const IMFS_node_control i2c_bus_node_control = {
|
||||
.imfs_type = IMFS_GENERIC,
|
||||
.handlers = &i2c_bus_handler,
|
||||
.node_initialize = IMFS_node_initialize_generic,
|
||||
.node_remove = IMFS_node_remove_default,
|
||||
.node_destroy = i2c_bus_node_destroy
|
||||
};
|
||||
static const IMFS_node_control i2c_bus_node_control = IMFS_GENERIC_INITIALIZER(
|
||||
&i2c_bus_handler,
|
||||
IMFS_node_initialize_generic,
|
||||
i2c_bus_node_destroy
|
||||
);
|
||||
|
||||
int i2c_bus_register(
|
||||
i2c_bus *bus,
|
||||
|
||||
@@ -116,23 +116,21 @@ static const rtems_filesystem_file_handlers_r i2c_dev_handler = {
|
||||
.writev_h = rtems_filesystem_default_writev
|
||||
};
|
||||
|
||||
static IMFS_jnode_t *i2c_dev_node_destroy(IMFS_jnode_t *node)
|
||||
static void i2c_dev_node_destroy(IMFS_jnode_t *node)
|
||||
{
|
||||
i2c_dev *dev;
|
||||
|
||||
dev = IMFS_generic_get_context_by_node(node);
|
||||
(*dev->destroy)(dev);
|
||||
|
||||
return node;
|
||||
IMFS_node_destroy_default(node);
|
||||
}
|
||||
|
||||
static const IMFS_node_control i2c_dev_node_control = {
|
||||
.imfs_type = IMFS_GENERIC,
|
||||
.handlers = &i2c_dev_handler,
|
||||
.node_initialize = IMFS_node_initialize_generic,
|
||||
.node_remove = IMFS_node_remove_default,
|
||||
.node_destroy = i2c_dev_node_destroy
|
||||
};
|
||||
static const IMFS_node_control i2c_dev_node_control = IMFS_GENERIC_INITIALIZER(
|
||||
&i2c_dev_handler,
|
||||
IMFS_node_initialize_generic,
|
||||
i2c_dev_node_destroy
|
||||
);
|
||||
|
||||
int i2c_dev_register(
|
||||
i2c_dev *dev,
|
||||
|
||||
@@ -229,13 +229,13 @@ static const rtems_filesystem_file_handlers_r rtems_blkdev_imfs_node = {
|
||||
|
||||
static IMFS_jnode_t *rtems_blkdev_imfs_initialize(
|
||||
IMFS_jnode_t *node,
|
||||
const IMFS_types_union *info
|
||||
void *arg
|
||||
)
|
||||
{
|
||||
rtems_blkdev_imfs_context *ctx;
|
||||
rtems_disk_device *dd;
|
||||
|
||||
node = IMFS_node_initialize_generic(node, info);
|
||||
node = IMFS_node_initialize_generic(node, arg);
|
||||
|
||||
ctx = IMFS_generic_get_context_by_node(node);
|
||||
dd = &ctx->dd;
|
||||
@@ -244,7 +244,7 @@ static IMFS_jnode_t *rtems_blkdev_imfs_initialize(
|
||||
return node;
|
||||
}
|
||||
|
||||
static IMFS_jnode_t *rtems_blkdev_imfs_destroy(IMFS_jnode_t *node)
|
||||
static void rtems_blkdev_imfs_destroy(IMFS_jnode_t *node)
|
||||
{
|
||||
rtems_blkdev_imfs_context *ctx = IMFS_generic_get_context_by_node(node);
|
||||
rtems_disk_device *dd = &ctx->dd;
|
||||
@@ -260,16 +260,15 @@ static IMFS_jnode_t *rtems_blkdev_imfs_destroy(IMFS_jnode_t *node)
|
||||
|
||||
free(ctx);
|
||||
|
||||
return node;
|
||||
IMFS_node_destroy_default(node);
|
||||
}
|
||||
|
||||
static const IMFS_node_control rtems_blkdev_imfs_control = {
|
||||
.imfs_type = IMFS_GENERIC,
|
||||
.handlers = &rtems_blkdev_imfs_node,
|
||||
.node_initialize = rtems_blkdev_imfs_initialize,
|
||||
.node_remove = IMFS_node_remove_default,
|
||||
.node_destroy = rtems_blkdev_imfs_destroy
|
||||
};
|
||||
static const IMFS_node_control rtems_blkdev_imfs_control =
|
||||
IMFS_GENERIC_INITIALIZER(
|
||||
&rtems_blkdev_imfs_node,
|
||||
rtems_blkdev_imfs_initialize,
|
||||
rtems_blkdev_imfs_destroy
|
||||
);
|
||||
|
||||
rtems_status_code rtems_blkdev_create(
|
||||
const char *device,
|
||||
|
||||
@@ -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
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -29,36 +29,36 @@
|
||||
* Prototypes of private routines
|
||||
*/
|
||||
MEMFILE_STATIC int IMFS_memfile_extend(
|
||||
IMFS_jnode_t *the_jnode,
|
||||
bool zero_fill,
|
||||
off_t new_length
|
||||
IMFS_memfile_t *memfile,
|
||||
bool zero_fill,
|
||||
off_t new_length
|
||||
);
|
||||
|
||||
MEMFILE_STATIC int IMFS_memfile_addblock(
|
||||
IMFS_jnode_t *the_jnode,
|
||||
unsigned int block
|
||||
IMFS_memfile_t *memfile,
|
||||
unsigned int block
|
||||
);
|
||||
|
||||
MEMFILE_STATIC void IMFS_memfile_remove_block(
|
||||
IMFS_jnode_t *the_jnode,
|
||||
unsigned int block
|
||||
IMFS_memfile_t *memfile,
|
||||
unsigned int block
|
||||
);
|
||||
|
||||
MEMFILE_STATIC block_p *IMFS_memfile_get_block_pointer(
|
||||
IMFS_jnode_t *the_jnode,
|
||||
IMFS_memfile_t *memfile,
|
||||
unsigned int block,
|
||||
int malloc_it
|
||||
);
|
||||
|
||||
MEMFILE_STATIC ssize_t IMFS_memfile_read(
|
||||
IMFS_jnode_t *the_jnode,
|
||||
IMFS_file_t *file,
|
||||
off_t start,
|
||||
unsigned char *destination,
|
||||
unsigned int length
|
||||
);
|
||||
|
||||
ssize_t IMFS_memfile_write( /* cannot be static as used in imfs_fchmod.c */
|
||||
IMFS_jnode_t *the_jnode,
|
||||
IMFS_memfile_t *memfile,
|
||||
off_t start,
|
||||
const unsigned char *source,
|
||||
unsigned int length
|
||||
@@ -70,50 +70,68 @@ void memfile_free_block(
|
||||
void *memory
|
||||
);
|
||||
|
||||
int memfile_open(
|
||||
int IMFS_linfile_open(
|
||||
rtems_libio_t *iop,
|
||||
const char *pathname,
|
||||
int oflag,
|
||||
mode_t mode
|
||||
)
|
||||
{
|
||||
IMFS_jnode_t *the_jnode;
|
||||
IMFS_file_t *file;
|
||||
|
||||
the_jnode = iop->pathinfo.node_access;
|
||||
file = iop->pathinfo.node_access;
|
||||
|
||||
/*
|
||||
* Perform 'copy on write' for linear files
|
||||
*/
|
||||
if ((iop->flags & LIBIO_FLAGS_WRITE)
|
||||
&& (IMFS_type( the_jnode ) == IMFS_LINEAR_FILE)) {
|
||||
uint32_t count = the_jnode->info.linearfile.size;
|
||||
const unsigned char *buffer = the_jnode->info.linearfile.direct;
|
||||
if ((iop->flags & LIBIO_FLAGS_WRITE) != 0) {
|
||||
uint32_t count = file->File.size;
|
||||
const unsigned char *buffer = file->Linearfile.direct;
|
||||
|
||||
the_jnode->control = &IMFS_node_control_memfile;
|
||||
the_jnode->info.file.size = 0;
|
||||
the_jnode->info.file.indirect = 0;
|
||||
the_jnode->info.file.doubly_indirect = 0;
|
||||
the_jnode->info.file.triply_indirect = 0;
|
||||
file->Node.control = &IMFS_node_control_memfile;
|
||||
file->File.size = 0;
|
||||
file->Memfile.indirect = 0;
|
||||
file->Memfile.doubly_indirect = 0;
|
||||
file->Memfile.triply_indirect = 0;
|
||||
if ((count != 0)
|
||||
&& (IMFS_memfile_write(the_jnode, 0, buffer, count) == -1))
|
||||
&& (IMFS_memfile_write(&file->Memfile, 0, buffer, count) == -1))
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
ssize_t IMFS_linfile_read(
|
||||
rtems_libio_t *iop,
|
||||
void *buffer,
|
||||
size_t count
|
||||
)
|
||||
{
|
||||
IMFS_file_t *file = IMFS_iop_to_file( iop );
|
||||
off_t start = iop->offset;
|
||||
size_t size = file->File.size;
|
||||
const unsigned char *data = file->Linearfile.direct;
|
||||
|
||||
if (count > size - start)
|
||||
count = size - start;
|
||||
|
||||
IMFS_update_atime( &file->Node );
|
||||
iop->offset = start + count;
|
||||
memcpy(buffer, &data[start], count);
|
||||
|
||||
return (ssize_t) count;
|
||||
}
|
||||
|
||||
ssize_t memfile_read(
|
||||
rtems_libio_t *iop,
|
||||
void *buffer,
|
||||
size_t count
|
||||
)
|
||||
{
|
||||
IMFS_jnode_t *the_jnode;
|
||||
ssize_t status;
|
||||
IMFS_file_t *file = IMFS_iop_to_file( iop );
|
||||
ssize_t status;
|
||||
|
||||
the_jnode = iop->pathinfo.node_access;
|
||||
|
||||
status = IMFS_memfile_read( the_jnode, iop->offset, buffer, count );
|
||||
status = IMFS_memfile_read( file, iop->offset, buffer, count );
|
||||
|
||||
if ( status > 0 )
|
||||
iop->offset += status;
|
||||
@@ -127,15 +145,13 @@ ssize_t memfile_write(
|
||||
size_t count
|
||||
)
|
||||
{
|
||||
IMFS_jnode_t *the_jnode;
|
||||
IMFS_memfile_t *memfile = IMFS_iop_to_memfile( iop );
|
||||
ssize_t status;
|
||||
|
||||
the_jnode = iop->pathinfo.node_access;
|
||||
|
||||
if ((iop->flags & LIBIO_FLAGS_APPEND) != 0)
|
||||
iop->offset = the_jnode->info.file.size;
|
||||
iop->offset = memfile->File.size;
|
||||
|
||||
status = IMFS_memfile_write( the_jnode, iop->offset, buffer, count );
|
||||
status = IMFS_memfile_write( memfile, iop->offset, buffer, count );
|
||||
|
||||
if ( status > 0 )
|
||||
iop->offset += status;
|
||||
@@ -154,9 +170,7 @@ int memfile_ftruncate(
|
||||
off_t length
|
||||
)
|
||||
{
|
||||
IMFS_jnode_t *the_jnode;
|
||||
|
||||
the_jnode = iop->pathinfo.node_access;
|
||||
IMFS_memfile_t *memfile = IMFS_iop_to_memfile( iop );
|
||||
|
||||
/*
|
||||
* POSIX 1003.1b does not specify what happens if you truncate a file
|
||||
@@ -164,17 +178,17 @@ int memfile_ftruncate(
|
||||
* as an extend operation.
|
||||
*/
|
||||
|
||||
if ( length > the_jnode->info.file.size )
|
||||
return IMFS_memfile_extend( the_jnode, true, length );
|
||||
if ( length > memfile->File.size )
|
||||
return IMFS_memfile_extend( memfile, true, length );
|
||||
|
||||
/*
|
||||
* The in-memory files do not currently reclaim memory until the file is
|
||||
* deleted. So we leave the previously allocated blocks in place for
|
||||
* future use and just set the length.
|
||||
*/
|
||||
the_jnode->info.file.size = length;
|
||||
memfile->File.size = length;
|
||||
|
||||
IMFS_mtime_ctime_update(the_jnode);
|
||||
IMFS_mtime_ctime_update( &memfile->File.Node );
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -187,9 +201,9 @@ int memfile_ftruncate(
|
||||
* extend the file.
|
||||
*/
|
||||
MEMFILE_STATIC int IMFS_memfile_extend(
|
||||
IMFS_jnode_t *the_jnode,
|
||||
bool zero_fill,
|
||||
off_t new_length
|
||||
IMFS_memfile_t *memfile,
|
||||
bool zero_fill,
|
||||
off_t new_length
|
||||
)
|
||||
{
|
||||
unsigned int block;
|
||||
@@ -200,8 +214,7 @@ MEMFILE_STATIC int IMFS_memfile_extend(
|
||||
/*
|
||||
* Perform internal consistency checks
|
||||
*/
|
||||
IMFS_assert( the_jnode );
|
||||
IMFS_assert( IMFS_type( the_jnode ) == IMFS_MEMORY_FILE );
|
||||
IMFS_assert( memfile );
|
||||
|
||||
/*
|
||||
* Verify new file size is supported
|
||||
@@ -212,32 +225,32 @@ MEMFILE_STATIC int IMFS_memfile_extend(
|
||||
/*
|
||||
* Verify new file size is actually larger than current size
|
||||
*/
|
||||
if ( new_length <= the_jnode->info.file.size )
|
||||
if ( new_length <= memfile->File.size )
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* Calculate the number of range of blocks to allocate
|
||||
*/
|
||||
new_blocks = new_length / IMFS_MEMFILE_BYTES_PER_BLOCK;
|
||||
old_blocks = the_jnode->info.file.size / IMFS_MEMFILE_BYTES_PER_BLOCK;
|
||||
offset = the_jnode->info.file.size - old_blocks * IMFS_MEMFILE_BYTES_PER_BLOCK;
|
||||
old_blocks = memfile->File.size / IMFS_MEMFILE_BYTES_PER_BLOCK;
|
||||
offset = memfile->File.size - old_blocks * IMFS_MEMFILE_BYTES_PER_BLOCK;
|
||||
|
||||
/*
|
||||
* Now allocate each of those blocks.
|
||||
*/
|
||||
for ( block=old_blocks ; block<=new_blocks ; block++ ) {
|
||||
if ( !IMFS_memfile_addblock( the_jnode, block ) ) {
|
||||
if ( !IMFS_memfile_addblock( memfile, block ) ) {
|
||||
if ( zero_fill ) {
|
||||
size_t count = IMFS_MEMFILE_BYTES_PER_BLOCK - offset;
|
||||
block_p *block_ptr =
|
||||
IMFS_memfile_get_block_pointer( the_jnode, block, 0 );
|
||||
IMFS_memfile_get_block_pointer( memfile, block, 0 );
|
||||
|
||||
memset( &(*block_ptr) [offset], 0, count);
|
||||
offset = 0;
|
||||
}
|
||||
} else {
|
||||
for ( ; block>=old_blocks ; block-- ) {
|
||||
IMFS_memfile_remove_block( the_jnode, block );
|
||||
IMFS_memfile_remove_block( memfile, block );
|
||||
}
|
||||
rtems_set_errno_and_return_minus_one( ENOSPC );
|
||||
}
|
||||
@@ -246,9 +259,10 @@ MEMFILE_STATIC int IMFS_memfile_extend(
|
||||
/*
|
||||
* Set the new length of the file.
|
||||
*/
|
||||
the_jnode->info.file.size = new_length;
|
||||
memfile->File.size = new_length;
|
||||
|
||||
IMFS_mtime_ctime_update( &memfile->File.Node );
|
||||
|
||||
IMFS_mtime_ctime_update(the_jnode);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -258,20 +272,19 @@ MEMFILE_STATIC int IMFS_memfile_extend(
|
||||
* This routine adds a single block to the specified in-memory file.
|
||||
*/
|
||||
MEMFILE_STATIC int IMFS_memfile_addblock(
|
||||
IMFS_jnode_t *the_jnode,
|
||||
unsigned int block
|
||||
IMFS_memfile_t *memfile,
|
||||
unsigned int block
|
||||
)
|
||||
{
|
||||
block_p memory;
|
||||
block_p *block_entry_ptr;
|
||||
|
||||
IMFS_assert( the_jnode );
|
||||
IMFS_assert( IMFS_type( the_jnode ) == IMFS_MEMORY_FILE );
|
||||
IMFS_assert( memfile );
|
||||
|
||||
/*
|
||||
* Obtain the pointer for the specified block number
|
||||
*/
|
||||
block_entry_ptr = IMFS_memfile_get_block_pointer( the_jnode, block, 1 );
|
||||
block_entry_ptr = IMFS_memfile_get_block_pointer( memfile, block, 1 );
|
||||
if ( !block_entry_ptr )
|
||||
return 1;
|
||||
|
||||
@@ -300,14 +313,14 @@ MEMFILE_STATIC int IMFS_memfile_addblock(
|
||||
* dangerous and the results unpredictable.
|
||||
*/
|
||||
MEMFILE_STATIC void IMFS_memfile_remove_block(
|
||||
IMFS_jnode_t *the_jnode,
|
||||
unsigned int block
|
||||
IMFS_memfile_t *memfile,
|
||||
unsigned int block
|
||||
)
|
||||
{
|
||||
block_p *block_ptr;
|
||||
block_p ptr;
|
||||
|
||||
block_ptr = IMFS_memfile_get_block_pointer( the_jnode, block, 0 );
|
||||
block_ptr = IMFS_memfile_get_block_pointer( memfile, block, 0 );
|
||||
if ( block_ptr ) {
|
||||
ptr = *block_ptr;
|
||||
*block_ptr = 0;
|
||||
@@ -372,21 +385,22 @@ static void memfile_free_blocks_in_table(
|
||||
* Regardless until the IMFS implementation is proven, it
|
||||
* is better to stick to simple, easy to understand algorithms.
|
||||
*/
|
||||
IMFS_jnode_t *IMFS_memfile_remove(
|
||||
void IMFS_memfile_remove(
|
||||
IMFS_jnode_t *the_jnode
|
||||
)
|
||||
{
|
||||
IMFS_memfile_t *info;
|
||||
IMFS_memfile_t *memfile;
|
||||
int i;
|
||||
int j;
|
||||
unsigned int to_free;
|
||||
block_p *p;
|
||||
|
||||
memfile = (IMFS_memfile_t *) the_jnode;
|
||||
|
||||
/*
|
||||
* Perform internal consistency checks
|
||||
*/
|
||||
IMFS_assert( the_jnode );
|
||||
IMFS_assert( IMFS_type( the_jnode ) == IMFS_MEMORY_FILE );
|
||||
IMFS_assert( memfile );
|
||||
|
||||
/*
|
||||
* Eventually this could be set smarter at each call to
|
||||
@@ -400,26 +414,25 @@ IMFS_jnode_t *IMFS_memfile_remove(
|
||||
* + doubly indirect
|
||||
* + triply indirect
|
||||
*/
|
||||
info = &the_jnode->info.file;
|
||||
|
||||
if ( info->indirect ) {
|
||||
memfile_free_blocks_in_table( &info->indirect, to_free );
|
||||
if ( memfile->indirect ) {
|
||||
memfile_free_blocks_in_table( &memfile->indirect, to_free );
|
||||
}
|
||||
|
||||
if ( info->doubly_indirect ) {
|
||||
if ( memfile->doubly_indirect ) {
|
||||
for ( i=0 ; i<IMFS_MEMFILE_BLOCK_SLOTS ; i++ ) {
|
||||
if ( info->doubly_indirect[i] ) {
|
||||
if ( memfile->doubly_indirect[i] ) {
|
||||
memfile_free_blocks_in_table(
|
||||
(block_p **)&info->doubly_indirect[i], to_free );
|
||||
(block_p **)&memfile->doubly_indirect[i], to_free );
|
||||
}
|
||||
}
|
||||
memfile_free_blocks_in_table( &info->doubly_indirect, to_free );
|
||||
memfile_free_blocks_in_table( &memfile->doubly_indirect, to_free );
|
||||
|
||||
}
|
||||
|
||||
if ( info->triply_indirect ) {
|
||||
if ( memfile->triply_indirect ) {
|
||||
for ( i=0 ; i<IMFS_MEMFILE_BLOCK_SLOTS ; i++ ) {
|
||||
p = (block_p *) info->triply_indirect[i];
|
||||
p = (block_p *) memfile->triply_indirect[i];
|
||||
if ( !p ) /* ensure we have a valid pointer */
|
||||
break;
|
||||
for ( j=0 ; j<IMFS_MEMFILE_BLOCK_SLOTS ; j++ ) {
|
||||
@@ -428,13 +441,13 @@ IMFS_jnode_t *IMFS_memfile_remove(
|
||||
}
|
||||
}
|
||||
memfile_free_blocks_in_table(
|
||||
(block_p **)&info->triply_indirect[i], to_free );
|
||||
(block_p **)&memfile->triply_indirect[i], to_free );
|
||||
}
|
||||
memfile_free_blocks_in_table(
|
||||
(block_p **)&info->triply_indirect, to_free );
|
||||
(block_p **)&memfile->triply_indirect, to_free );
|
||||
}
|
||||
|
||||
return the_jnode;
|
||||
IMFS_node_destroy_default( the_jnode );
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -449,7 +462,7 @@ IMFS_jnode_t *IMFS_memfile_remove(
|
||||
* read).
|
||||
*/
|
||||
MEMFILE_STATIC ssize_t IMFS_memfile_read(
|
||||
IMFS_jnode_t *the_jnode,
|
||||
IMFS_file_t *file,
|
||||
off_t start,
|
||||
unsigned char *destination,
|
||||
unsigned int length
|
||||
@@ -469,9 +482,7 @@ MEMFILE_STATIC ssize_t IMFS_memfile_read(
|
||||
/*
|
||||
* Perform internal consistency checks
|
||||
*/
|
||||
IMFS_assert( the_jnode );
|
||||
IMFS_assert( IMFS_type( the_jnode ) == IMFS_MEMORY_FILE ||
|
||||
IMFS_type( the_jnode ) == IMFS_LINEAR_FILE );
|
||||
IMFS_assert( file );
|
||||
IMFS_assert( dest );
|
||||
|
||||
/*
|
||||
@@ -480,28 +491,13 @@ MEMFILE_STATIC ssize_t IMFS_memfile_read(
|
||||
*/
|
||||
my_length = length;
|
||||
|
||||
if ( IMFS_type( the_jnode ) == IMFS_LINEAR_FILE ) {
|
||||
unsigned char *file_ptr;
|
||||
|
||||
file_ptr = (unsigned char *)the_jnode->info.linearfile.direct;
|
||||
|
||||
if (my_length > (the_jnode->info.linearfile.size - start))
|
||||
my_length = the_jnode->info.linearfile.size - start;
|
||||
|
||||
memcpy(dest, &file_ptr[start], my_length);
|
||||
|
||||
IMFS_update_atime( the_jnode );
|
||||
|
||||
return my_length;
|
||||
}
|
||||
|
||||
/*
|
||||
* If the last byte we are supposed to read is past the end of this
|
||||
* in memory file, then shorten the length to read.
|
||||
*/
|
||||
last_byte = start + length;
|
||||
if ( last_byte > the_jnode->info.file.size )
|
||||
my_length = the_jnode->info.file.size - start;
|
||||
if ( last_byte > file->Memfile.File.size )
|
||||
my_length = file->Memfile.File.size - start;
|
||||
|
||||
copied = 0;
|
||||
|
||||
@@ -521,7 +517,7 @@ MEMFILE_STATIC ssize_t IMFS_memfile_read(
|
||||
to_copy = IMFS_MEMFILE_BYTES_PER_BLOCK - start_offset;
|
||||
if ( to_copy > my_length )
|
||||
to_copy = my_length;
|
||||
block_ptr = IMFS_memfile_get_block_pointer( the_jnode, block, 0 );
|
||||
block_ptr = IMFS_memfile_get_block_pointer( &file->Memfile, block, 0 );
|
||||
if ( !block_ptr )
|
||||
return copied;
|
||||
memcpy( dest, &(*block_ptr)[ start_offset ], to_copy );
|
||||
@@ -536,7 +532,7 @@ MEMFILE_STATIC ssize_t IMFS_memfile_read(
|
||||
*/
|
||||
to_copy = IMFS_MEMFILE_BYTES_PER_BLOCK;
|
||||
while ( my_length >= IMFS_MEMFILE_BYTES_PER_BLOCK ) {
|
||||
block_ptr = IMFS_memfile_get_block_pointer( the_jnode, block, 0 );
|
||||
block_ptr = IMFS_memfile_get_block_pointer( &file->Memfile, block, 0 );
|
||||
if ( !block_ptr )
|
||||
return copied;
|
||||
memcpy( dest, &(*block_ptr)[ 0 ], to_copy );
|
||||
@@ -552,14 +548,14 @@ MEMFILE_STATIC ssize_t IMFS_memfile_read(
|
||||
IMFS_assert( my_length < IMFS_MEMFILE_BYTES_PER_BLOCK );
|
||||
|
||||
if ( my_length ) {
|
||||
block_ptr = IMFS_memfile_get_block_pointer( the_jnode, block, 0 );
|
||||
block_ptr = IMFS_memfile_get_block_pointer( &file->Memfile, block, 0 );
|
||||
if ( !block_ptr )
|
||||
return copied;
|
||||
memcpy( dest, &(*block_ptr)[ 0 ], my_length );
|
||||
copied += my_length;
|
||||
}
|
||||
|
||||
IMFS_update_atime( the_jnode );
|
||||
IMFS_update_atime( &file->Node );
|
||||
|
||||
return copied;
|
||||
}
|
||||
@@ -568,10 +564,10 @@ MEMFILE_STATIC ssize_t IMFS_memfile_read(
|
||||
* IMFS_memfile_write
|
||||
*
|
||||
* This routine writes the specified data buffer into the in memory
|
||||
* file pointed to by the_jnode. The file is extended as needed.
|
||||
* file pointed to by memfile. The file is extended as needed.
|
||||
*/
|
||||
MEMFILE_STATIC ssize_t IMFS_memfile_write(
|
||||
IMFS_jnode_t *the_jnode,
|
||||
IMFS_memfile_t *memfile,
|
||||
off_t start,
|
||||
const unsigned char *source,
|
||||
unsigned int length
|
||||
@@ -593,8 +589,7 @@ MEMFILE_STATIC ssize_t IMFS_memfile_write(
|
||||
* Perform internal consistency checks
|
||||
*/
|
||||
IMFS_assert( source );
|
||||
IMFS_assert( the_jnode );
|
||||
IMFS_assert( IMFS_type( the_jnode ) == IMFS_MEMORY_FILE );
|
||||
IMFS_assert( memfile );
|
||||
|
||||
my_length = length;
|
||||
/*
|
||||
@@ -603,10 +598,10 @@ MEMFILE_STATIC ssize_t IMFS_memfile_write(
|
||||
*/
|
||||
|
||||
last_byte = start + my_length;
|
||||
if ( last_byte > the_jnode->info.file.size ) {
|
||||
bool zero_fill = start > the_jnode->info.file.size;
|
||||
if ( last_byte > memfile->File.size ) {
|
||||
bool zero_fill = start > memfile->File.size;
|
||||
|
||||
status = IMFS_memfile_extend( the_jnode, zero_fill, last_byte );
|
||||
status = IMFS_memfile_extend( memfile, zero_fill, last_byte );
|
||||
if ( status )
|
||||
return status;
|
||||
}
|
||||
@@ -629,7 +624,7 @@ MEMFILE_STATIC ssize_t IMFS_memfile_write(
|
||||
to_copy = IMFS_MEMFILE_BYTES_PER_BLOCK - start_offset;
|
||||
if ( to_copy > my_length )
|
||||
to_copy = my_length;
|
||||
block_ptr = IMFS_memfile_get_block_pointer( the_jnode, block, 0 );
|
||||
block_ptr = IMFS_memfile_get_block_pointer( memfile, block, 0 );
|
||||
if ( !block_ptr )
|
||||
return copied;
|
||||
#if 0
|
||||
@@ -656,7 +651,7 @@ MEMFILE_STATIC ssize_t IMFS_memfile_write(
|
||||
|
||||
to_copy = IMFS_MEMFILE_BYTES_PER_BLOCK;
|
||||
while ( my_length >= IMFS_MEMFILE_BYTES_PER_BLOCK ) {
|
||||
block_ptr = IMFS_memfile_get_block_pointer( the_jnode, block, 0 );
|
||||
block_ptr = IMFS_memfile_get_block_pointer( memfile, block, 0 );
|
||||
if ( !block_ptr )
|
||||
return copied;
|
||||
#if 0
|
||||
@@ -676,7 +671,7 @@ MEMFILE_STATIC ssize_t IMFS_memfile_write(
|
||||
|
||||
to_copy = my_length;
|
||||
if ( my_length ) {
|
||||
block_ptr = IMFS_memfile_get_block_pointer( the_jnode, block, 0 );
|
||||
block_ptr = IMFS_memfile_get_block_pointer( memfile, block, 0 );
|
||||
if ( !block_ptr )
|
||||
return copied;
|
||||
#if 0
|
||||
@@ -687,7 +682,7 @@ MEMFILE_STATIC ssize_t IMFS_memfile_write(
|
||||
copied += to_copy;
|
||||
}
|
||||
|
||||
IMFS_mtime_ctime_update( the_jnode );
|
||||
IMFS_mtime_ctime_update( &memfile->File.Node );
|
||||
|
||||
return copied;
|
||||
}
|
||||
@@ -723,13 +718,12 @@ block_p *IMFS_memfile_get_block_pointer_DEBUG(
|
||||
#else
|
||||
block_p *IMFS_memfile_get_block_pointer(
|
||||
#endif
|
||||
IMFS_jnode_t *the_jnode,
|
||||
IMFS_memfile_t *memfile,
|
||||
unsigned int block,
|
||||
int malloc_it
|
||||
)
|
||||
{
|
||||
unsigned int my_block;
|
||||
IMFS_memfile_t *info;
|
||||
unsigned int singly;
|
||||
unsigned int doubly;
|
||||
unsigned int triply;
|
||||
@@ -740,17 +734,15 @@ block_p *IMFS_memfile_get_block_pointer(
|
||||
/*
|
||||
* Perform internal consistency checks
|
||||
*/
|
||||
IMFS_assert( the_jnode );
|
||||
IMFS_assert( IMFS_type( the_jnode ) == IMFS_MEMORY_FILE );
|
||||
IMFS_assert( memfile );
|
||||
|
||||
info = &the_jnode->info.file;
|
||||
my_block = block;
|
||||
|
||||
/*
|
||||
* Is the block number in the simple indirect portion?
|
||||
*/
|
||||
if ( my_block <= LAST_INDIRECT ) {
|
||||
p = info->indirect;
|
||||
p = memfile->indirect;
|
||||
|
||||
if ( malloc_it ) {
|
||||
|
||||
@@ -758,15 +750,15 @@ block_p *IMFS_memfile_get_block_pointer(
|
||||
p = memfile_alloc_block();
|
||||
if ( !p )
|
||||
return 0;
|
||||
info->indirect = p;
|
||||
memfile->indirect = p;
|
||||
}
|
||||
return &info->indirect[ my_block ];
|
||||
return &memfile->indirect[ my_block ];
|
||||
}
|
||||
|
||||
if ( !p )
|
||||
return 0;
|
||||
|
||||
return &info->indirect[ my_block ];
|
||||
return &memfile->indirect[ my_block ];
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -779,14 +771,14 @@ block_p *IMFS_memfile_get_block_pointer(
|
||||
singly = my_block % IMFS_MEMFILE_BLOCK_SLOTS;
|
||||
doubly = my_block / IMFS_MEMFILE_BLOCK_SLOTS;
|
||||
|
||||
p = info->doubly_indirect;
|
||||
p = memfile->doubly_indirect;
|
||||
if ( malloc_it ) {
|
||||
|
||||
if ( !p ) {
|
||||
p = memfile_alloc_block();
|
||||
if ( !p )
|
||||
return 0;
|
||||
info->doubly_indirect = p;
|
||||
memfile->doubly_indirect = p;
|
||||
}
|
||||
|
||||
p1 = (block_p *)p[ doubly ];
|
||||
@@ -821,14 +813,14 @@ block_p *IMFS_memfile_get_block_pointer(
|
||||
triply = doubly / IMFS_MEMFILE_BLOCK_SLOTS;
|
||||
doubly %= IMFS_MEMFILE_BLOCK_SLOTS;
|
||||
|
||||
p = info->triply_indirect;
|
||||
p = memfile->triply_indirect;
|
||||
|
||||
if ( malloc_it ) {
|
||||
if ( !p ) {
|
||||
p = memfile_alloc_block();
|
||||
if ( !p )
|
||||
return 0;
|
||||
info->triply_indirect = p;
|
||||
memfile->triply_indirect = p;
|
||||
}
|
||||
|
||||
p1 = (block_p *) p[ triply ];
|
||||
|
||||
@@ -262,12 +262,12 @@ static const rtems_filesystem_file_handlers_r node_handlers = {
|
||||
|
||||
static IMFS_jnode_t *node_initialize(
|
||||
IMFS_jnode_t *node,
|
||||
const IMFS_types_union *info
|
||||
void *arg
|
||||
)
|
||||
{
|
||||
test_state *state = NULL;
|
||||
|
||||
node = IMFS_node_initialize_generic(node, info);
|
||||
node = IMFS_node_initialize_generic(node, arg);
|
||||
state = IMFS_generic_get_context_by_node(node);
|
||||
|
||||
rtems_test_assert(*state == TEST_NEW);
|
||||
@@ -286,19 +286,19 @@ static IMFS_jnode_t *node_remove(IMFS_jnode_t *node)
|
||||
return node;
|
||||
}
|
||||
|
||||
static IMFS_jnode_t *node_destroy(IMFS_jnode_t *node)
|
||||
static void node_destroy(IMFS_jnode_t *node)
|
||||
{
|
||||
test_state *state = IMFS_generic_get_context_by_node(node);
|
||||
|
||||
rtems_test_assert(*state == TEST_REMOVED);
|
||||
*state = TEST_DESTROYED;
|
||||
|
||||
return node;
|
||||
IMFS_node_destroy_default(node);
|
||||
}
|
||||
|
||||
static const IMFS_node_control node_control = {
|
||||
.imfs_type = IMFS_GENERIC,
|
||||
.handlers = &node_handlers,
|
||||
.node_size = sizeof(IMFS_generic_t),
|
||||
.node_initialize = node_initialize,
|
||||
.node_remove = node_remove,
|
||||
.node_destroy = node_destroy
|
||||
@@ -370,7 +370,7 @@ static void test_imfs_make_generic_node(void)
|
||||
|
||||
static IMFS_jnode_t *node_initialize_error(
|
||||
IMFS_jnode_t *node,
|
||||
const IMFS_types_union *info
|
||||
void *arg
|
||||
)
|
||||
{
|
||||
errno = EIO;
|
||||
@@ -385,24 +385,14 @@ static IMFS_jnode_t *node_remove_inhibited(IMFS_jnode_t *node)
|
||||
return node;
|
||||
}
|
||||
|
||||
static IMFS_jnode_t *node_destroy_inhibited(IMFS_jnode_t *node)
|
||||
static void node_destroy_inhibited(IMFS_jnode_t *node)
|
||||
{
|
||||
rtems_test_assert(false);
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
static const IMFS_node_control node_invalid_control = {
|
||||
.imfs_type = IMFS_DIRECTORY,
|
||||
.handlers = &node_handlers,
|
||||
.node_initialize = node_initialize_error,
|
||||
.node_remove = node_remove_inhibited,
|
||||
.node_destroy = node_destroy_inhibited
|
||||
};
|
||||
|
||||
static const IMFS_node_control node_initialization_error_control = {
|
||||
.imfs_type = IMFS_GENERIC,
|
||||
.handlers = &node_handlers,
|
||||
.node_size = sizeof(IMFS_generic_t),
|
||||
.node_initialize = node_initialize_error,
|
||||
.node_remove = node_remove_inhibited,
|
||||
.node_destroy = node_destroy_inhibited
|
||||
@@ -421,17 +411,6 @@ static void test_imfs_make_generic_node_errors(void)
|
||||
|
||||
rtems_resource_snapshot_take(&before);
|
||||
|
||||
errno = 0;
|
||||
rv = IMFS_make_generic_node(
|
||||
path,
|
||||
S_IFCHR | S_IRWXU | S_IRWXG | S_IRWXO,
|
||||
&node_invalid_control,
|
||||
NULL
|
||||
);
|
||||
rtems_test_assert(rv == -1);
|
||||
rtems_test_assert(errno == EINVAL);
|
||||
rtems_test_assert(rtems_resource_snapshot_check(&before));
|
||||
|
||||
errno = 0;
|
||||
rv = IMFS_make_generic_node(
|
||||
path,
|
||||
|
||||
@@ -232,13 +232,11 @@ static const rtems_filesystem_file_handlers_r node_handlers = {
|
||||
.writev_h = handler_writev
|
||||
};
|
||||
|
||||
static const IMFS_node_control node_control = {
|
||||
.imfs_type = IMFS_GENERIC,
|
||||
.handlers = &node_handlers,
|
||||
.node_initialize = IMFS_node_initialize_default,
|
||||
.node_remove = IMFS_node_remove_default,
|
||||
.node_destroy = IMFS_node_destroy_default
|
||||
};
|
||||
static const IMFS_node_control node_control = IMFS_GENERIC_INITIALIZER(
|
||||
&node_handlers,
|
||||
IMFS_node_initialize_default,
|
||||
IMFS_node_destroy_default
|
||||
);
|
||||
|
||||
static void test(void)
|
||||
{
|
||||
|
||||
@@ -68,7 +68,6 @@ rtems_task Init(
|
||||
TEST_BEGIN();
|
||||
|
||||
test_tarfs_load();
|
||||
IMFS_dump();
|
||||
|
||||
TEST_END();
|
||||
exit( 0 );
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
*** TAR02 TEST ***
|
||||
*** BEGIN OF TEST TAR 2 ***
|
||||
Loading tarfs image ... successful
|
||||
========= /home/test_file =========
|
||||
(0)This is a test of loading an RTEMS filesystem from an
|
||||
@@ -8,14 +8,4 @@ initial tar image.
|
||||
(0)This is a test of loading an RTEMS filesystem from an
|
||||
initial tar image.
|
||||
|
||||
*************** Dump of Entire IMFS ***************
|
||||
/
|
||||
....dev/
|
||||
........ttyS0 (device 0, 0)
|
||||
........console (device 0, 0)
|
||||
........ttyS1 (device 0, 1)
|
||||
....home/
|
||||
........test_file (file 73 0x390f8)
|
||||
....symlink links not printed
|
||||
*************** End of Dump ***************
|
||||
*** END OF TAR02 TEST ***
|
||||
*** END OF TEST TAR 2 ***
|
||||
|
||||
@@ -1,11 +1,4 @@
|
||||
*** FILE TEST 1 ***
|
||||
*************** Dump of Entire IMFS ***************
|
||||
/
|
||||
....dev/
|
||||
........console_a (device 0, 0)
|
||||
........console (device 0, 0)
|
||||
........console_b (device 0, 1)
|
||||
*************** End of Dump ***************
|
||||
*** BEGIN OF TEST PSXFILE 1 ***
|
||||
stat of /dev/console
|
||||
....st_dev (0xfffe:0x0)
|
||||
....st_rdev (0x0:0x0)
|
||||
@@ -181,26 +174,6 @@ This is call 5 to fprintf
|
||||
....ctime = Sat Dec 31 09:00:00 1988
|
||||
....st_blksize 80
|
||||
....st_blocks 0
|
||||
*************** Dump of Entire IMFS ***************
|
||||
/
|
||||
....dev/
|
||||
........console_a (device 0, 0)
|
||||
........console (device 0, 0)
|
||||
........console_b (device 0, 1)
|
||||
........tty/
|
||||
............S3 (device 255, 128)
|
||||
........test_console (device 0, 0)
|
||||
....etc/
|
||||
........passwd (file 0)
|
||||
....tmp/
|
||||
........my_dir/
|
||||
........tom (file 0)
|
||||
........john (file 0)
|
||||
........joel (file 533)
|
||||
........j (file 130)
|
||||
....imfs/
|
||||
........hidden_on_mount/
|
||||
*************** End of Dump ***************
|
||||
truncate /tmp/j to length of 40
|
||||
....st_dev (0xfffe:0x0)
|
||||
....st_rdev (0x0:0x0)
|
||||
@@ -209,53 +182,15 @@ truncate /tmp/j to length of 40
|
||||
....nlink = 1
|
||||
....uid = 0
|
||||
....gid = 0
|
||||
....atime = Sat Dec 31 09:00:02 1988
|
||||
....mtime = Sat Dec 31 09:00:00 1988
|
||||
....ctime = Sat Dec 31 09:00:00 1988
|
||||
....atime = Sat Dec 31 09:00:01 1988
|
||||
....mtime = Sat Dec 31 09:00:02 1988
|
||||
....ctime = Sat Dec 31 09:00:02 1988
|
||||
....st_blksize 80
|
||||
....st_blocks 0
|
||||
*************** Dump of Entire IMFS ***************
|
||||
/
|
||||
....dev/
|
||||
........console_a (device 0, 0)
|
||||
........console (device 0, 0)
|
||||
........console_b (device 0, 1)
|
||||
........tty/
|
||||
............S3 (device 255, 128)
|
||||
........test_console (device 0, 0)
|
||||
....etc/
|
||||
........passwd (file 0)
|
||||
....tmp/
|
||||
........my_dir/
|
||||
........tom (file 0)
|
||||
........john (file 0)
|
||||
........j (file 40)
|
||||
....imfs/
|
||||
........hidden_on_mount/
|
||||
*************** End of Dump ***************
|
||||
truncate /tmp/j to length of 0
|
||||
truncate /tmp to length of 0 should fail with EISDIR
|
||||
|
||||
21: Is a directory
|
||||
*************** Dump of Entire IMFS ***************
|
||||
/
|
||||
....dev/
|
||||
........console_a (device 0, 0)
|
||||
........console (device 0, 0)
|
||||
........console_b (device 0, 1)
|
||||
........tty/
|
||||
............S3 (device 255, 128)
|
||||
........test_console (device 0, 0)
|
||||
....etc/
|
||||
........passwd (file 0)
|
||||
....tmp/
|
||||
........my_dir/
|
||||
........tom (file 0)
|
||||
........john (file 0)
|
||||
........j (file 0)
|
||||
....imfs/
|
||||
........hidden_on_mount/
|
||||
*************** End of Dump ***************
|
||||
Writing First File
|
||||
Writing Second File
|
||||
(0)this is a test line
|
||||
@@ -264,4 +199,4 @@ this is a test line
|
||||
(0)this is a test line
|
||||
this is a test line
|
||||
|
||||
*** END OF FILE TEST 1 ***
|
||||
*** END OF TEST PSXFILE 1 ***
|
||||
|
||||
@@ -166,18 +166,12 @@ int main(
|
||||
* Grab the maximum size of an in-memory file.
|
||||
*/
|
||||
|
||||
max_size = IMFS_memfile_maximum_size();
|
||||
max_size = IMFS_MEMFILE_MAXIMUM_SIZE;
|
||||
|
||||
build_time( &time, 12, 31, 1988, 9, 0, 0, 0 );
|
||||
rtems_status = rtems_clock_set( &time );
|
||||
directive_failed( rtems_status, "clock set" );
|
||||
|
||||
/*
|
||||
* Dump an empty file system
|
||||
*/
|
||||
|
||||
IMFS_dump();
|
||||
|
||||
/*
|
||||
* Simple stat() of /dev/console.
|
||||
*/
|
||||
@@ -605,8 +599,6 @@ since new path is not valid");
|
||||
rtems_test_assert( mtime1 == mtime2);
|
||||
rtems_test_assert( ctime1 == ctime2);
|
||||
|
||||
IMFS_dump();
|
||||
|
||||
unlink( "/tmp/joel" );
|
||||
|
||||
/*
|
||||
@@ -631,8 +623,6 @@ since new path is not valid");
|
||||
rtems_test_assert( mtime1 != mtime2);
|
||||
rtems_test_assert( ctime1 != ctime2);
|
||||
|
||||
IMFS_dump();
|
||||
|
||||
/* try to truncate the console and see what happens */
|
||||
status = truncate( "/dev/console", 40 );
|
||||
rtems_test_assert( status == 0 );
|
||||
@@ -647,8 +637,6 @@ since new path is not valid");
|
||||
printf( "%d: %s\n", errno, strerror( errno ) );
|
||||
rtems_test_assert( errno == EISDIR );
|
||||
|
||||
IMFS_dump();
|
||||
|
||||
status = truncate( "/tmp/fred", 10 );
|
||||
rtems_test_assert( status == -1);
|
||||
|
||||
|
||||
@@ -31,7 +31,6 @@ extern int seteuid(uid_t euid);
|
||||
|
||||
/* forward declarations to avoid warnings */
|
||||
rtems_task Init(rtems_task_argument argument);
|
||||
void IMFS_dump(void);
|
||||
|
||||
rtems_task Init(
|
||||
rtems_task_argument argument
|
||||
@@ -183,8 +182,6 @@ rtems_task Init(
|
||||
puts( "Creating a fifo -- OK" );
|
||||
status = mkfifo( "/fifo", S_IRWXU );
|
||||
rtems_test_assert( status == 0 );
|
||||
|
||||
IMFS_dump();
|
||||
|
||||
puts( "chown /fifo to 10 -- OK" );
|
||||
status = chown( "/fifo", 10, 10 );
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
*** TEST IMFS 02 ***
|
||||
*** BEGIN OF TEST PSXIMFS 2 ***
|
||||
Creating directory /dir00
|
||||
Creating directory /dir00/dir01
|
||||
Changing directory to /dir00
|
||||
@@ -24,42 +24,22 @@ Opening /node-link in WRONLY mode -- expect EACCES
|
||||
Creating a symlink /node-slink for /node
|
||||
Opening /node-slink in WRONLY mode -- expect EACCES
|
||||
Allocate most of heap
|
||||
Attempt to mount a fs at /dir01 -- expect ENOMEM
|
||||
Freeing allocated memory
|
||||
Allocate most of heap
|
||||
Attempt to mount a fs at dir01 -- expect ENOMEMFreeing allocated memory
|
||||
Changing directory to /
|
||||
Allocate most of heap
|
||||
Attempt to create /node-link-2 for /node -- expect ENOMEM
|
||||
Attempt to create /node-slink-2 for /node -- expect ENOMEM
|
||||
Freeing allocated memory
|
||||
Allocate most of heap
|
||||
Attempt to create /node-slink-2 for /node -- expect ENOMEM
|
||||
Freeing allocated memory
|
||||
Attempt to stat a hardlink -- expect ENOTSUP
|
||||
Attempt to create node-slink-2 for /node -- expect ENOMEMFreeing allocated memory
|
||||
Attempt to stat a hardlink
|
||||
Changing euid to 10
|
||||
Attempt chmod on /node -- expect EPERM
|
||||
Attempt chown on /node -- expect EPERM
|
||||
Changing euid back to 0 [root]
|
||||
Creating a fifo -- OK
|
||||
*************** Dump of Entire IMFS ***************
|
||||
/
|
||||
....dev/
|
||||
........console (device 0, 0)
|
||||
....dir00/
|
||||
........dir01/
|
||||
........dir01-link0 links not printed
|
||||
........dir01-link1 links not printed
|
||||
........dir01-link2 links not printed
|
||||
........dir01-link3 links not printed
|
||||
........dir01-link4 links not printed
|
||||
........dir01-link5 links not printed
|
||||
........dir01-link6 links not printed
|
||||
....node (file 0)
|
||||
....node-link links not printed
|
||||
....node-slink links not printed
|
||||
....fifo FIFO not printed
|
||||
*************** End of Dump ***************
|
||||
chown /fifo to 10 -- OK
|
||||
Changing euid to 10
|
||||
chmod /fifo -- OK
|
||||
chown /fifo to 0 -- OK
|
||||
*** END OF TEST IMFS 02 ***
|
||||
*** END OF TEST PSXIMFS 2 ***
|
||||
|
||||
Reference in New Issue
Block a user