[PATCH 1/5] imfs: Remove IMFS_NODE_FLAG_NAME_ALLOCATED

Sebastian Huber sebastian.huber at embedded-brains.de
Tue Mar 3 10:50:12 UTC 2020


Remove IMFS_NODE_FLAG_NAME_ALLOCATED and instead replace the node
control in rename operations.  This avoids a special case in the general
node destruction which pulled in free().

Update #3894.
---
 cpukit/include/rtems/imfs.h         |  3 ---
 cpukit/libfs/src/imfs/imfs_node.c   |  4 ---
 cpukit/libfs/src/imfs/imfs_rename.c | 49 +++++++++++++++++++++++++++++--------
 3 files changed, 39 insertions(+), 17 deletions(-)

diff --git a/cpukit/include/rtems/imfs.h b/cpukit/include/rtems/imfs.h
index 5327d632f9..1490186287 100644
--- a/cpukit/include/rtems/imfs.h
+++ b/cpukit/include/rtems/imfs.h
@@ -244,7 +244,6 @@ struct IMFS_jnode_tt {
   IMFS_jnode_t       *Parent;                /* Parent node */
   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 */
@@ -258,8 +257,6 @@ 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_node.c b/cpukit/libfs/src/imfs/imfs_node.c
index 0c296de339..ae087bd58f 100644
--- a/cpukit/libfs/src/imfs/imfs_node.c
+++ b/cpukit/libfs/src/imfs/imfs_node.c
@@ -107,9 +107,5 @@ 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( RTEMS_DECONST( char *, node->name ) );
-  }
-
   free( node );
 }
diff --git a/cpukit/libfs/src/imfs/imfs_rename.c b/cpukit/libfs/src/imfs/imfs_rename.c
index 5bc0b3be25..bf86f320f6 100644
--- a/cpukit/libfs/src/imfs/imfs_rename.c
+++ b/cpukit/libfs/src/imfs/imfs_rename.c
@@ -23,6 +23,29 @@
 #include <string.h>
 #include <stdlib.h>
 
+typedef struct {
+  IMFS_node_control Base;
+  const IMFS_node_control *replaced;
+  char name[ RTEMS_ZERO_LENGTH_ARRAY ];
+} IMFS_renamed_control;
+
+static void IMFS_restore_replaced_control( IMFS_jnode_t *node )
+{
+  const IMFS_node_control *base;
+  IMFS_renamed_control    *control;
+
+  base = RTEMS_DECONST( IMFS_node_control *, node->control );
+  control = (IMFS_renamed_control *) base;
+  node->control = control->replaced;
+  free( control );
+}
+
+static void IMFS_renamed_destroy( IMFS_jnode_t *node )
+{
+  IMFS_restore_replaced_control( node );
+  ( *node->control->node_destroy )( node );
+}
+
 int IMFS_rename(
   const rtems_filesystem_location_info_t *oldparentloc,
   const rtems_filesystem_location_info_t *oldloc,
@@ -31,15 +54,18 @@ int IMFS_rename(
   size_t namelen
 )
 {
-  IMFS_jnode_t *node = oldloc->node_access;
-  IMFS_jnode_t *new_parent = newparentloc->node_access;
-  char *allocated_name;
+  IMFS_jnode_t         *node;
+  IMFS_jnode_t         *new_parent;
+  IMFS_renamed_control *control;
 
   /*
    * FIXME: Due to insufficient checks we can create inaccessible nodes with
    * this operation.
    */
 
+  node = oldloc->node_access;
+  new_parent = newparentloc->node_access;
+
   if ( node->Parent == NULL ) {
     rtems_set_errno_and_return_minus_one( EINVAL );
   }
@@ -48,20 +74,23 @@ int IMFS_rename(
     rtems_set_errno_and_return_minus_one( ENAMETOOLONG );
   }
 
-  allocated_name = malloc( namelen );
-  if ( allocated_name == NULL ) {
+  control = malloc( sizeof( *control ) + namelen );
+  if ( control == NULL ) {
     rtems_set_errno_and_return_minus_one( ENOMEM );
   }
 
-  memcpy( allocated_name, name, namelen );
+  memcpy( control->name, name, namelen );
 
-  if ( ( node->flags & IMFS_NODE_FLAG_NAME_ALLOCATED ) != 0 ) {
-    free( RTEMS_DECONST( char *, node->name ) );
+  if ( node->control->node_destroy == IMFS_renamed_destroy ) {
+    IMFS_restore_replaced_control( node );
   }
 
-  node->name = allocated_name;
+  control->Base = *node->control;
+  control->Base.node_destroy = IMFS_renamed_destroy;
+  control->replaced = node->control;
+  node->control = &control->Base;
+  node->name = control->name;
   node->namelen = namelen;
-  node->flags |= IMFS_NODE_FLAG_NAME_ALLOCATED;
 
   IMFS_remove_from_directory( node );
   IMFS_add_to_directory( new_parent, node );
-- 
2.16.4



More information about the devel mailing list