diff options
author | Sebastian Huber <sebastian.huber@embedded-brains.de> | 2020-02-29 11:15:43 +0100 |
---|---|---|
committer | Sebastian Huber <sebastian.huber@embedded-brains.de> | 2020-03-04 09:30:02 +0100 |
commit | 0b0cd93a40c92018a959219e8a2c42eadeae7a79 (patch) | |
tree | c6e6cd5b25719cefc2556d705bbbab297157f3a7 /cpukit/libfs/src | |
parent | rtems: rtems_scheduler_get_processor_maximum() (diff) | |
download | rtems-0b0cd93a40c92018a959219e8a2c42eadeae7a79.tar.bz2 |
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.
Diffstat (limited to 'cpukit/libfs/src')
-rw-r--r-- | cpukit/libfs/src/imfs/imfs_node.c | 4 | ||||
-rw-r--r-- | cpukit/libfs/src/imfs/imfs_rename.c | 49 |
2 files changed, 39 insertions, 14 deletions
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 ); |