summaryrefslogtreecommitdiffstats
path: root/cpukit/libfs/src/imfs
diff options
context:
space:
mode:
authorSebastian Huber <sebastian.huber@embedded-brains.de>2015-02-15 10:38:15 +0100
committerSebastian Huber <sebastian.huber@embedded-brains.de>2015-02-15 11:26:39 +0100
commita43a34666e2124c24e86794206aa78d2ad5e910d (patch)
tree9cee489e9763ab32904bad5eef921c3411d7ca3f /cpukit/libfs/src/imfs
parentIMFS: Add CONFIGURE_IMFS_DISABLE_READDIR (diff)
downloadrtems-a43a34666e2124c24e86794206aa78d2ad5e910d.tar.bz2
IMFS: Implement variable length node names
This reduces the average node size and adds more flexibility.
Diffstat (limited to 'cpukit/libfs/src/imfs')
-rw-r--r--cpukit/libfs/src/imfs/imfs.h9
-rw-r--r--cpukit/libfs/src/imfs/imfs_creat.c6
-rw-r--r--cpukit/libfs/src/imfs/imfs_eval.c4
-rw-r--r--cpukit/libfs/src/imfs/imfs_initsupp.c8
-rw-r--r--cpukit/libfs/src/imfs/imfs_rename.c44
5 files changed, 46 insertions, 25 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;
}