From 3bd235e9e5583beaeda731933ce8d029cdea0fa1 Mon Sep 17 00:00:00 2001 From: "Raphael S. Carvalho" <raphaelsc@cloudius-systems.com> Date: Fri, 3 Jan 2014 16:16:43 -0200 Subject: [PATCH] vfs: Add hierarchy support to directory entries It will be useful to take better and safer VFS decisions in the future. For example, avoiding code that uses the absolute path to determine something. Signed-off-by: Raphael S. Carvalho <raphaelsc@cloudius-systems.com> Signed-off-by: Pekka Enberg <penberg@cloudius-systems.com> --- fs/vfs/vfs.h | 2 +- fs/vfs/vfs_lookup.c | 14 ++++++++++++-- fs/vfs/vfs_mount.cc | 7 ++++++- fs/vfs/vfs_syscalls.cc | 2 +- include/osv/dentry.h | 1 + 5 files changed, 21 insertions(+), 5 deletions(-) diff --git a/fs/vfs/vfs.h b/fs/vfs/vfs.h index 7eac21b96..1f76343ab 100644 --- a/fs/vfs/vfs.h +++ b/fs/vfs/vfs.h @@ -137,7 +137,7 @@ int vfs_findroot(char *path, struct mount **mp, char **root); int fs_noop(void); -struct dentry *dentry_alloc(struct vnode *vp, const char *path); +struct dentry *dentry_alloc(struct dentry *parent_dp, struct vnode *vp, const char *path); void dref(struct dentry *dp); void drele(struct dentry *dp); diff --git a/fs/vfs/vfs_lookup.c b/fs/vfs/vfs_lookup.c index 1709c728f..1fbc170f8 100644 --- a/fs/vfs/vfs_lookup.c +++ b/fs/vfs/vfs_lookup.c @@ -59,7 +59,7 @@ dentry_hash(struct mount *mp, const char *path) struct dentry * -dentry_alloc(struct vnode *vp, const char *path) +dentry_alloc(struct dentry *parent_dp, struct vnode *vp, const char *path) { struct mount *mp = vp->v_mount; struct dentry *dp = calloc(sizeof(*dp), 1); @@ -73,6 +73,12 @@ dentry_alloc(struct vnode *vp, const char *path) dp->d_vnode = vp; dp->d_mount = mp; dp->d_path = strdup(path); + + if (parent_dp) { + dref(parent_dp); + } + dp->d_parent = parent_dp; + vn_add_name(vp, dp); mutex_lock(&dentry_hash_lock); @@ -126,6 +132,10 @@ drele(struct dentry *dp) mutex_unlock(&dentry_hash_lock); + if (dp->d_parent) { + drele(dp->d_parent); + } + vrele(dp->d_vnode); free(dp->d_path); @@ -211,7 +221,7 @@ namei(char *path, struct dentry **dpp) return error; } - dp = dentry_alloc(vp, node); + dp = dentry_alloc(ddp, vp, node); vput(vp); if (!dp) { diff --git a/fs/vfs/vfs_mount.cc b/fs/vfs/vfs_mount.cc index 6634fb167..92ba92185 100644 --- a/fs/vfs/vfs_mount.cc +++ b/fs/vfs/vfs_mount.cc @@ -173,7 +173,7 @@ sys_mount(char *dev, char *dir, char *fsname, int flags, void *data) vp->v_flags = VROOT; vp->v_mode = S_IFDIR | S_IRUSR | S_IWUSR | S_IXUSR; - mp->m_root = dentry_alloc(vp, "/"); + mp->m_root = dentry_alloc(NULL, vp, "/"); if (!mp->m_root) { vput(vp); goto err3; @@ -318,6 +318,11 @@ sys_pivot_root(const char *new_root, const char *put_old) } newmp->m_covered = NULL; + if (newmp->m_root->d_parent) { + drele(newmp->m_root->d_parent); + } + newmp->m_root->d_parent = NULL; + free(oldmp); strlcpy(newmp->m_path, "/", sizeof(newmp->m_path)); diff --git a/fs/vfs/vfs_syscalls.cc b/fs/vfs/vfs_syscalls.cc index 0ee11d6db..c13148c81 100644 --- a/fs/vfs/vfs_syscalls.cc +++ b/fs/vfs/vfs_syscalls.cc @@ -777,7 +777,7 @@ sys_link(char *oldpath, char *newpath) goto out1; /* Map newpath into dentry hash with the same vnode as oldpath */ - if (!(newdp = dentry_alloc(vp, newpath))) { + if (!(newdp = dentry_alloc(newdirdp, vp, newpath))) { error = ENOMEM; goto out1; } diff --git a/include/osv/dentry.h b/include/osv/dentry.h index 291740671..ac1ade15f 100644 --- a/include/osv/dentry.h +++ b/include/osv/dentry.h @@ -19,6 +19,7 @@ struct dentry { char *d_path; /* pointer to path in fs */ struct vnode *d_vnode; struct mount *d_mount; + struct dentry *d_parent; /* pointer to parent */ LIST_ENTRY(dentry) d_names_link; /* link fo vnode::d_names */ }; -- GitLab