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

View File

@@ -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;

View File

@@ -7,6 +7,7 @@
#define __PATH_H__
#include <l4/lib/list.h>
#include <task.h>
/*
* 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__ */

View File

@@ -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);

View File

@@ -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;

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,
* 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);

View File

@@ -10,11 +10,13 @@
#include <lib/malloc.h>
#include <path.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;
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);

View File

@@ -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;

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 *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)