mirror of
https://github.com/drasko/codezero.git
synced 2026-09-18 19:30:22 +02:00
Adds tracking of hardlinks when reading a directory.
This commit is contained in:
@@ -102,7 +102,7 @@ struct dirbuf {
|
|||||||
struct vnode {
|
struct vnode {
|
||||||
unsigned long vnum; /* Filesystem-wide unique vnode id */
|
unsigned long vnum; /* Filesystem-wide unique vnode id */
|
||||||
int refcnt; /* Reference counter */
|
int refcnt; /* Reference counter */
|
||||||
int hardlinks; /* Number of hard links */
|
int links; /* Number of hard links */
|
||||||
struct superblock *sb; /* Reference to superblock */
|
struct superblock *sb; /* Reference to superblock */
|
||||||
struct vnode_ops ops; /* Operations on this vnode */
|
struct vnode_ops ops; /* Operations on this vnode */
|
||||||
struct file_ops fops; /* File-related 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);
|
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 = newd->vnode = vfs_lookup_byvnum(v->sb, memfsd[i].inum);
|
||||||
newv->vnum = memfsd[i].inum;
|
if (!newv) {
|
||||||
BUG_ON(newv->sb->ops->read_vnode(newv->sb, newv) < 0);
|
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 */
|
/* Assing this dentry as a name of its vnode */
|
||||||
list_add(&newd->vref, &newd->vnode->dentries);
|
list_add(&newd->vref, &newd->vnode->dentries);
|
||||||
|
|
||||||
|
/* Increase link count */
|
||||||
|
newv->links++;
|
||||||
|
|
||||||
/* Copy fields into generic dentry */
|
/* Copy fields into generic dentry */
|
||||||
memcpy(newd->name, memfsd[i].name, MEMFS_DNAME_MAX);
|
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 */
|
/* Tell mm0 about opened vnode information */
|
||||||
BUG_ON(send_pager_opendata(sender, fd, v->vnum) < 0);
|
BUG_ON(send_pager_opendata(sender, fd, v->vnum) < 0);
|
||||||
|
|
||||||
|
kfree(copypath);
|
||||||
return 0;
|
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)
|
if ((err = vparent->ops.mkdir(vparent, newdir_name)) < 0)
|
||||||
return err;
|
return err;
|
||||||
kfree(pathbuf);
|
kfree(pathbuf);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -35,14 +35,6 @@ struct vnode *vfs_lookup_byvnum(struct superblock *sb, unsigned long vnum)
|
|||||||
if (v->vnum == vnum)
|
if (v->vnum == vnum)
|
||||||
return v;
|
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 */
|
/* Check the actual filesystem for the vnode */
|
||||||
v = vfs_alloc_vnode();
|
v = vfs_alloc_vnode();
|
||||||
v->vnum = vnum;
|
v->vnum = vnum;
|
||||||
|
|||||||
Reference in New Issue
Block a user