IMFS: Implement variable length node names

This reduces the average node size and adds more flexibility.
This commit is contained in:
Sebastian Huber
2015-02-15 10:38:15 +01:00
parent f78549221b
commit a43a34666e
6 changed files with 51 additions and 26 deletions

View File

@@ -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;

View File

@@ -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.
*/

View File

@@ -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;

View File

@@ -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 );
}

View File

@@ -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;
}

View File

@@ -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