forked from Imagelibrary/rtems
IMFS: Implement variable length node names
This reduces the average node size and adds more flexibility.
This commit is contained in:
@@ -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;
|
||||
|
||||
@@ -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.
|
||||
*/
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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 );
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user