From a43a34666e2124c24e86794206aa78d2ad5e910d Mon Sep 17 00:00:00 2001 From: Sebastian Huber Date: Sun, 15 Feb 2015 10:38:15 +0100 Subject: IMFS: Implement variable length node names This reduces the average node size and adds more flexibility. --- cpukit/libfs/src/imfs/imfs.h | 9 +++++-- cpukit/libfs/src/imfs/imfs_creat.c | 6 +++-- cpukit/libfs/src/imfs/imfs_eval.c | 4 ++-- cpukit/libfs/src/imfs/imfs_initsupp.c | 8 +++++-- cpukit/libfs/src/imfs/imfs_rename.c | 44 +++++++++++++++++++++-------------- testsuites/psxtests/psxstat/test.c | 6 ++++- 6 files changed, 51 insertions(+), 26 deletions(-) diff --git a/cpukit/libfs/src/imfs/imfs.h b/cpukit/libfs/src/imfs/imfs.h index 2a1eddcfcc..bcf13d8072 100644 --- a/cpukit/libfs/src/imfs/imfs.h +++ b/cpukit/libfs/src/imfs/imfs.h @@ -230,16 +230,19 @@ typedef struct { * Maximum length of a "basename" of an IMFS file/node. */ -#define IMFS_NAME_MAX 32 +#define IMFS_NAME_MAX _POSIX_NAME_MAX /* + * The control structure for an IMFS jnode. */ struct IMFS_jnode_tt { rtems_chain_node Node; /* for chaining them together */ IMFS_jnode_t *Parent; /* Parent node */ - char name[IMFS_NAME_MAX+1]; /* "basename" */ + 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 */ @@ -253,6 +256,8 @@ 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_creat.c b/cpukit/libfs/src/imfs/imfs_creat.c index 9675ca35a3..2e24972a28 100644 --- a/cpukit/libfs/src/imfs/imfs_creat.c +++ b/cpukit/libfs/src/imfs/imfs_creat.c @@ -35,7 +35,7 @@ IMFS_jnode_t *IMFS_create_node( IMFS_jnode_t *allocated_node; IMFS_jnode_t *node; - allocated_node = calloc( 1, node_size ); + allocated_node = calloc( 1, node_size + namelen ); if ( allocated_node == NULL ) { errno = ENOMEM; @@ -45,7 +45,7 @@ IMFS_jnode_t *IMFS_create_node( node = IMFS_initialize_node( allocated_node, node_control, - name, + (char *) allocated_node + node_size, namelen, mode, arg @@ -53,6 +53,8 @@ IMFS_jnode_t *IMFS_create_node( if ( node != NULL ) { IMFS_jnode_t *parent = parentloc->node_access; + memcpy( node->name, name, namelen ); + /* * This node MUST have a parent, so put it in that directory list. */ diff --git a/cpukit/libfs/src/imfs/imfs_eval.c b/cpukit/libfs/src/imfs/imfs_eval.c index 9e2d6f5c1f..d9d7b9224b 100644 --- a/cpukit/libfs/src/imfs/imfs_eval.c +++ b/cpukit/libfs/src/imfs/imfs_eval.c @@ -55,8 +55,8 @@ static IMFS_jnode_t *IMFS_search_in_directory( while ( current != tail ) { IMFS_jnode_t *entry = (IMFS_jnode_t *) current; - bool match = strncmp( entry->name, token, tokenlen ) == 0 - && entry->name [tokenlen] == '\0'; + bool match = entry->namelen == tokenlen + && memcmp( entry->name, token, tokenlen ) == 0; if ( match ) { return entry; diff --git a/cpukit/libfs/src/imfs/imfs_initsupp.c b/cpukit/libfs/src/imfs/imfs_initsupp.c index 5f0df250e5..242856340e 100644 --- a/cpukit/libfs/src/imfs/imfs_initsupp.c +++ b/cpukit/libfs/src/imfs/imfs_initsupp.c @@ -78,10 +78,10 @@ IMFS_jnode_t *IMFS_initialize_node( /* * Fill in the basic information */ + node->name = name; + node->namelen = namelen; node->reference_count = 1; node->st_nlink = 1; - memcpy( node->name, name, namelen ); - node->name [namelen] = '\0'; node->control = node_control; /* @@ -192,6 +192,10 @@ 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( node->name ); + } + free( node ); } diff --git a/cpukit/libfs/src/imfs/imfs_rename.c b/cpukit/libfs/src/imfs/imfs_rename.c index 46ef674075..b8f64c4ac1 100644 --- a/cpukit/libfs/src/imfs/imfs_rename.c +++ b/cpukit/libfs/src/imfs/imfs_rename.c @@ -30,31 +30,41 @@ int IMFS_rename( size_t namelen ) { - int rv = 0; IMFS_jnode_t *node = oldloc->node_access; IMFS_jnode_t *new_parent = newparentloc->node_access; + char *allocated_name; /* * FIXME: Due to insufficient checks we can create inaccessible nodes with * this operation. */ - if ( node->Parent != NULL ) { - if ( namelen < IMFS_NAME_MAX ) { - memcpy( node->name, name, namelen ); - node->name [namelen] = '\0'; - - IMFS_remove_from_directory( node ); - IMFS_add_to_directory( new_parent, node ); - IMFS_update_ctime( node ); - } else { - errno = ENAMETOOLONG; - rv = -1; - } - } else { - errno = EINVAL; - rv = -1; + if ( node->Parent == NULL ) { + rtems_set_errno_and_return_minus_one( EINVAL ); } - return rv; + if ( namelen >= IMFS_NAME_MAX ) { + rtems_set_errno_and_return_minus_one( ENAMETOOLONG ); + } + + allocated_name = malloc( namelen ); + if ( allocated_name == NULL ) { + rtems_set_errno_and_return_minus_one( ENOMEM ); + } + + memcpy( allocated_name, name, namelen ); + + if ( ( node->flags & IMFS_NODE_FLAG_NAME_ALLOCATED ) != 0 ) { + free( node->name ); + } + + node->name = allocated_name; + node->namelen = namelen; + node->flags |= IMFS_NODE_FLAG_NAME_ALLOCATED; + + IMFS_remove_from_directory( node ); + IMFS_add_to_directory( new_parent, node ); + IMFS_update_ctime( node ); + + return 0; } diff --git a/testsuites/psxtests/psxstat/test.c b/testsuites/psxtests/psxstat/test.c index 826a3948b2..e489180122 100644 --- a/testsuites/psxtests/psxstat/test.c +++ b/testsuites/psxtests/psxstat/test.c @@ -171,7 +171,11 @@ char *Good_absolute_paths[] = { char *Bad_paths[] = { - "/my_mount_point/links/ENAMETOOLONG__________________________", + "/my_mount_point/links/ENAMETOOLONG________________________________________" + "__________________________________________________________________________" + "__________________________________________________________________________" + "__________________________________________________________________________" + "______________________________________", "/my_mount_point/dir1/file4/NOTADIR", "/my_mount_point/dir1/dir1/EACCES__", 0 -- cgit v1.2.3