From 0b0cd93a40c92018a959219e8a2c42eadeae7a79 Mon Sep 17 00:00:00 2001 From: Sebastian Huber Date: Sat, 29 Feb 2020 11:15:43 +0100 Subject: imfs: Remove IMFS_NODE_FLAG_NAME_ALLOCATED 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 #include +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 ); -- cgit v1.2.3