mirror of
https://github.com/drasko/codezero.git
synced 2026-01-12 02:43:15 +01:00
Added resolving of current directory in case lookup starts from current dir.
This commit is contained in:
@@ -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;
|
||||
|
||||
@@ -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__ */
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user