summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cpukit/include/rtems/imfs.h3
-rw-r--r--cpukit/libfs/src/imfs/imfs_node.c4
-rw-r--r--cpukit/libfs/src/imfs/imfs_rename.c49
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 <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 );