aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorTrond Myklebust <Trond.Myklebust@netapp.com>2009-06-22 15:09:13 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2009-06-23 00:28:25 -0400
commitcf8d2c11cb77f129675478792122f50827e5b0ae (patch)
tree85bebdff4cffbca238952e839b0cb801e6a9bfe7 /fs
parent616511d039af402670de8500d0e24495113a9cab (diff)
VFS: Add VFS helper functions for setting up private namespaces
The purpose of this patch is to improve the remote mount path lookup support for distributed filesystems such as the NFSv4 client. When given a mount command of the form "mount server:/foo/bar /mnt", the NFSv4 client is required to look up the filehandle for "server:/", and then look up each component of the remote mount path "foo/bar" in order to find the directory that is actually going to be mounted on /mnt. Following that remote mount path may involve following symlinks, crossing server-side mount points and even following referrals to filesystem volumes on other servers. Since the standard VFS path lookup code already supports walking paths that contain all these features (using in-kernel automounts for following referrals) we would like to be able to reuse that rather than duplicate the full path traversal functionality in the NFSv4 client code. This patch therefore defines a VFS helper function create_mnt_ns(), that sets up a temporary filesystem namespace and attaches a root filesystem to it. It exports the create_mnt_ns() and put_mnt_ns() function for use by filesystem modules. Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'fs')
-rw-r--r--fs/namespace.c45
1 files changed, 37 insertions, 8 deletions
diff --git a/fs/namespace.c b/fs/namespace.c
index 6645846f205..a7bea8c8bd4 100644
--- a/fs/namespace.c
+++ b/fs/namespace.c
@@ -1937,6 +1937,21 @@ dput_out:
1937 return retval; 1937 return retval;
1938} 1938}
1939 1939
1940static struct mnt_namespace *alloc_mnt_ns(void)
1941{
1942 struct mnt_namespace *new_ns;
1943
1944 new_ns = kmalloc(sizeof(struct mnt_namespace), GFP_KERNEL);
1945 if (!new_ns)
1946 return ERR_PTR(-ENOMEM);
1947 atomic_set(&new_ns->count, 1);
1948 new_ns->root = NULL;
1949 INIT_LIST_HEAD(&new_ns->list);
1950 init_waitqueue_head(&new_ns->poll);
1951 new_ns->event = 0;
1952 return new_ns;
1953}
1954
1940/* 1955/*
1941 * Allocate a new namespace structure and populate it with contents 1956 * Allocate a new namespace structure and populate it with contents
1942 * copied from the namespace of the passed in task structure. 1957 * copied from the namespace of the passed in task structure.
@@ -1948,14 +1963,9 @@ static struct mnt_namespace *dup_mnt_ns(struct mnt_namespace *mnt_ns,
1948 struct vfsmount *rootmnt = NULL, *pwdmnt = NULL; 1963 struct vfsmount *rootmnt = NULL, *pwdmnt = NULL;
1949 struct vfsmount *p, *q; 1964 struct vfsmount *p, *q;
1950 1965
1951 new_ns = kmalloc(sizeof(struct mnt_namespace), GFP_KERNEL); 1966 new_ns = alloc_mnt_ns();
1952 if (!new_ns) 1967 if (IS_ERR(new_ns))
1953 return ERR_PTR(-ENOMEM); 1968 return new_ns;
1954
1955 atomic_set(&new_ns->count, 1);
1956 INIT_LIST_HEAD(&new_ns->list);
1957 init_waitqueue_head(&new_ns->poll);
1958 new_ns->event = 0;
1959 1969
1960 down_write(&namespace_sem); 1970 down_write(&namespace_sem);
1961 /* First pass: copy the tree topology */ 1971 /* First pass: copy the tree topology */
@@ -2019,6 +2029,24 @@ struct mnt_namespace *copy_mnt_ns(unsigned long flags, struct mnt_namespace *ns,
2019 return new_ns; 2029 return new_ns;
2020} 2030}
2021 2031
2032/**
2033 * create_mnt_ns - creates a private namespace and adds a root filesystem
2034 * @mnt: pointer to the new root filesystem mountpoint
2035 */
2036struct mnt_namespace *create_mnt_ns(struct vfsmount *mnt)
2037{
2038 struct mnt_namespace *new_ns;
2039
2040 new_ns = alloc_mnt_ns();
2041 if (!IS_ERR(new_ns)) {
2042 mnt->mnt_ns = new_ns;
2043 new_ns->root = mnt;
2044 list_add(&new_ns->list, &new_ns->root->mnt_list);
2045 }
2046 return new_ns;
2047}
2048EXPORT_SYMBOL(create_mnt_ns);
2049
2022SYSCALL_DEFINE5(mount, char __user *, dev_name, char __user *, dir_name, 2050SYSCALL_DEFINE5(mount, char __user *, dev_name, char __user *, dir_name,
2023 char __user *, type, unsigned long, flags, void __user *, data) 2051 char __user *, type, unsigned long, flags, void __user *, data)
2024{ 2052{
@@ -2264,3 +2292,4 @@ void put_mnt_ns(struct mnt_namespace *ns)
2264 release_mounts(&umount_list); 2292 release_mounts(&umount_list);
2265 kfree(ns); 2293 kfree(ns);
2266} 2294}
2295EXPORT_SYMBOL(put_mnt_ns);