|
@@ -2397,20 +2397,25 @@ static struct mnt_namespace *alloc_mnt_ns(struct user_namespace *user_ns)
|
|
|
return new_ns;
|
|
|
}
|
|
|
|
|
|
-/*
|
|
|
- * Allocate a new namespace structure and populate it with contents
|
|
|
- * copied from the namespace of the passed in task structure.
|
|
|
- */
|
|
|
-static struct mnt_namespace *dup_mnt_ns(struct mnt_namespace *mnt_ns,
|
|
|
- struct user_namespace *user_ns, struct fs_struct *fs)
|
|
|
+struct mnt_namespace *copy_mnt_ns(unsigned long flags, struct mnt_namespace *ns,
|
|
|
+ struct user_namespace *user_ns, struct fs_struct *new_fs)
|
|
|
{
|
|
|
struct mnt_namespace *new_ns;
|
|
|
struct vfsmount *rootmnt = NULL, *pwdmnt = NULL;
|
|
|
struct mount *p, *q;
|
|
|
- struct mount *old = mnt_ns->root;
|
|
|
+ struct mount *old;
|
|
|
struct mount *new;
|
|
|
int copy_flags;
|
|
|
|
|
|
+ BUG_ON(!ns);
|
|
|
+
|
|
|
+ if (likely(!(flags & CLONE_NEWNS))) {
|
|
|
+ get_mnt_ns(ns);
|
|
|
+ return ns;
|
|
|
+ }
|
|
|
+
|
|
|
+ old = ns->root;
|
|
|
+
|
|
|
new_ns = alloc_mnt_ns(user_ns);
|
|
|
if (IS_ERR(new_ns))
|
|
|
return new_ns;
|
|
@@ -2418,7 +2423,7 @@ static struct mnt_namespace *dup_mnt_ns(struct mnt_namespace *mnt_ns,
|
|
|
namespace_lock();
|
|
|
/* First pass: copy the tree topology */
|
|
|
copy_flags = CL_COPY_UNBINDABLE | CL_EXPIRE;
|
|
|
- if (user_ns != mnt_ns->user_ns)
|
|
|
+ if (user_ns != ns->user_ns)
|
|
|
copy_flags |= CL_SHARED_TO_SLAVE | CL_UNPRIVILEGED;
|
|
|
new = copy_tree(old, old->mnt.mnt_root, copy_flags);
|
|
|
if (IS_ERR(new)) {
|
|
@@ -2438,13 +2443,13 @@ static struct mnt_namespace *dup_mnt_ns(struct mnt_namespace *mnt_ns,
|
|
|
q = new;
|
|
|
while (p) {
|
|
|
q->mnt_ns = new_ns;
|
|
|
- if (fs) {
|
|
|
- if (&p->mnt == fs->root.mnt) {
|
|
|
- fs->root.mnt = mntget(&q->mnt);
|
|
|
+ if (new_fs) {
|
|
|
+ if (&p->mnt == new_fs->root.mnt) {
|
|
|
+ new_fs->root.mnt = mntget(&q->mnt);
|
|
|
rootmnt = &p->mnt;
|
|
|
}
|
|
|
- if (&p->mnt == fs->pwd.mnt) {
|
|
|
- fs->pwd.mnt = mntget(&q->mnt);
|
|
|
+ if (&p->mnt == new_fs->pwd.mnt) {
|
|
|
+ new_fs->pwd.mnt = mntget(&q->mnt);
|
|
|
pwdmnt = &p->mnt;
|
|
|
}
|
|
|
}
|
|
@@ -2465,23 +2470,6 @@ static struct mnt_namespace *dup_mnt_ns(struct mnt_namespace *mnt_ns,
|
|
|
return new_ns;
|
|
|
}
|
|
|
|
|
|
-struct mnt_namespace *copy_mnt_ns(unsigned long flags, struct mnt_namespace *ns,
|
|
|
- struct user_namespace *user_ns, struct fs_struct *new_fs)
|
|
|
-{
|
|
|
- struct mnt_namespace *new_ns;
|
|
|
-
|
|
|
- BUG_ON(!ns);
|
|
|
- get_mnt_ns(ns);
|
|
|
-
|
|
|
- if (!(flags & CLONE_NEWNS))
|
|
|
- return ns;
|
|
|
-
|
|
|
- new_ns = dup_mnt_ns(ns, user_ns, new_fs);
|
|
|
-
|
|
|
- put_mnt_ns(ns);
|
|
|
- return new_ns;
|
|
|
-}
|
|
|
-
|
|
|
/**
|
|
|
* create_mnt_ns - creates a private namespace and adds a root filesystem
|
|
|
* @mnt: pointer to the new root filesystem mountpoint
|