|
@@ -1937,6 +1937,21 @@ dput_out:
|
|
|
return retval;
|
|
|
}
|
|
|
|
|
|
+static struct mnt_namespace *alloc_mnt_ns(void)
|
|
|
+{
|
|
|
+ struct mnt_namespace *new_ns;
|
|
|
+
|
|
|
+ new_ns = kmalloc(sizeof(struct mnt_namespace), GFP_KERNEL);
|
|
|
+ if (!new_ns)
|
|
|
+ return ERR_PTR(-ENOMEM);
|
|
|
+ atomic_set(&new_ns->count, 1);
|
|
|
+ new_ns->root = NULL;
|
|
|
+ INIT_LIST_HEAD(&new_ns->list);
|
|
|
+ init_waitqueue_head(&new_ns->poll);
|
|
|
+ new_ns->event = 0;
|
|
|
+ return new_ns;
|
|
|
+}
|
|
|
+
|
|
|
/*
|
|
|
* Allocate a new namespace structure and populate it with contents
|
|
|
* 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,
|
|
|
struct vfsmount *rootmnt = NULL, *pwdmnt = NULL;
|
|
|
struct vfsmount *p, *q;
|
|
|
|
|
|
- new_ns = kmalloc(sizeof(struct mnt_namespace), GFP_KERNEL);
|
|
|
- if (!new_ns)
|
|
|
- return ERR_PTR(-ENOMEM);
|
|
|
-
|
|
|
- atomic_set(&new_ns->count, 1);
|
|
|
- INIT_LIST_HEAD(&new_ns->list);
|
|
|
- init_waitqueue_head(&new_ns->poll);
|
|
|
- new_ns->event = 0;
|
|
|
+ new_ns = alloc_mnt_ns();
|
|
|
+ if (IS_ERR(new_ns))
|
|
|
+ return new_ns;
|
|
|
|
|
|
down_write(&namespace_sem);
|
|
|
/* First pass: copy the tree topology */
|
|
@@ -2019,6 +2029,24 @@ struct mnt_namespace *copy_mnt_ns(unsigned long flags, struct mnt_namespace *ns,
|
|
|
return new_ns;
|
|
|
}
|
|
|
|
|
|
+/**
|
|
|
+ * create_mnt_ns - creates a private namespace and adds a root filesystem
|
|
|
+ * @mnt: pointer to the new root filesystem mountpoint
|
|
|
+ */
|
|
|
+struct mnt_namespace *create_mnt_ns(struct vfsmount *mnt)
|
|
|
+{
|
|
|
+ struct mnt_namespace *new_ns;
|
|
|
+
|
|
|
+ new_ns = alloc_mnt_ns();
|
|
|
+ if (!IS_ERR(new_ns)) {
|
|
|
+ mnt->mnt_ns = new_ns;
|
|
|
+ new_ns->root = mnt;
|
|
|
+ list_add(&new_ns->list, &new_ns->root->mnt_list);
|
|
|
+ }
|
|
|
+ return new_ns;
|
|
|
+}
|
|
|
+EXPORT_SYMBOL(create_mnt_ns);
|
|
|
+
|
|
|
SYSCALL_DEFINE5(mount, char __user *, dev_name, char __user *, dir_name,
|
|
|
char __user *, type, unsigned long, flags, void __user *, data)
|
|
|
{
|
|
@@ -2264,3 +2292,4 @@ void put_mnt_ns(struct mnt_namespace *ns)
|
|
|
release_mounts(&umount_list);
|
|
|
kfree(ns);
|
|
|
}
|
|
|
+EXPORT_SYMBOL(put_mnt_ns);
|