Subversion Repositories HelenOS

Compare Revisions

Ignore whitespace Rev 2759 → Rev 2760

/trunk/uspace/lib/libfs/libfs.c
175,7 → 175,7
len = 0;
 
/* match the component */
while (tmp && !ops->match(tmp, component))
while (tmp && !ops->match(cur, tmp, component))
tmp = ops->sibling_get(tmp);
 
/* handle miss: match amongst siblings */
/trunk/uspace/lib/libfs/libfs.h
42,7 → 42,7
#include <async.h>
 
typedef struct {
bool (* match)(void *, const char *);
bool (* match)(void *, void *, const char *);
void * (* create)(int);
void (* destroy)(void *);
bool (* link)(void *, void *, const char *);
/trunk/uspace/srv/fs/tmpfs/tmpfs.h
47,7 → 47,7
link_t dh_link; /**< Dentries hash table link. */
struct tmpfs_dentry *sibling;
struct tmpfs_dentry *child;
char *name;
hash_table_t names; /**< All names linking to this TMPFS node. */
enum {
TMPFS_NONE,
TMPFS_FILE,
/trunk/uspace/srv/fs/tmpfs/tmpfs_ops.c
56,6 → 56,8
 
#define DENTRIES_BUCKETS 256
 
#define NAMES_BUCKETS 4
 
/*
* For now, we don't distinguish between different dev_handles/instances. All
* requests resolve to the only instance, rooted in the following variable.
67,7 → 69,7
*/
 
/* Forward declarations of static functions. */
static bool tmpfs_match(void *, const char *);
static bool tmpfs_match(void *, void *, const char *);
static void *tmpfs_create_node(int);
static bool tmpfs_link_node(void *, void *, const char *);
static int tmpfs_unlink_node(void *, void *);
140,7 → 142,7
/** Hash table of all directory entries. */
hash_table_t dentries;
 
/* Implementation of hash table interface. */
/* Implementation of hash table interface for the dentries hash table. */
static hash_index_t dentries_hash(unsigned long *key)
{
return *key % DENTRIES_BUCKETS;
167,17 → 169,61
 
unsigned tmpfs_next_index = 1;
 
static void tmpfs_dentry_initialize(tmpfs_dentry_t *dentry)
typedef struct {
char *name;
tmpfs_dentry_t *parent;
link_t link;
} tmpfs_name_t;
 
/* Implementation of hash table interface for the names hash table. */
static hash_index_t names_hash(unsigned long *key)
{
tmpfs_dentry_t *dentry = (tmpfs_dentry_t *) *key;
return dentry->index % NAMES_BUCKETS;
}
 
static int names_compare(unsigned long *key, hash_count_t keys, link_t *item)
{
tmpfs_dentry_t *dentry = (tmpfs_dentry_t *) *key;
tmpfs_name_t *namep = hash_table_get_instance(item, tmpfs_name_t,
link);
return dentry == namep->parent;
}
 
static void names_remove_callback(link_t *item)
{
tmpfs_name_t *namep = hash_table_get_instance(item, tmpfs_name_t,
link);
free(namep->name);
free(namep);
}
 
/** TMPFS node names hash table operations. */
static hash_table_operations_t names_ops = {
.hash = names_hash,
.compare = names_compare,
.remove_callback = names_remove_callback
};
 
static void tmpfs_name_initialize(tmpfs_name_t *namep)
{
namep->name = NULL;
namep->parent = NULL;
link_initialize(&namep->link);
}
 
static bool tmpfs_dentry_initialize(tmpfs_dentry_t *dentry)
{
dentry->index = 0;
dentry->sibling = NULL;
dentry->child = NULL;
dentry->name = NULL;
dentry->type = TMPFS_NONE;
dentry->lnkcnt = 0;
dentry->size = 0;
dentry->data = NULL;
link_initialize(&dentry->dh_link);
return (bool)hash_table_create(&dentry->names, NAMES_BUCKETS, 1,
&names_ops);
}
 
static bool tmpfs_init(void)
185,22 → 231,33
if (!hash_table_create(&dentries, DENTRIES_BUCKETS, 1, &dentries_ops))
return false;
root = (tmpfs_dentry_t *) tmpfs_create_node(L_DIRECTORY);
if (!root) {
hash_table_destroy(&dentries);
return false;
}
root->lnkcnt = 1;
return root != NULL;
return true;
}
 
/** Compare one component of path to a directory entry.
*
* @param nodep Node to compare the path component with.
* @param prnt Node from which we descended.
* @param chld Node to compare the path component with.
* @param component Array of characters holding component name.
*
* @return True on match, false otherwise.
*/
bool tmpfs_match(void *nodep, const char *component)
bool tmpfs_match(void *prnt, void *chld, const char *component)
{
tmpfs_dentry_t *dentry = (tmpfs_dentry_t *) nodep;
tmpfs_dentry_t *parentp = (tmpfs_dentry_t *) prnt;
tmpfs_dentry_t *childp = (tmpfs_dentry_t *) chld;
 
return !strcmp(dentry->name, component);
unsigned long key = (unsigned long) parentp;
link_t *hlp = hash_table_find(&childp->names, &key);
assert(hlp);
tmpfs_name_t *namep = hash_table_get_instance(hlp, tmpfs_name_t, link);
 
return !strcmp(namep->name, component);
}
 
void *tmpfs_create_node(int lflag)
211,7 → 268,10
if (!node)
return NULL;
 
tmpfs_dentry_initialize(node);
if (!tmpfs_dentry_initialize(node)) {
free(node);
return NULL;
}
node->index = tmpfs_next_index++;
if (lflag & L_DIRECTORY)
node->type = TMPFS_DIRECTORY;
230,16 → 290,24
 
assert(parentp->type == TMPFS_DIRECTORY);
 
tmpfs_name_t *namep = malloc(sizeof(tmpfs_name_t));
if (!namep)
return false;
tmpfs_name_initialize(namep);
size_t len = strlen(nm);
char *name = malloc(len + 1);
if (!name)
namep->name = malloc(len + 1);
if (!namep->name) {
free(namep);
return false;
}
strcpy(namep->name, nm);
namep->parent = parentp;
childp->lnkcnt++;
strcpy(name, nm);
childp->name = name;
 
unsigned long key = (unsigned long) parentp;
hash_table_insert(&childp->names, &key, &namep->link);
 
/* Insert the new node into the namespace. */
if (parentp->child) {
tmpfs_dentry_t *tmp = parentp->child;
275,8 → 343,8
}
childp->sibling = NULL;
 
free(childp->name);
childp->name = NULL;
unsigned long key = (unsigned long) parentp;
hash_table_remove(&childp->names, &key, 1);
 
childp->lnkcnt--;
 
294,6 → 362,8
unsigned long index = dentry->index;
hash_table_remove(&dentries, &index, 1);
 
hash_table_destroy(&dentry->names);
 
if (dentry->type == TMPFS_FILE)
free(dentry->data);
free(dentry);
364,8 → 434,14
return;
}
 
(void) ipc_data_read_finalize(callid, cur->name,
strlen(cur->name) + 1);
unsigned long key = (unsigned long) dentry;
link_t *hlp = hash_table_find(&cur->names, &key);
assert(hlp);
tmpfs_name_t *namep = hash_table_get_instance(hlp, tmpfs_name_t,
link);
 
(void) ipc_data_read_finalize(callid, namep->name,
strlen(namep->name) + 1);
bytes = 1;
}