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/libfs/src/imfs/imfs_node.c | 4 --- cpukit/libfs/src/imfs/imfs_rename.c | 49 +++++++++++++++++++++++++++++-------- 2 files changed, 39 insertions(+), 14 deletions(-) (limited to 'cpukit/libfs/src') 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