mirror of
https://github.com/drasko/codezero.git
synced 2026-01-12 02:43:15 +01:00
Adds tracking of hardlinks when reading a directory.
This commit is contained in:
@@ -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 */
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user