diff --git a/tasks/fs0/include/fs.h b/tasks/fs0/include/fs.h index d2403fa..0081912 100644 --- a/tasks/fs0/include/fs.h +++ b/tasks/fs0/include/fs.h @@ -22,7 +22,7 @@ struct superblock; struct vnode; struct dentry_ops { - int (*compare)(struct dentry *d, char *n); + int (*compare)(struct dentry *d, const char *n); }; /* Operations that work on file content */ @@ -47,13 +47,13 @@ struct file_ops { struct vnode_ops { vnode_op_t create; struct vnode *(*lookup)(struct vnode *root, struct pathdata *pdata, - char *component); + const char *component); int (*readdir)(struct vnode *v); int (*filldir)(void *buf, struct vnode *v, int count); vnode_op_t link; vnode_op_t unlink; - int (*mkdir)(struct vnode *parent, char *name); - int (*mknod)(struct vnode *parent, char *name, unsigned int mode); + int (*mkdir)(struct vnode *parent, const char *name); + int (*mknod)(struct vnode *parent, const char *name, unsigned int mode); vnode_op_t rmdir; vnode_op_t rename; vnode_op_t getattr; diff --git a/tasks/fs0/include/path.h b/tasks/fs0/include/path.h index 8101f4e..ea6ad52 100644 --- a/tasks/fs0/include/path.h +++ b/tasks/fs0/include/path.h @@ -7,6 +7,7 @@ #define __PATH_H__ #include +#include /* * FIXME: @@ -21,13 +22,13 @@ struct pathdata { struct list_head list; - struct tcb *task; + struct vnode *vstart; int root; }; struct pathcomp { struct list_head list; - char *str; + const char *str; }; 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); /* Destructive, i.e. unlinks those components from list */ -char *pathdata_next_component(struct pathdata *pdata); -char *pathdata_last_component(struct pathdata *pdata); +const char *pathdata_next_component(struct pathdata *pdata); +const char *pathdata_last_component(struct pathdata *pdata); #endif /* __PATH_H__ */ diff --git a/tasks/fs0/include/vfs.h b/tasks/fs0/include/vfs.h index 876181f..5f13fb7 100644 --- a/tasks/fs0/include/vfs.h +++ b/tasks/fs0/include/vfs.h @@ -83,7 +83,7 @@ extern struct vfs_mountpoint vfs_root; int vfs_mount_root(struct superblock *sb); 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_byvnum(struct superblock *sb, unsigned long vnum); diff --git a/tasks/fs0/src/lookup.c b/tasks/fs0/src/lookup.c index abca41b..16cec21 100644 --- a/tasks/fs0/src/lookup.c +++ b/tasks/fs0/src/lookup.c @@ -20,7 +20,7 @@ struct vnode *lookup_dentry_children(struct dentry *parentdir, { struct dentry *childdir; struct vnode *v; - char *component = pathdata_next_component(pdata); + const char *component = pathdata_next_component(pdata); list_for_each_entry(childdir, &parentdir->children, child) 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 */ struct vnode *generic_vnode_lookup(struct vnode *thisnode, struct pathdata *pdata, - char *component) + const char *component) { struct dentry *d; struct vnode *found; @@ -76,7 +76,7 @@ struct vnode *generic_vnode_lookup(struct vnode *thisnode, 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)) return 1; diff --git a/tasks/fs0/src/memfs/vnode.c b/tasks/fs0/src/memfs/vnode.c index 650459c..c1d1ef8 100644 --- a/tasks/fs0/src/memfs/vnode.c +++ b/tasks/fs0/src/memfs/vnode.c @@ -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, * 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, vref); diff --git a/tasks/fs0/src/path.c b/tasks/fs0/src/path.c index bb5ff87..48d5122 100644 --- a/tasks/fs0/src/path.c +++ b/tasks/fs0/src/path.c @@ -10,11 +10,13 @@ #include #include #include +#include +#include -char *pathdata_next_component(struct pathdata *pdata) +const char *pathdata_next_component(struct pathdata *pdata) { struct pathcomp *p, *n; - char *pathstr; + const char *pathstr; list_for_each_entry_safe(p, n, &pdata->list, 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 */ -char *pathdata_last_component(struct pathdata *pdata) +const char *pathdata_last_component(struct pathdata *pdata) { struct pathcomp *p; - char *pathstr; + const char *pathstr; if (!list_empty(&pdata->list)) { p = list_entry(pdata->list.prev, struct pathcomp, list); @@ -77,9 +79,8 @@ struct pathdata *pathdata_parse(const char *pathname, /* Initialise pathdata */ INIT_LIST_HEAD(&pdata->list); 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 (!(comp = kzalloc(sizeof(*comp)))) { kfree(pdata); @@ -88,19 +89,47 @@ struct pathdata *pathdata_parse(const char *pathname, INIT_LIST_HEAD(&comp->list); comp->str = VFS_STR_ROOTDIR; 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 */ str = splitpath(&pathbuf, VFS_CHAR_SEP); while(*str) { - if (!(comp = kzalloc(sizeof(*comp)))) { - pathdata_destroy(pdata); - return PTR_ERR(-ENOMEM); + /* Any curdir components in path are ignored. */ + if (!strcmp(str, VFS_STR_CURDIR)) { + ; + } 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 */ str = splitpath(&pathbuf, VFS_CHAR_SEP); diff --git a/tasks/fs0/src/syscalls.c b/tasks/fs0/src/syscalls.c index c05cd96..2c0d5a1 100644 --- a/tasks/fs0/src/syscalls.c +++ b/tasks/fs0/src/syscalls.c @@ -61,7 +61,7 @@ void print_vnode(struct vnode *v) int vfs_create(struct tcb *task, struct pathdata *pdata, unsigned int mode) { struct vnode *vparent; - char *nodename; + const char *nodename; int err; /* 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) return 0; - fill_dirent(buf, v->vnum, nbytes, "."); + fill_dirent(buf, v->vnum, nbytes, VFS_STR_CURDIR); nbytes += dirent_size; buf += 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) return 0; - fill_dirent(buf, d->parent->vnode->vnum, nbytes, ".."); + fill_dirent(buf, d->parent->vnode->vnum, nbytes, VFS_STR_PARDIR); nbytes += dirent_size; buf += dirent_size; count -= dirent_size; diff --git a/tasks/fs0/src/vfs.c b/tasks/fs0/src/vfs.c index f2ea262..9afde6a 100644 --- a/tasks/fs0/src/vfs.c +++ b/tasks/fs0/src/vfs.c @@ -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 *vstart; - char *firstcomp; - - /* Do we start from root or curdir? */ - if (pdata->root) - vstart = pdata->task->rootdir; - else - vstart = pdata->task->curdir; + const char *firstcomp; /* * This does vfs cache + fs lookup. */ BUG_ON(list_empty(&pdata->list)); 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)