forked from Imagelibrary/rtems
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:
@@ -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;
|
||||
|
||||
@@ -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 );
|
||||
}
|
||||
|
||||
@@ -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 );
|
||||
|
||||
Reference in New Issue
Block a user