[rtems commit] IMFS: Implement variable length node names
Sebastian Huber
sebh at rtems.org
Sun Feb 15 10:27:10 UTC 2015
Module: rtems
Branch: master
Commit: a43a34666e2124c24e86794206aa78d2ad5e910d
Changeset: http://git.rtems.org/rtems/commit/?id=a43a34666e2124c24e86794206aa78d2ad5e910d
Author: Sebastian Huber <sebastian.huber at embedded-brains.de>
Date: Sun Feb 15 10:38:15 2015 +0100
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 2a1eddc..bcf13d8 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 9675ca3..2e24972 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 9e2d6f5..d9d7b92 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 5f0df25..2428563 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 46ef674..b8f64c4 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 826a394..e489180 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
More information about the vc
mailing list