Subversion Repositories HelenOS

Compare Revisions

Ignore whitespace Rev 2924 → Rev 2925

/branches/tracing/uspace/lib/libfs/libfs.c
142,42 → 142,38
dev_handle_t dev_handle = IPC_GET_ARG3(*request);
int lflag = IPC_GET_ARG4(*request);
fs_index_t index = IPC_GET_ARG5(*request); /* when L_LINK specified */
char component[NAME_MAX + 1];
int len;
 
if (last < next)
last += PLB_SIZE;
 
void *par = NULL;
void *cur = ops->root_get();
void *tmp = ops->child_get(cur);
void *cur = ops->root_get(dev_handle);
void *tmp = NULL;
 
if (ops->plb_get_char(next) == '/')
next++; /* eat slash */
char component[NAME_MAX + 1];
int len = 0;
while (tmp && next <= last) {
 
while (ops->has_children(cur) && next <= last) {
/* collect the component */
if (ops->plb_get_char(next) != '/') {
len = 0;
while ((ops->plb_get_char(next) != '/') && (next <= last)) {
if (len + 1 == NAME_MAX) {
/* comopnent length overflow */
ipc_answer_0(rid, ENAMETOOLONG);
return;
goto out;
}
component[len++] = ops->plb_get_char(next);
next++; /* process next character */
if (next <= last)
continue;
}
 
assert(len);
component[len] = '\0';
next++; /* eat slash */
len = 0;
 
/* match the component */
while (tmp && !ops->match(cur, tmp, component))
tmp = ops->sibling_get(tmp);
tmp = ops->match(cur, component);
 
/* handle miss: match amongst siblings */
if (!tmp) {
184,7 → 180,7
if (next <= last) {
/* there are unprocessed components */
ipc_answer_0(rid, ENOENT);
return;
goto out;
}
/* miss in the last component */
if (lflag & (L_CREATE | L_LINK)) {
191,18 → 187,18
/* request to create a new link */
if (!ops->is_directory(cur)) {
ipc_answer_0(rid, ENOTDIR);
return;
goto out;
}
void *nodep;
if (lflag & L_CREATE)
nodep = ops->create(lflag);
else
nodep = ops->node_get(fs_handle,
dev_handle, index);
nodep = ops->node_get(dev_handle,
index);
if (nodep) {
if (!ops->link(cur, nodep, component)) {
if (lflag & L_CREATE)
ops->destroy(nodep);
(void)ops->destroy(nodep);
ipc_answer_0(rid, ENOSPC);
} else {
ipc_answer_5(rid, EOK,
210,11 → 206,12
ops->index_get(nodep),
ops->size_get(nodep),
ops->lnkcnt_get(nodep));
ops->node_put(nodep);
}
} else {
ipc_answer_0(rid, ENOSPC);
}
return;
goto out;
} else if (lflag & L_PARENT) {
/* return parent */
ipc_answer_5(rid, EOK, fs_handle, dev_handle,
222,34 → 219,38
ops->lnkcnt_get(cur));
}
ipc_answer_0(rid, ENOENT);
return;
goto out;
}
 
if (par)
ops->node_put(par);
 
/* descend one level */
par = cur;
cur = tmp;
tmp = ops->child_get(tmp);
tmp = NULL;
}
 
/* handle miss: excessive components */
if (!tmp && next <= last) {
if (!ops->has_children(cur) && next <= last) {
if (lflag & (L_CREATE | L_LINK)) {
if (!ops->is_directory(cur)) {
ipc_answer_0(rid, ENOTDIR);
return;
goto out;
}
 
/* collect next component */
len = 0;
while (next <= last) {
if (ops->plb_get_char(next) == '/') {
/* more than one component */
ipc_answer_0(rid, ENOENT);
return;
goto out;
}
if (len + 1 == NAME_MAX) {
/* component length overflow */
ipc_answer_0(rid, ENAMETOOLONG);
return;
goto out;
}
component[len++] = ops->plb_get_char(next);
next++; /* process next character */
256,18 → 257,16
}
assert(len);
component[len] = '\0';
len = 0;
void *nodep;
if (lflag & L_CREATE)
nodep = ops->create(lflag);
else
nodep = ops->node_get(fs_handle, dev_handle,
index);
nodep = ops->node_get(dev_handle, index);
if (nodep) {
if (!ops->link(cur, nodep, component)) {
if (lflag & L_CREATE)
ops->destroy(nodep);
(void)ops->destroy(nodep);
ipc_answer_0(rid, ENOSPC);
} else {
ipc_answer_5(rid, EOK,
275,22 → 274,25
ops->index_get(nodep),
ops->size_get(nodep),
ops->lnkcnt_get(nodep));
ops->node_put(nodep);
}
} else {
ipc_answer_0(rid, ENOSPC);
}
return;
goto out;
}
ipc_answer_0(rid, ENOENT);
return;
goto out;
}
 
/* handle hit */
if (lflag & L_PARENT) {
ops->node_put(cur);
cur = par;
par = NULL;
if (!cur) {
ipc_answer_0(rid, ENOENT);
return;
goto out;
}
}
if (lflag & L_UNLINK) {
298,24 → 300,32
int res = ops->unlink(par, cur);
ipc_answer_5(rid, (ipcarg_t)res, fs_handle, dev_handle,
ops->index_get(cur), ops->size_get(cur), old_lnkcnt);
return;
goto out;
}
if (((lflag & (L_CREATE | L_EXCLUSIVE)) == (L_CREATE | L_EXCLUSIVE)) ||
(lflag & L_LINK)) {
ipc_answer_0(rid, EEXIST);
return;
goto out;
}
if ((lflag & L_FILE) && (ops->is_directory(cur))) {
ipc_answer_0(rid, EISDIR);
return;
goto out;
}
if ((lflag & L_DIRECTORY) && (ops->is_file(cur))) {
ipc_answer_0(rid, ENOTDIR);
return;
goto out;
}
 
ipc_answer_5(rid, EOK, fs_handle, dev_handle, ops->index_get(cur),
ops->size_get(cur), ops->lnkcnt_get(cur));
 
out:
if (par)
ops->node_put(par);
if (cur)
ops->node_put(cur);
if (tmp)
ops->node_put(tmp);
}
 
/** @}