[rtems commit] IMFS: Replace node union with individual struct

Sebastian Huber sebh at rtems.org
Tue Jan 27 07:31:23 UTC 2015


Module:    rtems
Branch:    master
Commit:    cf36b70e8dd8755e7dac6eb516169f586e78566d
Changeset: http://git.rtems.org/rtems/commit/?id=cf36b70e8dd8755e7dac6eb516169f586e78566d

Author:    Sebastian Huber <sebastian.huber at embedded-brains.de>
Date:      Wed Dec 31 10:56:05 2014 +0100

IMFS: Replace node union with individual struct

This reduces the average node size.

Add and use IMFS_GENERIC_INITIALIZER().

---

 cpukit/dev/i2c/i2c-bus.c                        |  16 +-
 cpukit/dev/i2c/i2c-dev.c                        |  16 +-
 cpukit/libblock/src/blkdev-imfs.c               |  21 +-
 cpukit/libfs/Makefile.am                        |   2 +-
 cpukit/libfs/src/imfs/deviceio.c                |  40 ++--
 cpukit/libfs/src/imfs/imfs.h                    | 291 ++++++++++++++----------
 cpukit/libfs/src/imfs/imfs_creat.c              |  10 +-
 cpukit/libfs/src/imfs/imfs_debug.c              | 138 -----------
 cpukit/libfs/src/imfs/imfs_directory.c          |  55 +++--
 cpukit/libfs/src/imfs/imfs_eval.c               |  43 ++--
 cpukit/libfs/src/imfs/imfs_fifo.c               |   4 +-
 cpukit/libfs/src/imfs/imfs_fsunmount.c          |   2 +-
 cpukit/libfs/src/imfs/imfs_handlers_device.c    |  15 +-
 cpukit/libfs/src/imfs/imfs_handlers_directory.c |  27 ++-
 cpukit/libfs/src/imfs/imfs_handlers_link.c      |  36 +--
 cpukit/libfs/src/imfs/imfs_handlers_memfile.c   |  30 ++-
 cpukit/libfs/src/imfs/imfs_initsupp.c           |  14 +-
 cpukit/libfs/src/imfs/imfs_link.c               |  10 +-
 cpukit/libfs/src/imfs/imfs_load_tar.c           |  25 +-
 cpukit/libfs/src/imfs/imfs_make_generic_node.c  |  63 +++--
 cpukit/libfs/src/imfs/imfs_mknod.c              |  25 +-
 cpukit/libfs/src/imfs/imfs_mount.c              |   6 +-
 cpukit/libfs/src/imfs/imfs_readlink.c           |  10 +-
 cpukit/libfs/src/imfs/imfs_symlink.c            |  12 +-
 cpukit/libfs/src/imfs/imfs_unmount.c            |   6 +-
 cpukit/libfs/src/imfs/memfile.c                 | 244 ++++++++++----------
 testsuites/fstests/fsimfsgeneric01/init.c       |  37 +--
 testsuites/libtests/newlib01/init.c             |  12 +-
 testsuites/libtests/tar02/init.c                |   1 -
 testsuites/libtests/tar02/tar02.scn             |  14 +-
 testsuites/psxtests/psxfile01/psxfile01.scn     |  75 +-----
 testsuites/psxtests/psxfile01/test.c            |  14 +-
 testsuites/psxtests/psximfs02/init.c            |   3 -
 testsuites/psxtests/psximfs02/psximfs02.scn     |  32 +--
 34 files changed, 563 insertions(+), 786 deletions(-)

diff --git a/cpukit/dev/i2c/i2c-bus.c b/cpukit/dev/i2c/i2c-bus.c
index dafd758..0f27d06 100644
--- a/cpukit/dev/i2c/i2c-bus.c
+++ b/cpukit/dev/i2c/i2c-bus.c
@@ -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,
diff --git a/cpukit/dev/i2c/i2c-dev.c b/cpukit/dev/i2c/i2c-dev.c
index 76ae757..6710632 100644
--- a/cpukit/dev/i2c/i2c-dev.c
+++ b/cpukit/dev/i2c/i2c-dev.c
@@ -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,
diff --git a/cpukit/libblock/src/blkdev-imfs.c b/cpukit/libblock/src/blkdev-imfs.c
index d6134f9..7a2d00b 100644
--- a/cpukit/libblock/src/blkdev-imfs.c
+++ b/cpukit/libblock/src/blkdev-imfs.c
@@ -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,
diff --git a/cpukit/libfs/Makefile.am b/cpukit/libfs/Makefile.am
index b255d1c..6427d69 100644
--- a/cpukit/libfs/Makefile.am
+++ b/cpukit/libfs/Makefile.am
@@ -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 \
diff --git a/cpukit/libfs/src/imfs/deviceio.c b/cpukit/libfs/src/imfs/deviceio.c
index cdb18ee..4819e80 100644
--- a/cpukit/libfs/src/imfs/deviceio.c
+++ b/cpukit/libfs/src/imfs/deviceio.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
   );
 }
 
diff --git a/cpukit/libfs/src/imfs/imfs.h b/cpukit/libfs/src/imfs/imfs.h
index c34f89f..fe99493 100644
--- a/cpukit/libfs/src/imfs/imfs.h
+++ b/cpukit/libfs/src/imfs/imfs.h
@@ -41,32 +41,6 @@ extern "C" {
 struct IMFS_jnode_tt;
 typedef struct IMFS_jnode_tt IMFS_jnode_t;
 
-typedef struct {
-  rtems_chain_control                    Entries;
-  rtems_filesystem_mount_table_entry_t  *mt_fs;
-}  IMFS_directory_t;
-
-typedef struct {
-  rtems_device_major_number  major;
-  rtems_device_minor_number  minor;
-}  IMFS_device_t;
-
-typedef struct {
-  IMFS_jnode_t  *link_node;
-} IMFS_link_t;
-
-typedef struct {
-  char *name;
-} IMFS_sym_link_t;
-
-typedef struct {
-  pipe_control_t  *pipe;
-} IMFS_fifo_t;
-
-typedef struct {
-  void *context;
-} IMFS_generic_t;
-
 /**
  *  IMFS "memfile" information
  *
@@ -100,18 +74,6 @@ typedef struct {
 typedef uint8_t *block_p;
 typedef block_p *block_ptr;
 
-typedef struct {
-  off_t         size;             /* size of file in bytes */
-  block_ptr     indirect;         /* array of 128 data blocks pointers */
-  block_ptr     doubly_indirect;  /* 128 indirect blocks */
-  block_ptr     triply_indirect;  /* 128 doubly indirect blocks */
-} IMFS_memfile_t;
-
-typedef struct {
-  off_t         size;             /* size of file in bytes */
-  block_p       direct;           /* pointer to file image */
-} IMFS_linearfile_t;
-
 /*
  *  Important block numbers for "memfiles"
  */
@@ -142,25 +104,11 @@ typedef enum {
   IMFS_SYM_LINK,
   IMFS_MEMORY_FILE,
   IMFS_LINEAR_FILE,
-  IMFS_FIFO,
-  IMFS_GENERIC,
-  IMFS_INVALID_NODE
+  IMFS_FIFO
 } IMFS_jnode_types_t;
 
-/* The IMFS_GENERIC does not count */
 #define IMFS_TYPE_COUNT (IMFS_FIFO + 1)
 
-typedef union {
-  IMFS_directory_t   directory;
-  IMFS_device_t      device;
-  IMFS_link_t        hard_link;
-  IMFS_sym_link_t    sym_link;
-  IMFS_memfile_t     file;
-  IMFS_linearfile_t  linearfile;
-  IMFS_fifo_t        fifo;
-  IMFS_generic_t     generic;
-} IMFS_types_union;
-
 /** @} */
 
 /**
@@ -171,8 +119,9 @@ typedef union {
 /**
  * @brief Initializes an IMFS node.
  *
- * @param[in,out] node The IMFS node.
- * @param[in] info The IMFS type information.
+ * @param[in] node The IMFS node.
+ * @param[in] arg The user provided argument pointer.  It may contain node
+ *   specific initialization information.
  *
  * @retval node Successful operation.
  * @retval NULL An error occurred.  The @c errno indicates the error.  This
@@ -183,14 +132,14 @@ typedef union {
  */
 typedef IMFS_jnode_t *(*IMFS_node_control_initialize)(
   IMFS_jnode_t *node,
-  const IMFS_types_union *info
+  void *arg
 );
 
 /**
  * @brief Returns the node and does nothing else.
  *
- * @param[in,out] node The IMFS node.
- * @param[in] info The IMFS type information.
+ * @param[in] node The IMFS node.
+ * @param[in] arg The user provided argument pointer.  It is not used.
  *
  * @retval node Returns always the node passed as parameter.
  *
@@ -198,14 +147,15 @@ typedef IMFS_jnode_t *(*IMFS_node_control_initialize)(
  */
 IMFS_jnode_t *IMFS_node_initialize_default(
   IMFS_jnode_t *node,
-  const IMFS_types_union *info
+  void *arg
 );
 
 /**
  * @brief Returns the node and sets the generic node context.
  *
- * @param[in,out] node The IMFS node.
- * @param[in] info The IMFS type information.
+ * @param[in] node The IMFS node.
+ * @param[in] arg The user provided argument pointer.  It must contain the
+ *   generic context.
  *
  * @retval node Returns always the node passed as parameter.
  *
@@ -213,13 +163,13 @@ IMFS_jnode_t *IMFS_node_initialize_default(
  */
 IMFS_jnode_t *IMFS_node_initialize_generic(
   IMFS_jnode_t *node,
-  const IMFS_types_union *info
+  void *arg
 );
 
 /**
  * @brief Prepares the removal of an IMFS node from its parent directory.
  *
- * @param[in,out] node The IMFS node.
+ * @param[in] node The IMFS node.
  *
  * @retval node Successful operation.
  * @retval NULL An error occurred.  The @c errno indicates the error.  This
@@ -234,7 +184,7 @@ typedef IMFS_jnode_t *(*IMFS_node_control_remove)(
 /**
  * @brief Returns the node and does nothing else.
  *
- * @param[in,out] node The IMFS node.
+ * @param[in] node The IMFS node.
  *
  * @retval node Returns always the node passed as parameter.
  *
@@ -247,31 +197,27 @@ IMFS_jnode_t *IMFS_node_remove_default(
 /**
  * @brief Destroys an IMFS node.
  *
- * @param[in,out] node The IMFS node.
- *
- * @retval node Returns always the node passed as parameter.
+ * @param[in] node The IMFS node.
  *
  * @see IMFS_node_control and IMFS_node_destroy_default().
  */
-typedef IMFS_jnode_t *(*IMFS_node_control_destroy)( IMFS_jnode_t *node );
+typedef void (*IMFS_node_control_destroy)( IMFS_jnode_t *node );
 
 /**
- * @brief Returns the node and does nothing else.
- *
- * @param[in,out] node The IMFS node.
+ * @brief Frees the node.
  *
- * @retval node Returns always the node passed as parameter.
+ * @param[in] node The IMFS node.
  *
  * @see IMFS_node_control.
  */
-IMFS_jnode_t *IMFS_node_destroy_default( IMFS_jnode_t *node );
+void IMFS_node_destroy_default( IMFS_jnode_t *node );
 
 /**
  * @brief IMFS node control.
  */
 typedef struct {
-  IMFS_jnode_types_t imfs_type;
   const rtems_filesystem_file_handlers_r *handlers;
+  size_t node_size;
   IMFS_node_control_initialize node_initialize;
   IMFS_node_control_remove node_remove;
   IMFS_node_control_destroy node_destroy;
@@ -323,9 +269,87 @@ struct IMFS_jnode_tt {
   time_t              stat_mtime;            /* Time of last modification */
   time_t              stat_ctime;            /* Time of last status change */
   const IMFS_node_control *control;
-  IMFS_types_union    info;
 };
 
+typedef struct {
+  IMFS_jnode_t                          Node;
+  rtems_chain_control                   Entries;
+  rtems_filesystem_mount_table_entry_t *mt_fs;
+} IMFS_directory_t;
+
+typedef struct {
+  IMFS_jnode_t              Node;
+  rtems_device_major_number major;
+  rtems_device_minor_number minor;
+} IMFS_device_t;
+
+typedef struct {
+  IMFS_jnode_t  Node;
+  IMFS_jnode_t *link_node;
+} IMFS_link_t;
+
+typedef struct {
+  IMFS_jnode_t  Node;
+  char         *name;
+} IMFS_sym_link_t;
+
+typedef struct {
+  IMFS_jnode_t Node;
+  size_t       size;             /* size of file in bytes */
+} IMFS_filebase_t;
+
+typedef struct {
+  IMFS_filebase_t File;
+  block_ptr       indirect;         /* array of 128 data blocks pointers */
+  block_ptr       doubly_indirect;  /* 128 indirect blocks */
+  block_ptr       triply_indirect;  /* 128 doubly indirect blocks */
+} IMFS_memfile_t;
+
+typedef struct {
+  IMFS_filebase_t File;
+  block_p         direct;           /* pointer to file image */
+} IMFS_linearfile_t;
+
+/* Support copy on write for linear files */
+typedef union {
+  IMFS_jnode_t      Node;
+  IMFS_filebase_t   File;
+  IMFS_memfile_t    Memfile;
+  IMFS_linearfile_t Linearfile;
+} IMFS_file_t;
+
+typedef struct {
+  IMFS_jnode_t    Node;
+  pipe_control_t *pipe;
+} IMFS_fifo_t;
+
+typedef struct {
+  IMFS_jnode_t  Node;
+  void         *context;
+} IMFS_generic_t;
+
+static inline IMFS_directory_t *IMFS_iop_to_directory(
+  const rtems_libio_t *iop
+)
+{
+  return (IMFS_directory_t *) iop->pathinfo.node_access;
+}
+
+static inline IMFS_device_t *IMFS_iop_to_device( const rtems_libio_t *iop )
+{
+  return (IMFS_device_t *) iop->pathinfo.node_access;
+}
+
+static inline IMFS_file_t *IMFS_iop_to_file( const rtems_libio_t *iop )
+{
+  return (IMFS_file_t *) iop->pathinfo.node_access;
+}
+
+static inline IMFS_memfile_t *IMFS_iop_to_memfile( const rtems_libio_t *iop )
+{
+  return (IMFS_memfile_t *) iop->pathinfo.node_access;
+}
+
 static inline void IMFS_update_atime( IMFS_jnode_t *jnode )
 {
   struct timeval now;
@@ -480,26 +504,6 @@ extern int rtems_tarfs_load(
 );
 
 /**
- * @brief Dump the entire IMFS.
- * 
- * This routine dumps the entire IMFS that is mounted at the root
- * directory.
- *
- * NOTE: Assuming the "/" directory is bad.
- *       Not checking that the starting directory is in an IMFS is bad.
- */
-extern void IMFS_dump( void );
-
-/**
- * @brief Get the size of the largest file which can be created
- * using the IMFS memory file type.
- * 
- * Return the size of the largest file which can be created
- * using the IMFS memory file type.
- */
-extern int IMFS_memfile_maximum_size( void );
-
-/**
  * @brief Destroy an IMFS node.
  */
 extern void IMFS_node_destroy( IMFS_jnode_t *node );
@@ -581,7 +585,7 @@ extern IMFS_jnode_t *IMFS_allocate_node(
   const char *name,
   size_t namelen,
   mode_t mode,
-  const IMFS_types_union *info
+  void *arg
 );
 
 /**
@@ -596,7 +600,7 @@ extern IMFS_jnode_t *IMFS_create_node_with_control(
   const char *name,
   size_t namelen,
   mode_t mode,
-  const IMFS_types_union *info
+  void *arg
 );
 
 extern bool IMFS_is_imfs_instance(
@@ -617,8 +621,25 @@ extern bool IMFS_is_imfs_instance(
  * more features like support for fsync() and fdatasync().  The generic nodes
  * use the reference counting of the IMFS.  This provides automatic node
  * destruction when the last reference vanishes.
+ *
+ * @{
  */
-/**@{*/
+
+/**
+ * @brief Initializer for a generic node control.
+ *
+ * @param[in] handlers The file system node handlers.
+ * @param[in] init The node initialization method.
+ * @param[in] destroy The node destruction method.
+ */
+#define IMFS_GENERIC_INITIALIZER( handlers, init, destroy ) \
+  { \
+    ( handlers ), \
+    sizeof( IMFS_generic_t ), \
+    ( init ), \
+    IMFS_node_remove_default, \
+    ( destroy ) \
+  }
 
 /**
  * @brief Makes a generic IMFS node.
@@ -638,14 +659,33 @@ extern bool IMFS_is_imfs_instance(
  *
  * #include <rtems/imfs.h>
  *
- * static const IMFS_node_control some_node_control = {
- *   .imfs_type = IMFS_GENERIC,
- *   .handlers = &some_node_handlers,
- *   .node_initialize = IMFS_node_initialize_generic,
- *   .node_remove = IMFS_node_remove_default,
- *   .node_destroy = some_node_destroy
+ * static const rtems_filesystem_file_handlers_r some_node_handlers = {
+ *   ...
  * };
  *
+ * static IMFS_jnode_t *some_node_init(IMFS_jnode_t *node, void *arg)
+ * {
+ *   void *context;
+ *
+ *   node = IMFS_node_initialize_generic(node, arg);
+ *   context = IMFS_generic_get_context_by_node(node);
+ *
+ *   return node;
+ * }
+ *
+ * static void some_node_destroy(IMFS_jnode_t *node)
+ * {
+ *   void *context = IMFS_generic_get_context_by_node(node);
+ *
+ *   IMFS_node_destroy_default(node);
+ * }
+ *
+ * static const IMFS_node_control some_node_control = IMFS_GENERIC_INITIALIZER(
+ *   &some_node_handlers,
+ *   some_node_init,
+ *   some_node_destroy
+ * );
+ *
  * void example(void *some_node_context)
  * {
  *   int rv;
@@ -688,7 +728,7 @@ extern int IMFS_unmount(
   rtems_filesystem_mount_table_entry_t *mt_entry  /* IN */
 );
 
-extern IMFS_jnode_t *IMFS_memfile_remove(
+extern void IMFS_memfile_remove(
  IMFS_jnode_t  *the_jnode         /* IN/OUT */
 );
 
@@ -734,18 +774,23 @@ extern ssize_t imfs_dir_read(
 /**@{*/
 
 /**
- * @brief Open a memory file.
+ * @brief Open a linear file.
  *
- * This routine processes the open() system call.  Note that there is
- * nothing special to be done at open() time.
+ * Transforms the file into a memfile if opened for writing.
  */
-extern int memfile_open(
+extern int IMFS_linfile_open(
   rtems_libio_t *iop,             /* IN  */
   const char    *pathname,        /* IN  */
   int            oflag,           /* IN  */
   mode_t         mode             /* IN  */
 );
 
+extern ssize_t IMFS_linfile_read(
+  rtems_libio_t *iop,
+  void          *buffer,
+  size_t         count
+);
+
 /**
  * @brief Read a memory file.
  *
@@ -905,12 +950,14 @@ static inline void IMFS_Set_handlers( rtems_filesystem_location_info_t *loc )
 }
 
 static inline void IMFS_add_to_directory(
-  IMFS_jnode_t *dir,
-  IMFS_jnode_t *node
+  IMFS_jnode_t *dir_node,
+  IMFS_jnode_t *entry_node
 )
 {
-  node->Parent = dir;
-  rtems_chain_append_unprotected( &dir->info.directory.Entries, &node->Node );
+  IMFS_directory_t *dir = (IMFS_directory_t *) dir_node;
+
+  entry_node->Parent = dir_node;
+  rtems_chain_append_unprotected( &dir->Entries, &entry_node->Node );
 }
 
 static inline void IMFS_remove_from_directory( IMFS_jnode_t *node )
@@ -920,14 +967,16 @@ static inline void IMFS_remove_from_directory( IMFS_jnode_t *node )
   rtems_chain_extract_unprotected( &node->Node );
 }
 
-static inline IMFS_jnode_types_t IMFS_type( const IMFS_jnode_t *node )
+static inline bool IMFS_is_directory( const IMFS_jnode_t *node )
 {
-  return node->control->imfs_type;
+  return S_ISDIR( node->st_mode );
 }
 
-static inline bool IMFS_is_directory( const IMFS_jnode_t *node )
+#define IMFS_STAT_FMT_HARD_LINK 0
+
+static inline bool IMFS_is_hard_link( mode_t mode )
 {
-  return node->control->imfs_type == IMFS_DIRECTORY;
+  return ( mode & S_IFMT ) == IMFS_STAT_FMT_HARD_LINK;
 }
 
 static inline IMFS_jnode_t *IMFS_create_node(
@@ -936,7 +985,7 @@ static inline IMFS_jnode_t *IMFS_create_node(
   const char *name,
   size_t namelen,
   mode_t mode,
-  const IMFS_types_union *info
+  void *arg
 )
 {
   const IMFS_fs_info_t *fs_info =
@@ -948,7 +997,7 @@ static inline IMFS_jnode_t *IMFS_create_node(
     name,
     namelen,
     mode,
-    info
+    arg
   );
 }
 
@@ -963,7 +1012,9 @@ static inline void *IMFS_generic_get_context_by_node(
   const IMFS_jnode_t *node
 )
 {
-  return node->info.generic.context;
+  const IMFS_generic_t *generic = (const IMFS_generic_t *) node;
+
+  return generic->context;
 }
 
 static inline void *IMFS_generic_get_context_by_location(
diff --git a/cpukit/libfs/src/imfs/imfs_creat.c b/cpukit/libfs/src/imfs/imfs_creat.c
index 4cea0c2..effb84b 100644
--- a/cpukit/libfs/src/imfs/imfs_creat.c
+++ b/cpukit/libfs/src/imfs/imfs_creat.c
@@ -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 ) {
diff --git a/cpukit/libfs/src/imfs/imfs_debug.c b/cpukit/libfs/src/imfs/imfs_debug.c
deleted file mode 100644
index 9f56466..0000000
--- a/cpukit/libfs/src/imfs/imfs_debug.c
+++ /dev/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;
-}
diff --git a/cpukit/libfs/src/imfs/imfs_directory.c b/cpukit/libfs/src/imfs/imfs_directory.c
index 8325a14..fc35b01 100644
--- a/cpukit/libfs/src/imfs/imfs_directory.c
+++ b/cpukit/libfs/src/imfs/imfs_directory.c
@@ -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 );
       }
    }
 
diff --git a/cpukit/libfs/src/imfs/imfs_eval.c b/cpukit/libfs/src/imfs/imfs_eval.c
index 9bbfc83..9e2d6f5 100644
--- a/cpukit/libfs/src/imfs/imfs_eval.c
+++ b/cpukit/libfs/src/imfs/imfs_eval.c
@@ -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 =
diff --git a/cpukit/libfs/src/imfs/imfs_fifo.c b/cpukit/libfs/src/imfs/imfs_fifo.c
index 72aa29f..36eab85 100644
--- a/cpukit/libfs/src/imfs/imfs_fifo.c
+++ b/cpukit/libfs/src/imfs/imfs_fifo.c
@@ -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
diff --git a/cpukit/libfs/src/imfs/imfs_fsunmount.c b/cpukit/libfs/src/imfs/imfs_fsunmount.c
index a2e676f..629818f 100644
--- a/cpukit/libfs/src/imfs/imfs_fsunmount.c
+++ b/cpukit/libfs/src/imfs/imfs_fsunmount.c
@@ -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 ) )
diff --git a/cpukit/libfs/src/imfs/imfs_handlers_device.c b/cpukit/libfs/src/imfs/imfs_handlers_device.c
index 95e8dea..f27511e 100644
--- a/cpukit/libfs/src/imfs/imfs_handlers_device.c
+++ b/cpukit/libfs/src/imfs/imfs_handlers_device.c
@@ -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
diff --git a/cpukit/libfs/src/imfs/imfs_handlers_directory.c b/cpukit/libfs/src/imfs/imfs_handlers_directory.c
index 4b5f133..1be399b 100644
--- a/cpukit/libfs/src/imfs/imfs_handlers_directory.c
+++ b/cpukit/libfs/src/imfs/imfs_handlers_directory.c
@@ -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
diff --git a/cpukit/libfs/src/imfs/imfs_handlers_link.c b/cpukit/libfs/src/imfs/imfs_handlers_link.c
index cd71f95..25848be 100644
--- a/cpukit/libfs/src/imfs/imfs_handlers_link.c
+++ b/cpukit/libfs/src/imfs/imfs_handlers_link.c
@@ -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
diff --git a/cpukit/libfs/src/imfs/imfs_handlers_memfile.c b/cpukit/libfs/src/imfs/imfs_handlers_memfile.c
index fbc3054..db682bb 100644
--- a/cpukit/libfs/src/imfs/imfs_handlers_memfile.c
+++ b/cpukit/libfs/src/imfs/imfs_handlers_memfile.c
@@ -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
diff --git a/cpukit/libfs/src/imfs/imfs_initsupp.c b/cpukit/libfs/src/imfs/imfs_initsupp.c
index 3c103ab..5f857d1 100644
--- a/cpukit/libfs/src/imfs/imfs_initsupp.c
+++ b/cpukit/libfs/src/imfs/imfs_initsupp.c
@@ -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
diff --git a/cpukit/libfs/src/imfs/imfs_link.c b/cpukit/libfs/src/imfs/imfs_link.c
index cb9246a..61b9f43 100644
--- a/cpukit/libfs/src/imfs/imfs_link.c
+++ b/cpukit/libfs/src/imfs/imfs_link.c
@@ -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 )
diff --git a/cpukit/libfs/src/imfs/imfs_load_tar.c b/cpukit/libfs/src/imfs/imfs_load_tar.c
index 1ef0e0b..c775a10 100644
--- a/cpukit/libfs/src/imfs/imfs_load_tar.c
+++ b/cpukit/libfs/src/imfs/imfs_load_tar.c
@@ -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;
diff --git a/cpukit/libfs/src/imfs/imfs_make_generic_node.c b/cpukit/libfs/src/imfs/imfs_make_generic_node.c
index c054a48..1daef3e 100644
--- a/cpukit/libfs/src/imfs/imfs_make_generic_node.c
+++ b/cpukit/libfs/src/imfs/imfs_make_generic_node.c
@@ -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 );
-
-      if ( IMFS_is_imfs_instance( currentloc ) ) {
-        IMFS_types_union info;
-        IMFS_jnode_t *new_node;
-
-        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;
-
-          IMFS_mtime_ctime_update( parent );
-        } else {
-          rv = -1;
-        }
+    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_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
+      );
+
+      if ( new_node != NULL ) {
+        IMFS_jnode_t *parent = currentloc->node_access;
+
+        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;
diff --git a/cpukit/libfs/src/imfs/imfs_mknod.c b/cpukit/libfs/src/imfs/imfs_mknod.c
index 5bb8c2d..9800642 100644
--- a/cpukit/libfs/src/imfs/imfs_mknod.c
+++ b/cpukit/libfs/src/imfs/imfs_mknod.c
@@ -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;
 
diff --git a/cpukit/libfs/src/imfs/imfs_mount.c b/cpukit/libfs/src/imfs/imfs_mount.c
index 06227f6..56a3621 100644
--- a/cpukit/libfs/src/imfs/imfs_mount.c
+++ b/cpukit/libfs/src/imfs/imfs_mount.c
@@ -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;
diff --git a/cpukit/libfs/src/imfs/imfs_readlink.c b/cpukit/libfs/src/imfs/imfs_readlink.c
index 45ca4a1..2c26954 100644
--- a/cpukit/libfs/src/imfs/imfs_readlink.c
+++ b/cpukit/libfs/src/imfs/imfs_readlink.c
@@ -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;
 }
diff --git a/cpukit/libfs/src/imfs/imfs_symlink.c b/cpukit/libfs/src/imfs/imfs_symlink.c
index 003b379..963cefc 100644
--- a/cpukit/libfs/src/imfs/imfs_symlink.c
+++ b/cpukit/libfs/src/imfs/imfs_symlink.c
@@ -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);
   }
 
diff --git a/cpukit/libfs/src/imfs/imfs_unmount.c b/cpukit/libfs/src/imfs/imfs_unmount.c
index 62fc4b4..13a3a14 100644
--- a/cpukit/libfs/src/imfs/imfs_unmount.c
+++ b/cpukit/libfs/src/imfs/imfs_unmount.c
@@ -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;
diff --git a/cpukit/libfs/src/imfs/memfile.c b/cpukit/libfs/src/imfs/memfile.c
index 1fdb741..563001a 100644
--- a/cpukit/libfs/src/imfs/memfile.c
+++ b/cpukit/libfs/src/imfs/memfile.c
@@ -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 memfile_read(
+ssize_t IMFS_linfile_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 );
+  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;
+}
 
-  the_jnode = iop->pathinfo.node_access;
+ssize_t memfile_read(
+  rtems_libio_t *iop,
+  void          *buffer,
+  size_t         count
+)
+{
+  IMFS_file_t *file = IMFS_iop_to_file( iop );
+  ssize_t      status;
 
-  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 ];
diff --git a/testsuites/fstests/fsimfsgeneric01/init.c b/testsuites/fstests/fsimfsgeneric01/init.c
index 03e4c19..671ad14 100644
--- a/testsuites/fstests/fsimfsgeneric01/init.c
+++ b/testsuites/fstests/fsimfsgeneric01/init.c
@@ -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
@@ -424,17 +414,6 @@ static void test_imfs_make_generic_node_errors(void)
   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,
     S_IFDIR | S_IRWXU | S_IRWXG | S_IRWXO,
     &node_control,
     NULL
diff --git a/testsuites/libtests/newlib01/init.c b/testsuites/libtests/newlib01/init.c
index 0361607..f9d3936 100644
--- a/testsuites/libtests/newlib01/init.c
+++ b/testsuites/libtests/newlib01/init.c
@@ -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)
 {
diff --git a/testsuites/libtests/tar02/init.c b/testsuites/libtests/tar02/init.c
index ebf87f8..8d790f6 100644
--- a/testsuites/libtests/tar02/init.c
+++ b/testsuites/libtests/tar02/init.c
@@ -68,7 +68,6 @@ rtems_task Init(
   TEST_BEGIN();
 
   test_tarfs_load();
-  IMFS_dump();
 
   TEST_END();
   exit( 0 );
diff --git a/testsuites/libtests/tar02/tar02.scn b/testsuites/libtests/tar02/tar02.scn
index f4ba9ce..e7a9165 100644
--- a/testsuites/libtests/tar02/tar02.scn
+++ b/testsuites/libtests/tar02/tar02.scn
@@ -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 ***
diff --git a/testsuites/psxtests/psxfile01/psxfile01.scn b/testsuites/psxtests/psxfile01/psxfile01.scn
index 5cdd609..605fef1 100644
--- a/testsuites/psxtests/psxfile01/psxfile01.scn
+++ b/testsuites/psxtests/psxfile01/psxfile01.scn
@@ -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 ***
diff --git a/testsuites/psxtests/psxfile01/test.c b/testsuites/psxtests/psxfile01/test.c
index 94f80c8..abc9295 100644
--- a/testsuites/psxtests/psxfile01/test.c
+++ b/testsuites/psxtests/psxfile01/test.c
@@ -166,19 +166,13 @@ 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);
 
diff --git a/testsuites/psxtests/psximfs02/init.c b/testsuites/psxtests/psximfs02/init.c
index 9d45b75..c7e2d3c 100644
--- a/testsuites/psxtests/psximfs02/init.c
+++ b/testsuites/psxtests/psximfs02/init.c
@@ -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 );
diff --git a/testsuites/psxtests/psximfs02/psximfs02.scn b/testsuites/psxtests/psximfs02/psximfs02.scn
index f86e975..930a0fa 100644
--- a/testsuites/psxtests/psximfs02/psximfs02.scn
+++ b/testsuites/psxtests/psximfs02/psximfs02.scn
@@ -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 ***



More information about the vc mailing list