aboutsummaryrefslogtreecommitdiffstats
path: root/fs/namespace.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/namespace.c')
-rw-r--r--fs/namespace.c53
1 files changed, 43 insertions, 10 deletions
diff --git a/fs/namespace.c b/fs/namespace.c
index 2dd333b0fe7f..a7bea8c8bd46 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{
@@ -2246,10 +2274,14 @@ void __init mnt_init(void)
2246 init_mount_tree(); 2274 init_mount_tree();
2247} 2275}
2248 2276
2249void __put_mnt_ns(struct mnt_namespace *ns) 2277void put_mnt_ns(struct mnt_namespace *ns)
2250{ 2278{
2251 struct vfsmount *root = ns->root; 2279 struct vfsmount *root;
2252 LIST_HEAD(umount_list); 2280 LIST_HEAD(umount_list);
2281
2282 if (!atomic_dec_and_lock(&ns->count, &vfsmount_lock))
2283 return;
2284 root = ns->root;
2253 ns->root = NULL; 2285 ns->root = NULL;
2254 spin_unlock(&vfsmount_lock); 2286 spin_unlock(&vfsmount_lock);
2255 down_write(&namespace_sem); 2287 down_write(&namespace_sem);
@@ -2260,3 +2292,4 @@ void __put_mnt_ns(struct mnt_namespace *ns)
2260 release_mounts(&umount_list); 2292 release_mounts(&umount_list);
2261 kfree(ns); 2293 kfree(ns);
2262} 2294}
2295EXPORT_SYMBOL(put_mnt_ns);