Added resolving of current directory in case lookup starts from current dir.

This commit is contained in:
Bahadir Balban
2008-04-16 14:48:05 +01:00
parent 9d32f840c0
commit 730e7c210f
8 changed files with 61 additions and 38 deletions
+4 -4
View File
@@ -22,7 +22,7 @@ struct superblock;
struct vnode; struct vnode;
struct dentry_ops { struct dentry_ops {
int (*compare)(struct dentry *d, char *n); int (*compare)(struct dentry *d, const char *n);
}; };
/* Operations that work on file content */ /* Operations that work on file content */
@@ -47,13 +47,13 @@ struct file_ops {
struct vnode_ops { struct vnode_ops {
vnode_op_t create; vnode_op_t create;
struct vnode *(*lookup)(struct vnode *root, struct pathdata *pdata, struct vnode *(*lookup)(struct vnode *root, struct pathdata *pdata,
char *component); const char *component);
int (*readdir)(struct vnode *v); int (*readdir)(struct vnode *v);
int (*filldir)(void *buf, struct vnode *v, int count); int (*filldir)(void *buf, struct vnode *v, int count);
vnode_op_t link; vnode_op_t link;
vnode_op_t unlink; vnode_op_t unlink;
int (*mkdir)(struct vnode *parent, char *name); int (*mkdir)(struct vnode *parent, const char *name);
int (*mknod)(struct vnode *parent, char *name, unsigned int mode); int (*mknod)(struct vnode *parent, const char *name, unsigned int mode);
vnode_op_t rmdir; vnode_op_t rmdir;
vnode_op_t rename; vnode_op_t rename;
vnode_op_t getattr; vnode_op_t getattr;
+5 -4
View File
@@ -7,6 +7,7 @@
#define __PATH_H__ #define __PATH_H__
#include <l4/lib/list.h> #include <l4/lib/list.h>
#include <task.h>
/* /*
* FIXME: * FIXME:
@@ -21,13 +22,13 @@
struct pathdata { struct pathdata {
struct list_head list; struct list_head list;
struct tcb *task; struct vnode *vstart;
int root; int root;
}; };
struct pathcomp { struct pathcomp {
struct list_head list; struct list_head list;
char *str; const char *str;
}; };
struct pathdata *pathdata_parse(const char *pathname, char *pathbuf, struct pathdata *pathdata_parse(const char *pathname, char *pathbuf,
@@ -35,7 +36,7 @@ struct pathdata *pathdata_parse(const char *pathname, char *pathbuf,
void pathdata_destroy(struct pathdata *p); void pathdata_destroy(struct pathdata *p);
/* Destructive, i.e. unlinks those components from list */ /* Destructive, i.e. unlinks those components from list */
char *pathdata_next_component(struct pathdata *pdata); const char *pathdata_next_component(struct pathdata *pdata);
char *pathdata_last_component(struct pathdata *pdata); const char *pathdata_last_component(struct pathdata *pdata);
#endif /* __PATH_H__ */ #endif /* __PATH_H__ */
+1 -1
View File
@@ -83,7 +83,7 @@ extern struct vfs_mountpoint vfs_root;
int vfs_mount_root(struct superblock *sb); int vfs_mount_root(struct superblock *sb);
struct vnode *generic_vnode_lookup(struct vnode *thisnode, struct pathdata *p, struct vnode *generic_vnode_lookup(struct vnode *thisnode, struct pathdata *p,
char *component); const char *component);
struct vnode *vfs_lookup_bypath(struct pathdata *p); struct vnode *vfs_lookup_bypath(struct pathdata *p);
struct vnode *vfs_lookup_byvnum(struct superblock *sb, unsigned long vnum); struct vnode *vfs_lookup_byvnum(struct superblock *sb, unsigned long vnum);
+3 -3
View File
@@ -20,7 +20,7 @@ struct vnode *lookup_dentry_children(struct dentry *parentdir,
{ {
struct dentry *childdir; struct dentry *childdir;
struct vnode *v; struct vnode *v;
char *component = pathdata_next_component(pdata); const char *component = pathdata_next_component(pdata);
list_for_each_entry(childdir, &parentdir->children, child) list_for_each_entry(childdir, &parentdir->children, child)
if (IS_ERR(v = childdir->vnode->ops.lookup(childdir->vnode, if (IS_ERR(v = childdir->vnode->ops.lookup(childdir->vnode,
@@ -40,7 +40,7 @@ struct vnode *lookup_dentry_children(struct dentry *parentdir,
/* Lookup, recursive, assuming single-mountpoint */ /* Lookup, recursive, assuming single-mountpoint */
struct vnode *generic_vnode_lookup(struct vnode *thisnode, struct vnode *generic_vnode_lookup(struct vnode *thisnode,
struct pathdata *pdata, struct pathdata *pdata,
char *component) const char *component)
{ {
struct dentry *d; struct dentry *d;
struct vnode *found; struct vnode *found;
@@ -76,7 +76,7 @@ struct vnode *generic_vnode_lookup(struct vnode *thisnode,
return PTR_ERR(-ENOENT); return PTR_ERR(-ENOENT);
} }
int generic_dentry_compare(struct dentry *d, char *name) int generic_dentry_compare(struct dentry *d, const char *name)
{ {
if (!strcmp(d->name, name) || !strcmp(name, VFS_STR_CURDIR)) if (!strcmp(d->name, name) || !strcmp(name, VFS_STR_CURDIR))
return 1; return 1;
+1 -1
View File
@@ -210,7 +210,7 @@ int memfs_write_vnode(struct superblock *sb, struct vnode *v)
* Creates ordinary files and directories at the moment. In the future, * Creates ordinary files and directories at the moment. In the future,
* other file types will be added. * other file types will be added.
*/ */
int memfs_vnode_mknod(struct vnode *v, char *dirname, unsigned int mode) int memfs_vnode_mknod(struct vnode *v, const char *dirname, unsigned int mode)
{ {
struct dentry *d, *parent = list_entry(v->dentries.next, struct dentry *d, *parent = list_entry(v->dentries.next,
struct dentry, vref); struct dentry, vref);
+42 -13
View File
@@ -10,11 +10,13 @@
#include <lib/malloc.h> #include <lib/malloc.h>
#include <path.h> #include <path.h>
#include <stdio.h> #include <stdio.h>
#include <fs.h>
#include <task.h>
char *pathdata_next_component(struct pathdata *pdata) const char *pathdata_next_component(struct pathdata *pdata)
{ {
struct pathcomp *p, *n; struct pathcomp *p, *n;
char *pathstr; const char *pathstr;
list_for_each_entry_safe(p, n, &pdata->list, list) { list_for_each_entry_safe(p, n, &pdata->list, list) {
list_del(&p->list); list_del(&p->list);
@@ -26,10 +28,10 @@ char *pathdata_next_component(struct pathdata *pdata)
} }
/* Check there's at least one element, unlink and return the last element */ /* Check there's at least one element, unlink and return the last element */
char *pathdata_last_component(struct pathdata *pdata) const char *pathdata_last_component(struct pathdata *pdata)
{ {
struct pathcomp *p; struct pathcomp *p;
char *pathstr; const char *pathstr;
if (!list_empty(&pdata->list)) { if (!list_empty(&pdata->list)) {
p = list_entry(pdata->list.prev, struct pathcomp, list); p = list_entry(pdata->list.prev, struct pathcomp, list);
@@ -77,9 +79,8 @@ struct pathdata *pathdata_parse(const char *pathname,
/* Initialise pathdata */ /* Initialise pathdata */
INIT_LIST_HEAD(&pdata->list); INIT_LIST_HEAD(&pdata->list);
strcpy(pathbuf, pathname); strcpy(pathbuf, pathname);
pdata->task = task;
/* Handle root if there's a root */ /* First component is root if there's a root */
if (pathname[0] == VFS_CHAR_SEP) { if (pathname[0] == VFS_CHAR_SEP) {
if (!(comp = kzalloc(sizeof(*comp)))) { if (!(comp = kzalloc(sizeof(*comp)))) {
kfree(pdata); kfree(pdata);
@@ -88,19 +89,47 @@ struct pathdata *pathdata_parse(const char *pathname,
INIT_LIST_HEAD(&comp->list); INIT_LIST_HEAD(&comp->list);
comp->str = VFS_STR_ROOTDIR; comp->str = VFS_STR_ROOTDIR;
list_add_tail(&comp->list, &pdata->list); list_add_tail(&comp->list, &pdata->list);
pdata->root = 1;
/* Lookup start vnode is root vnode */
pdata->vstart = task->rootdir;
/* Otherwise start from current directory */
} else {
struct dentry *curdir;
if (!(comp = kzalloc(sizeof(*comp)))) {
kfree(pdata);
return PTR_ERR(-ENOMEM);
}
INIT_LIST_HEAD(&comp->list);
/* Get current dentry for this task */
curdir = list_entry(task->curdir->dentries.next,
struct dentry, vref);
/* Use its name in path component */
comp->str = curdir->name;
list_add_tail(&comp->list, &pdata->list);
/* Lookup start vnode is current dir vnode */
pdata->vstart = task->curdir;
} }
/* Add every other path component */ /* Add every other path component */
str = splitpath(&pathbuf, VFS_CHAR_SEP); str = splitpath(&pathbuf, VFS_CHAR_SEP);
while(*str) { while(*str) {
if (!(comp = kzalloc(sizeof(*comp)))) { /* Any curdir components in path are ignored. */
pathdata_destroy(pdata); if (!strcmp(str, VFS_STR_CURDIR)) {
return PTR_ERR(-ENOMEM); ;
} else {
if (!(comp = kzalloc(sizeof(*comp)))) {
pathdata_destroy(pdata);
return PTR_ERR(-ENOMEM);
}
INIT_LIST_HEAD(&comp->list);
comp->str = str;
list_add_tail(&comp->list, &pdata->list);
} }
INIT_LIST_HEAD(&comp->list);
comp->str = str;
list_add_tail(&comp->list, &pdata->list);
/* Next component */ /* Next component */
str = splitpath(&pathbuf, VFS_CHAR_SEP); str = splitpath(&pathbuf, VFS_CHAR_SEP);
+3 -3
View File
@@ -61,7 +61,7 @@ void print_vnode(struct vnode *v)
int vfs_create(struct tcb *task, struct pathdata *pdata, unsigned int mode) int vfs_create(struct tcb *task, struct pathdata *pdata, unsigned int mode)
{ {
struct vnode *vparent; struct vnode *vparent;
char *nodename; const char *nodename;
int err; int err;
/* The last component is to be created */ /* The last component is to be created */
@@ -325,7 +325,7 @@ int sys_readdir(l4id_t sender, int fd, void *buf, int count)
if (count < dirent_size) if (count < dirent_size)
return 0; return 0;
fill_dirent(buf, v->vnum, nbytes, "."); fill_dirent(buf, v->vnum, nbytes, VFS_STR_CURDIR);
nbytes += dirent_size; nbytes += dirent_size;
buf += dirent_size; buf += dirent_size;
count -= dirent_size; count -= dirent_size;
@@ -333,7 +333,7 @@ int sys_readdir(l4id_t sender, int fd, void *buf, int count)
if (count < dirent_size) if (count < dirent_size)
return 0; return 0;
fill_dirent(buf, d->parent->vnode->vnum, nbytes, ".."); fill_dirent(buf, d->parent->vnode->vnum, nbytes, VFS_STR_PARDIR);
nbytes += dirent_size; nbytes += dirent_size;
buf += dirent_size; buf += dirent_size;
count -= dirent_size; count -= dirent_size;
+2 -9
View File
@@ -60,21 +60,14 @@ struct vnode *vfs_lookup_byvnum(struct superblock *sb, unsigned long vnum)
*/ */
struct vnode *vfs_lookup_bypath(struct pathdata *pdata) struct vnode *vfs_lookup_bypath(struct pathdata *pdata)
{ {
struct vnode *vstart; const char *firstcomp;
char *firstcomp;
/* Do we start from root or curdir? */
if (pdata->root)
vstart = pdata->task->rootdir;
else
vstart = pdata->task->curdir;
/* /*
* This does vfs cache + fs lookup. * This does vfs cache + fs lookup.
*/ */
BUG_ON(list_empty(&pdata->list)); BUG_ON(list_empty(&pdata->list));
firstcomp = pathdata_next_component(pdata); firstcomp = pathdata_next_component(pdata);
return vstart->ops.lookup(vstart, pdata, firstcomp); return pdata->vstart->ops.lookup(pdata->vstart, pdata, firstcomp);
} }
int vfs_mount_root(struct superblock *sb) int vfs_mount_root(struct superblock *sb)