From: Andreas Gruenbacher Subject: Add d_namespace_path() to compute namespace relative pathnames In AppArmor, we are interested in pathnames relative to the namespace root. This is the same as d_path() except for the root where the search ends. Add a function for computing the namespace-relative path. Signed-off-by: Andreas Gruenbacher Signed-off-by: John Johansen --- fs/namespace.c | 29 +++++++++++++++++++++++++++++ include/linux/mount.h | 2 ++ 2 files changed, 31 insertions(+) --- a/fs/namespace.c +++ b/fs/namespace.c @@ -2351,3 +2351,32 @@ void __put_mnt_ns(struct mnt_namespace * release_mounts(&umount_list); kfree(ns); } + +char *d_namespace_path(struct dentry *dentry, struct vfsmount *vfsmnt, + char *buf, int buflen) +{ + struct path root, ns_root = { }; + struct path path = { .mnt = vfsmnt, .dentry = dentry }; + char *res; + + read_lock(¤t->fs->lock); + root = current->fs->root; + path_get(¤t->fs->root); + read_unlock(¤t->fs->lock); + spin_lock(&vfsmount_lock); + if (root.mnt) + ns_root.mnt = mntget(root.mnt->mnt_ns->root); + if (ns_root.mnt) + ns_root.dentry = dget(ns_root.mnt->mnt_root); + spin_unlock(&vfsmount_lock); + res = __d_path(&path, &ns_root, buf, buflen, + D_PATH_FAIL_DELETED | D_PATH_DISCONNECT); + path_put(&root); + path_put(&ns_root); + + /* Prevent empty path for lazily unmounted filesystems. */ + if (!IS_ERR(res) && *res == '\0') + *--res = '.'; + return res; +} +EXPORT_SYMBOL(d_namespace_path); --- a/include/linux/mount.h +++ b/include/linux/mount.h @@ -113,4 +113,6 @@ extern void mark_mounts_for_expiry(struc extern spinlock_t vfsmount_lock; extern dev_t name_to_dev_t(char *name); +extern char *d_namespace_path(struct dentry *, struct vfsmount *, char *, int); + #endif /* _LINUX_MOUNT_H */