Subversion Repositories HelenOS

Compare Revisions

Ignore whitespace Rev 2741 → Rev 2742

/trunk/uspace/srv/fs/tmpfs/tmpfs_ops.c
61,9 → 61,13
#define TMPFS_GET_INDEX(x) (((tmpfs_dentry_t *)(x))->index)
#define TMPFS_GET_LNKCNT(x) 1
 
/*
* Hash table of all directory entries.
*/
/* Forward declarations of static functions. */
static void *create_node(int);
static bool link_node(void *, void *, const char *);
static int unlink_node(void *);
static void destroy_node(void *);
 
/** Hash table of all directory entries. */
hash_table_t dentries;
 
static hash_index_t dentries_hash(unsigned long *key)
115,17 → 119,8
{
if (!hash_table_create(&dentries, DENTRIES_BUCKETS, 1, &dentries_ops))
return false;
 
root = (tmpfs_dentry_t *) malloc(sizeof(tmpfs_dentry_t));
if (!root)
return false;
tmpfs_dentry_initialize(root);
root->index = tmpfs_next_index++;
root->name = "";
root->type = TMPFS_DIRECTORY;
hash_table_insert(&dentries, &root->index, &root->dh_link);
 
return true;
root = (tmpfs_dentry_t *) create_node(L_DIRECTORY);
return root != NULL;
}
 
/** Compare one component of path to a directory entry.
142,50 → 137,55
return !strcmp(dentry->name, component);
}
 
static void *create_node(void *nodep,
const char *component, int lflag)
void *create_node(int lflag)
{
tmpfs_dentry_t *dentry = (tmpfs_dentry_t *) nodep;
 
assert(dentry->type == TMPFS_DIRECTORY);
assert((lflag & L_FILE) ^ (lflag & L_DIRECTORY));
 
tmpfs_dentry_t *node = malloc(sizeof(tmpfs_dentry_t));
if (!node)
return NULL;
size_t len = strlen(component);
char *name = malloc(len + 1);
if (!name) {
free(node);
return NULL;
}
strcpy(name, component);
 
tmpfs_dentry_initialize(node);
node->index = tmpfs_next_index++;
node->name = name;
node->parent = dentry;
if (lflag & L_DIRECTORY)
node->type = TMPFS_DIRECTORY;
else
node->type = TMPFS_FILE;
 
/* Insert the new node into the dentry hash table. */
hash_table_insert(&dentries, &node->index, &node->dh_link);
return (void *) node;
}
 
bool link_node(void *prnt, void *chld, const char *nm)
{
tmpfs_dentry_t *parentp = (tmpfs_dentry_t *) prnt;
tmpfs_dentry_t *childp = (tmpfs_dentry_t *) chld;
 
assert(parentp->type == TMPFS_DIRECTORY);
 
size_t len = strlen(nm);
char *name = malloc(len + 1);
if (!name)
return false;
strcpy(name, nm);
childp->name = name;
 
/* Insert the new node into the namespace. */
if (dentry->child) {
tmpfs_dentry_t *tmp = dentry->child;
if (parentp->child) {
tmpfs_dentry_t *tmp = parentp->child;
while (tmp->sibling)
tmp = tmp->sibling;
tmp->sibling = node;
tmp->sibling = childp;
} else {
dentry->child = node;
parentp->child = childp;
}
childp->parent = parentp;
 
/* Insert the new node into the dentry hash table. */
hash_table_insert(&dentries, &node->index, &node->dh_link);
return (void *) node;
return true;
}
 
static int destroy_component(void *nodeptr)
int unlink_node(void *nodeptr)
{
tmpfs_dentry_t *dentry = (tmpfs_dentry_t *)nodeptr;
 
207,9 → 207,27
dentry->sibling = NULL;
dentry->parent = NULL;
 
free(dentry->name);
dentry->name = NULL;
 
return EOK;
}
 
void destroy_node(void *nodep)
{
tmpfs_dentry_t *dentry = (tmpfs_dentry_t *) nodep;
assert(!dentry->child);
assert(!dentry->sibling);
 
unsigned long index = dentry->index;
hash_table_remove(&dentries, &index, 1);
 
if (dentry->type == TMPFS_FILE)
free(dentry->data);
free(dentry);
}
 
void tmpfs_lookup(ipc_callid_t rid, ipc_call_t *request)
{
unsigned next = IPC_GET_ARG1(*request);
268,13 → 286,19
ipc_answer_0(rid, ENOTDIR);
return;
}
void *nodep = create_node(dcur,
component, lflag);
void *nodep = create_node(lflag);
if (nodep) {
ipc_answer_5(rid, EOK,
tmpfs_reg.fs_handle, dev_handle,
TMPFS_GET_INDEX(nodep), 0,
TMPFS_GET_LNKCNT(nodep));
if (!link_node(dcur, nodep,
component)) {
destroy_node(nodep);
ipc_answer_0(rid, ENOSPC);
} else {
ipc_answer_5(rid, EOK,
tmpfs_reg.fs_handle,
dev_handle,
TMPFS_GET_INDEX(nodep), 0,
TMPFS_GET_LNKCNT(nodep));
}
} else {
ipc_answer_0(rid, ENOSPC);
}
316,11 → 340,17
component[len] = '\0';
len = 0;
void *nodep = create_node(dcur, component, lflag);
void *nodep = create_node(lflag);
if (nodep) {
ipc_answer_5(rid, EOK, tmpfs_reg.fs_handle,
dev_handle, TMPFS_GET_INDEX(nodep), 0,
TMPFS_GET_LNKCNT(nodep));
if (!link_node(dcur, nodep, component)) {
destroy_node(nodep);
ipc_answer_0(rid, ENOSPC);
} else {
ipc_answer_5(rid, EOK,
tmpfs_reg.fs_handle,
dev_handle, TMPFS_GET_INDEX(nodep),
0, TMPFS_GET_LNKCNT(nodep));
}
} else {
ipc_answer_0(rid, ENOSPC);
}
333,7 → 363,7
/* handle hit */
if (lflag & L_DESTROY) {
unsigned old_lnkcnt = TMPFS_GET_LNKCNT(dcur);
int res = destroy_component(dcur);
int res = unlink_node(dcur);
ipc_answer_5(rid, (ipcarg_t)res, tmpfs_reg.fs_handle,
dev_handle, dcur->index, dcur->size, old_lnkcnt);
return;
518,7 → 548,7
ipc_answer_0(rid, EOK);
}
 
void tmpfs_free(ipc_callid_t rid, ipc_call_t *request)
void tmpfs_destroy(ipc_callid_t rid, ipc_call_t *request)
{
int dev_handle = IPC_GET_ARG1(*request);
unsigned long index = IPC_GET_ARG2(*request);
531,18 → 561,7
}
tmpfs_dentry_t *dentry = hash_table_get_instance(hlp, tmpfs_dentry_t,
dh_link);
assert(!dentry->parent);
assert(!dentry->child);
assert(!dentry->sibling);
 
hash_table_remove(&dentries, &index, 1);
 
if (dentry->type == TMPFS_FILE)
free(dentry->data);
free(dentry->name);
free(dentry);
 
destroy_node(dentry);
ipc_answer_0(rid, EOK);
}