[rtems commit] IMFS: Implement variable length node names

Sebastian Huber sebh at rtems.org
Sun Feb 15 10:27:10 UTC 2015


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

Author:    Sebastian Huber <sebastian.huber at embedded-brains.de>
Date:      Sun Feb 15 10:38:15 2015 +0100

IMFS: Implement variable length node names

This reduces the average node size and adds more flexibility.

---

 cpukit/libfs/src/imfs/imfs.h          |  9 +++++--
 cpukit/libfs/src/imfs/imfs_creat.c    |  6 +++--
 cpukit/libfs/src/imfs/imfs_eval.c     |  4 ++--
 cpukit/libfs/src/imfs/imfs_initsupp.c |  8 +++++--
 cpukit/libfs/src/imfs/imfs_rename.c   | 44 +++++++++++++++++++++--------------
 testsuites/psxtests/psxstat/test.c    |  6 ++++-
 6 files changed, 51 insertions(+), 26 deletions(-)

diff --git a/cpukit/libfs/src/imfs/imfs.h b/cpukit/libfs/src/imfs/imfs.h
index 2a1eddc..bcf13d8 100644
--- a/cpukit/libfs/src/imfs/imfs.h
+++ b/cpukit/libfs/src/imfs/imfs.h
@@ -230,16 +230,19 @@ typedef struct {
  *  Maximum length of a "basename" of an IMFS file/node.
  */
 
-#define IMFS_NAME_MAX  32
+#define IMFS_NAME_MAX _POSIX_NAME_MAX
 
 /*
+
  *  The control structure for an IMFS jnode.
  */
 
 struct IMFS_jnode_tt {
   rtems_chain_node    Node;                  /* for chaining them together */
   IMFS_jnode_t       *Parent;                /* Parent node */
-  char                name[IMFS_NAME_MAX+1]; /* "basename" */
+  const char         *name;                  /* "basename" (not \0 terminated) */
+  uint16_t            namelen;               /* Length of "basename" */
+  uint16_t            flags;                 /* Node flags */
   mode_t              st_mode;               /* File mode */
   unsigned short      reference_count;
   nlink_t             st_nlink;              /* Link count */
@@ -253,6 +256,8 @@ struct IMFS_jnode_tt {
   const IMFS_node_control *control;
 };
 
+#define IMFS_NODE_FLAG_NAME_ALLOCATED 0x1
+
 typedef struct {
   IMFS_jnode_t                          Node;
   rtems_chain_control                   Entries;
diff --git a/cpukit/libfs/src/imfs/imfs_creat.c b/cpukit/libfs/src/imfs/imfs_creat.c
index 9675ca3..2e24972 100644
--- a/cpukit/libfs/src/imfs/imfs_creat.c
+++ b/cpukit/libfs/src/imfs/imfs_creat.c
@@ -35,7 +35,7 @@ IMFS_jnode_t *IMFS_create_node(
   IMFS_jnode_t *allocated_node;
   IMFS_jnode_t *node;
 
-  allocated_node = calloc( 1, node_size );
+  allocated_node = calloc( 1, node_size + namelen );
   if ( allocated_node == NULL ) {
     errno = ENOMEM;
 
@@ -45,7 +45,7 @@ IMFS_jnode_t *IMFS_create_node(
   node = IMFS_initialize_node(
     allocated_node,
     node_control,
-    name,
+    (char *) allocated_node + node_size,
     namelen,
     mode,
     arg
@@ -53,6 +53,8 @@ IMFS_jnode_t *IMFS_create_node(
   if ( node != NULL ) {
     IMFS_jnode_t *parent = parentloc->node_access;
 
+    memcpy( node->name, name, namelen );
+
     /*
      *  This node MUST have a parent, so put it in that directory list.
      */
diff --git a/cpukit/libfs/src/imfs/imfs_eval.c b/cpukit/libfs/src/imfs/imfs_eval.c
index 9e2d6f5..d9d7b92 100644
--- a/cpukit/libfs/src/imfs/imfs_eval.c
+++ b/cpukit/libfs/src/imfs/imfs_eval.c
@@ -55,8 +55,8 @@ static IMFS_jnode_t *IMFS_search_in_directory(
 
       while ( current != tail ) {
         IMFS_jnode_t *entry = (IMFS_jnode_t *) current;
-        bool match = strncmp( entry->name, token, tokenlen ) == 0
-          && entry->name [tokenlen] == '\0';
+        bool match = entry->namelen == tokenlen
+          && memcmp( entry->name, token, tokenlen ) == 0;
 
         if ( match ) {
           return entry;
diff --git a/cpukit/libfs/src/imfs/imfs_initsupp.c b/cpukit/libfs/src/imfs/imfs_initsupp.c
index 5f0df25..2428563 100644
--- a/cpukit/libfs/src/imfs/imfs_initsupp.c
+++ b/cpukit/libfs/src/imfs/imfs_initsupp.c
@@ -78,10 +78,10 @@ IMFS_jnode_t *IMFS_initialize_node(
   /*
    *  Fill in the basic information
    */
+  node->name = name;
+  node->namelen = namelen;
   node->reference_count = 1;
   node->st_nlink = 1;
-  memcpy( node->name, name, namelen );
-  node->name [namelen] = '\0';
   node->control = node_control;
 
   /*
@@ -192,6 +192,10 @@ IMFS_jnode_t *IMFS_node_remove_default(
 
 void IMFS_node_destroy_default( IMFS_jnode_t *node )
 {
+  if ( ( node->flags & IMFS_NODE_FLAG_NAME_ALLOCATED ) != 0 ) {
+    free( node->name );
+  }
+
   free( node );
 }
 
diff --git a/cpukit/libfs/src/imfs/imfs_rename.c b/cpukit/libfs/src/imfs/imfs_rename.c
index 46ef674..b8f64c4 100644
--- a/cpukit/libfs/src/imfs/imfs_rename.c
+++ b/cpukit/libfs/src/imfs/imfs_rename.c
@@ -30,31 +30,41 @@ int IMFS_rename(
   size_t namelen
 )
 {
-  int rv = 0;
   IMFS_jnode_t *node = oldloc->node_access;
   IMFS_jnode_t *new_parent = newparentloc->node_access;
+  char *allocated_name;
 
   /*
    * FIXME: Due to insufficient checks we can create inaccessible nodes with
    * this operation.
    */
 
-  if ( node->Parent != NULL ) {
-    if ( namelen < IMFS_NAME_MAX ) {
-      memcpy( node->name, name, namelen );
-      node->name [namelen] = '\0';
-
-      IMFS_remove_from_directory( node );
-      IMFS_add_to_directory( new_parent, node );
-      IMFS_update_ctime( node );
-    } else {
-      errno = ENAMETOOLONG;
-      rv = -1;
-    }
-  } else {
-    errno = EINVAL;
-    rv = -1;
+  if ( node->Parent == NULL ) {
+    rtems_set_errno_and_return_minus_one( EINVAL );
   }
 
-  return rv;
+  if ( namelen >= IMFS_NAME_MAX ) {
+    rtems_set_errno_and_return_minus_one( ENAMETOOLONG );
+  }
+
+  allocated_name = malloc( namelen );
+  if ( allocated_name == NULL ) {
+    rtems_set_errno_and_return_minus_one( ENOMEM );
+  }
+
+  memcpy( allocated_name, name, namelen );
+
+  if ( ( node->flags & IMFS_NODE_FLAG_NAME_ALLOCATED ) != 0 ) {
+    free( node->name );
+  }
+
+  node->name = allocated_name;
+  node->namelen = namelen;
+  node->flags |= IMFS_NODE_FLAG_NAME_ALLOCATED;
+
+  IMFS_remove_from_directory( node );
+  IMFS_add_to_directory( new_parent, node );
+  IMFS_update_ctime( node );
+
+  return 0;
 }
diff --git a/testsuites/psxtests/psxstat/test.c b/testsuites/psxtests/psxstat/test.c
index 826a394..e489180 100644
--- a/testsuites/psxtests/psxstat/test.c
+++ b/testsuites/psxtests/psxstat/test.c
@@ -171,7 +171,11 @@ char *Good_absolute_paths[] = {
 
 
 char *Bad_paths[] = {
-  "/my_mount_point/links/ENAMETOOLONG__________________________",
+  "/my_mount_point/links/ENAMETOOLONG________________________________________"
+  "__________________________________________________________________________"
+  "__________________________________________________________________________"
+  "__________________________________________________________________________"
+  "______________________________________",
   "/my_mount_point/dir1/file4/NOTADIR",
   "/my_mount_point/dir1/dir1/EACCES__",
   0



More information about the vc mailing list