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.
This commit is contained in:
Sebastian Huber
2020-02-29 11:15:43 +01:00
parent 8b73ee5023
commit 0b0cd93a40
3 changed files with 39 additions and 17 deletions

View File

@@ -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;

View File

@@ -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 );
}

View File

@@ -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 );