From 08b1e0e42c358e4fc5f78d73f9af3df08db19a51 Mon Sep 17 00:00:00 2001 From: Bahadir Balban Date: Sat, 16 Feb 2008 12:36:50 +0000 Subject: [PATCH] Adds tracking of hardlinks when reading a directory. --- tasks/fs0/include/fs.h | 2 +- tasks/fs0/src/memfs/vnode.c | 19 +++++++++++++++---- tasks/fs0/src/syscalls.c | 2 +- tasks/fs0/src/vfs.c | 8 -------- 4 files changed, 17 insertions(+), 14 deletions(-) diff --git a/tasks/fs0/include/fs.h b/tasks/fs0/include/fs.h index fc0a884..1b0829b 100644 --- a/tasks/fs0/include/fs.h +++ b/tasks/fs0/include/fs.h @@ -102,7 +102,7 @@ struct dirbuf { struct vnode { unsigned long vnum; /* Filesystem-wide unique vnode id */ int refcnt; /* Reference counter */ - int hardlinks; /* Number of hard links */ + int links; /* Number of hard links */ struct superblock *sb; /* Reference to superblock */ struct vnode_ops ops; /* Operations on this vnode */ struct file_ops fops; /* File-related operations on this vnode */ diff --git a/tasks/fs0/src/memfs/vnode.c b/tasks/fs0/src/memfs/vnode.c index 325ac86..c50d7eb 100644 --- a/tasks/fs0/src/memfs/vnode.c +++ b/tasks/fs0/src/memfs/vnode.c @@ -334,15 +334,26 @@ int memfs_vnode_readdir(struct vnode *v) list_add(&newd->child, &parent->children); /* - * Read the vnode for dentry by its vnode number. + * Lookup the vnode for dentry by its vnode number. We call + * vnode_lookup_byvnum instead of directly reading it because + * this dentry might just be a link to a vnode that's already + * in the vnode cache. If it's not there, the lookup function + * allocates and reads it for us as well. */ - newv = newd->vnode = vfs_alloc_vnode(); - newv->vnum = memfsd[i].inum; - BUG_ON(newv->sb->ops->read_vnode(newv->sb, newv) < 0); + newv = newd->vnode = vfs_lookup_byvnum(v->sb, memfsd[i].inum); + if (!newv) { + printf("Filesystem seems to be broken. Directory has" + "inode number: %d, but no such inode found.\n", + memfsd[i].inum); + BUG(); + } /* Assing this dentry as a name of its vnode */ list_add(&newd->vref, &newd->vnode->dentries); + /* Increase link count */ + newv->links++; + /* Copy fields into generic dentry */ memcpy(newd->name, memfsd[i].name, MEMFS_DNAME_MAX); diff --git a/tasks/fs0/src/syscalls.c b/tasks/fs0/src/syscalls.c index bbc5bbc..3f359e3 100644 --- a/tasks/fs0/src/syscalls.c +++ b/tasks/fs0/src/syscalls.c @@ -69,6 +69,7 @@ int sys_open(l4id_t sender, const char *pathname, int flags, unsigned int mode) /* Tell mm0 about opened vnode information */ BUG_ON(send_pager_opendata(sender, fd, v->vnum) < 0); + kfree(copypath); return 0; } @@ -97,7 +98,6 @@ int sys_mkdir(l4id_t sender, const char *pathname, unsigned int mode) if ((err = vparent->ops.mkdir(vparent, newdir_name)) < 0) return err; kfree(pathbuf); - return 0; } diff --git a/tasks/fs0/src/vfs.c b/tasks/fs0/src/vfs.c index 4846255..d52a5c2 100644 --- a/tasks/fs0/src/vfs.c +++ b/tasks/fs0/src/vfs.c @@ -35,14 +35,6 @@ struct vnode *vfs_lookup_byvnum(struct superblock *sb, unsigned long vnum) if (v->vnum == vnum) return v; - /* - * In the future it will be possible that a vnum known by the fd table - * is not in the cache, because the cache will be able to grow and shrink. - * But currently it just grows, so its a bug that a known vnum is not in - * the cache. - */ - BUG(); - /* Check the actual filesystem for the vnode */ v = vfs_alloc_vnode(); v->vnum = vnum;