diff --git a/tasks/fs0/include/fs.h b/tasks/fs0/include/fs.h index 69c3ce2..42ccd96 100644 --- a/tasks/fs0/include/fs.h +++ b/tasks/fs0/include/fs.h @@ -47,7 +47,7 @@ struct file_ops { struct vnode_ops { vnode_op_t create; struct vnode *(*lookup)(struct vnode *root, char *path); - void *(*readdir)(struct vnode *v, void *dirbuf); + int (*readdir)(struct vnode *v); vnode_op_t link; vnode_op_t unlink; vnode_op_t mkdir; diff --git a/tasks/fs0/src/lookup.c b/tasks/fs0/src/lookup.c index ae01faa..aafe402 100644 --- a/tasks/fs0/src/lookup.c +++ b/tasks/fs0/src/lookup.c @@ -76,8 +76,8 @@ struct vnode *generic_vnode_lookup(struct vnode *thisnode, char *path) /* Are there any more path components? */ if (path) /* Read directory contents */ - if (IS_ERR(err = (int)d->vnode->ops.readdir(d->vnode, 0))) - return PTR_ERR(err); + if ((err = (int)d->vnode->ops.readdir(d->vnode))) + return err; /* Search all children one level below. */ if ((found = lookup_dentry_children(d, path))) /* Either found, or non-zero error */ diff --git a/tasks/fs0/src/memfs/vnode.c b/tasks/fs0/src/memfs/vnode.c index 109c9e8..1565b8d 100644 --- a/tasks/fs0/src/memfs/vnode.c +++ b/tasks/fs0/src/memfs/vnode.c @@ -201,10 +201,7 @@ int memfs_write_vnode(struct superblock *sb, struct vnode *v) return 0; } - /* - * Given a non-zero dirbuf, uses it, otherwise it allocates one on its own. - * * Allocates and populates all dentries and their corresponding vnodes that are * the direct children of vnode v. This means that by each call to readdir, the vfs * layer increases its cache of filesystem tree by one level beneath that directory. @@ -223,18 +220,20 @@ int memfs_vnode_readdir(struct vnode *v) if (!vfs_isdir(v)) return -ENOTDIR; - /* Allocate dirbuf if one is not provided by the upper layer */ - if (!v->dirbuf->buffer) { - /* This is as big as a page */ - v->dirbuf->buffer = vfs_alloc_dirbuf(); - memfsd = dirbuf = v->dirbuf->buffer; + /* If a buffer is there, it means the directory is already read */ + if (v->dirbuf->buffer) + return 0; - /* - * Fail if vnode size is bigger than a page. Since this allocation - * method is to be replaced, we can live with this limitation for now. - */ - BUG_ON(v->size > PAGE_SIZE); - } + /* This is as big as a page */ + v->dirbuf->buffer = vfs_alloc_dirbuf(); + v->dirbuf->npages = 1; + memfsd = dirbuf = v->dirbuf->buffer; + + /* + * Fail if vnode size is bigger than a page. Since this allocation + * method is to be replaced, we can live with this limitation for now. + */ + BUG_ON(v->size > PAGE_SIZE); /* Read memfsd contents into the buffer */ if ((err = v->fops.read(v, 0, 1, dirbuf))) @@ -271,6 +270,7 @@ int memfs_vnode_readdir(struct vnode *v) list_add(&newd->cache_list, &dentry_cache); list_add(&newv->cache_list, &vnode_cache); } + return 0; }