vfs: spread struct mount - clone_mnt/copy_tree argument

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
diff --git a/fs/namespace.c b/fs/namespace.c
index fa0f30d..211455e 100644
--- a/fs/namespace.c
+++ b/fs/namespace.c
@@ -687,17 +687,17 @@
 }
 EXPORT_SYMBOL_GPL(vfs_kern_mount);
 
-static struct mount *clone_mnt(struct vfsmount *old, struct dentry *root,
+static struct mount *clone_mnt(struct mount *old, struct dentry *root,
 					int flag)
 {
-	struct super_block *sb = old->mnt_sb;
-	struct mount *mnt = alloc_vfsmnt(old->mnt_devname);
+	struct super_block *sb = old->mnt.mnt_sb;
+	struct mount *mnt = alloc_vfsmnt(old->mnt.mnt_devname);
 
 	if (mnt) {
 		if (flag & (CL_SLAVE | CL_PRIVATE))
 			mnt->mnt.mnt_group_id = 0; /* not a peer of original */
 		else
-			mnt->mnt.mnt_group_id = old->mnt_group_id;
+			mnt->mnt.mnt_group_id = old->mnt.mnt_group_id;
 
 		if ((flag & CL_MAKE_SHARED) && !mnt->mnt.mnt_group_id) {
 			int err = mnt_alloc_group_id(mnt);
@@ -705,7 +705,7 @@
 				goto out_free;
 		}
 
-		mnt->mnt.mnt_flags = old->mnt_flags & ~MNT_WRITE_HOLD;
+		mnt->mnt.mnt_flags = old->mnt.mnt_flags & ~MNT_WRITE_HOLD;
 		atomic_inc(&sb->s_active);
 		mnt->mnt.mnt_sb = sb;
 		mnt->mnt.mnt_root = dget(root);
@@ -713,15 +713,15 @@
 		mnt->mnt.mnt_parent = &mnt->mnt;
 
 		if (flag & CL_SLAVE) {
-			list_add(&mnt->mnt.mnt_slave, &old->mnt_slave_list);
-			mnt->mnt.mnt_master = old;
+			list_add(&mnt->mnt.mnt_slave, &old->mnt.mnt_slave_list);
+			mnt->mnt.mnt_master = &old->mnt;
 			CLEAR_MNT_SHARED(&mnt->mnt);
 		} else if (!(flag & CL_PRIVATE)) {
-			if ((flag & CL_MAKE_SHARED) || IS_MNT_SHARED(old))
-				list_add(&mnt->mnt.mnt_share, &old->mnt_share);
-			if (IS_MNT_SLAVE(old))
-				list_add(&mnt->mnt.mnt_slave, &old->mnt_slave);
-			mnt->mnt.mnt_master = old->mnt_master;
+			if ((flag & CL_MAKE_SHARED) || IS_MNT_SHARED(&old->mnt))
+				list_add(&mnt->mnt.mnt_share, &old->mnt.mnt_share);
+			if (IS_MNT_SLAVE(&old->mnt))
+				list_add(&mnt->mnt.mnt_slave, &old->mnt.mnt_slave);
+			mnt->mnt.mnt_master = old->mnt.mnt_master;
 		}
 		if (flag & CL_MAKE_SHARED)
 			set_mnt_shared(mnt);
@@ -729,8 +729,8 @@
 		/* stick the duplicate mount on the same expiry list
 		 * as the original if that was on one */
 		if (flag & CL_EXPIRE) {
-			if (!list_empty(&old->mnt_expire))
-				list_add(&mnt->mnt.mnt_expire, &old->mnt_expire);
+			if (!list_empty(&old->mnt.mnt_expire))
+				list_add(&mnt->mnt.mnt_expire, &old->mnt.mnt_expire);
 		}
 	}
 	return mnt;
@@ -1408,23 +1408,23 @@
 #endif
 }
 
-struct mount *copy_tree(struct vfsmount *mnt, struct dentry *dentry,
+struct mount *copy_tree(struct mount *mnt, struct dentry *dentry,
 					int flag)
 {
-	struct mount *res, *q;
-	struct vfsmount *p, *r;
+	struct mount *res, *p, *q;
+	struct vfsmount *r;
 	struct path path;
 
-	if (!(flag & CL_COPY_ALL) && IS_MNT_UNBINDABLE(mnt))
+	if (!(flag & CL_COPY_ALL) && IS_MNT_UNBINDABLE(&mnt->mnt))
 		return NULL;
 
 	res = q = clone_mnt(mnt, dentry, flag);
 	if (!q)
 		goto Enomem;
-	q->mnt.mnt_mountpoint = mnt->mnt_mountpoint;
+	q->mnt.mnt_mountpoint = mnt->mnt.mnt_mountpoint;
 
 	p = mnt;
-	list_for_each_entry(r, &mnt->mnt_mounts, mnt_child) {
+	list_for_each_entry(r, &mnt->mnt.mnt_mounts, mnt_child) {
 		struct mount *s;
 		if (!is_subdir(r->mnt_mountpoint, dentry))
 			continue;
@@ -1434,14 +1434,14 @@
 				s = skip_mnt_tree(s);
 				continue;
 			}
-			while (p != s->mnt.mnt_parent) {
-				p = p->mnt_parent;
+			while (p != real_mount(s->mnt.mnt_parent)) {
+				p = real_mount(p->mnt.mnt_parent);
 				q = real_mount(q->mnt.mnt_parent);
 			}
-			p = &s->mnt;
+			p = s;
 			path.mnt = &q->mnt;
-			path.dentry = p->mnt_mountpoint;
-			q = clone_mnt(p, p->mnt_root, flag);
+			path.dentry = p->mnt.mnt_mountpoint;
+			q = clone_mnt(p, p->mnt.mnt_root, flag);
 			if (!q)
 				goto Enomem;
 			br_write_lock(vfsmount_lock);
@@ -1466,7 +1466,8 @@
 {
 	struct mount *tree;
 	down_write(&namespace_sem);
-	tree = copy_tree(path->mnt, path->dentry, CL_COPY_ALL | CL_PRIVATE);
+	tree = copy_tree(real_mount(path->mnt), path->dentry,
+			 CL_COPY_ALL | CL_PRIVATE);
 	up_write(&namespace_sem);
 	return tree ? &tree->mnt : NULL;
 }
@@ -1740,7 +1741,7 @@
 {
 	LIST_HEAD(umount_list);
 	struct path old_path;
-	struct mount *mnt = NULL;
+	struct mount *mnt = NULL, *old;
 	int err = mount_is_safe(path);
 	if (err)
 		return err;
@@ -1754,6 +1755,8 @@
 	if (err)
 		goto out;
 
+	old = real_mount(old_path.mnt);
+
 	err = -EINVAL;
 	if (IS_MNT_UNBINDABLE(old_path.mnt))
 		goto out2;
@@ -1763,9 +1766,9 @@
 
 	err = -ENOMEM;
 	if (recurse)
-		mnt = copy_tree(old_path.mnt, old_path.dentry, 0);
+		mnt = copy_tree(old, old_path.dentry, 0);
 	else
-		mnt = clone_mnt(old_path.mnt, old_path.dentry, 0);
+		mnt = clone_mnt(old, old_path.dentry, 0);
 
 	if (!mnt)
 		goto out2;
@@ -2394,7 +2397,7 @@
 
 	down_write(&namespace_sem);
 	/* First pass: copy the tree topology */
-	new = copy_tree(mnt_ns->root, mnt_ns->root->mnt_root,
+	new = copy_tree(real_mount(mnt_ns->root), mnt_ns->root->mnt_root,
 					CL_COPY_ALL | CL_EXPIRE);
 	if (!new) {
 		up_write(&namespace_sem);
diff --git a/fs/pnode.c b/fs/pnode.c
index efbe0c0..5d79f38 100644
--- a/fs/pnode.c
+++ b/fs/pnode.c
@@ -239,7 +239,7 @@
 
 		source =  get_source(m, prev_dest_mnt, prev_src_mnt, &type);
 
-		if (!(child = copy_tree(source, source->mnt_root, type))) {
+		if (!(child = copy_tree(real_mount(source), source->mnt_root, type))) {
 			ret = -ENOMEM;
 			list_splice(tree_list, tmp_list.prev);
 			goto out;
diff --git a/fs/pnode.h b/fs/pnode.h
index 3f9ab4f..609ec00 100644
--- a/fs/pnode.h
+++ b/fs/pnode.h
@@ -41,7 +41,7 @@
 			struct vfsmount *);
 void release_mounts(struct list_head *);
 void umount_tree(struct mount *, int, struct list_head *);
-struct mount *copy_tree(struct vfsmount *, struct dentry *, int);
+struct mount *copy_tree(struct mount *, struct dentry *, int);
 bool is_path_reachable(struct vfsmount *, struct dentry *,
 			 const struct path *root);
 #endif /* _LINUX_PNODE_H */