vfs: spread struct mount - clone_mnt/copy_tree result

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
diff --git a/fs/namespace.c b/fs/namespace.c
index c7fa75f..6051a03 100644
--- a/fs/namespace.c
+++ b/fs/namespace.c
@@ -687,7 +687,7 @@
 }
 EXPORT_SYMBOL_GPL(vfs_kern_mount);
 
-static struct vfsmount *clone_mnt(struct vfsmount *old, struct dentry *root,
+static struct mount *clone_mnt(struct vfsmount *old, struct dentry *root,
 					int flag)
 {
 	struct super_block *sb = old->mnt_sb;
@@ -733,7 +733,7 @@
 				list_add(&mnt->mnt.mnt_expire, &old->mnt_expire);
 		}
 	}
-	return &mnt->mnt;
+	return mnt;
 
  out_free:
 	free_vfsmnt(mnt);
@@ -1408,10 +1408,11 @@
 #endif
 }
 
-struct vfsmount *copy_tree(struct vfsmount *mnt, struct dentry *dentry,
+struct mount *copy_tree(struct vfsmount *mnt, struct dentry *dentry,
 					int flag)
 {
-	struct vfsmount *res, *p, *q, *r;
+	struct mount *res, *q;
+	struct vfsmount *p, *r;
 	struct path path;
 
 	if (!(flag & CL_COPY_ALL) && IS_MNT_UNBINDABLE(mnt))
@@ -1420,7 +1421,7 @@
 	res = q = clone_mnt(mnt, dentry, flag);
 	if (!q)
 		goto Enomem;
-	q->mnt_mountpoint = mnt->mnt_mountpoint;
+	q->mnt.mnt_mountpoint = mnt->mnt_mountpoint;
 
 	p = mnt;
 	list_for_each_entry(r, &mnt->mnt_mounts, mnt_child) {
@@ -1435,17 +1436,17 @@
 			}
 			while (p != s->mnt.mnt_parent) {
 				p = p->mnt_parent;
-				q = q->mnt_parent;
+				q = real_mount(q->mnt.mnt_parent);
 			}
 			p = &s->mnt;
-			path.mnt = q;
+			path.mnt = &q->mnt;
 			path.dentry = p->mnt_mountpoint;
 			q = clone_mnt(p, p->mnt_root, flag);
 			if (!q)
 				goto Enomem;
 			br_write_lock(vfsmount_lock);
-			list_add_tail(&q->mnt_list, &res->mnt_list);
-			attach_mnt(real_mount(q), &path);
+			list_add_tail(&q->mnt.mnt_list, &res->mnt.mnt_list);
+			attach_mnt(q, &path);
 			br_write_unlock(vfsmount_lock);
 		}
 	}
@@ -1454,7 +1455,7 @@
 	if (res) {
 		LIST_HEAD(umount_list);
 		br_write_lock(vfsmount_lock);
-		umount_tree(res, 0, &umount_list);
+		umount_tree(&res->mnt, 0, &umount_list);
 		br_write_unlock(vfsmount_lock);
 		release_mounts(&umount_list);
 	}
@@ -1463,11 +1464,11 @@
 
 struct vfsmount *collect_mounts(struct path *path)
 {
-	struct vfsmount *tree;
+	struct mount *tree;
 	down_write(&namespace_sem);
 	tree = copy_tree(path->mnt, path->dentry, CL_COPY_ALL | CL_PRIVATE);
 	up_write(&namespace_sem);
-	return tree;
+	return tree ? &tree->mnt : NULL;
 }
 
 void drop_collected_mounts(struct vfsmount *mnt)
@@ -1739,7 +1740,7 @@
 {
 	LIST_HEAD(umount_list);
 	struct path old_path;
-	struct vfsmount *mnt = NULL;
+	struct mount *mnt = NULL;
 	int err = mount_is_safe(path);
 	if (err)
 		return err;
@@ -1769,10 +1770,10 @@
 	if (!mnt)
 		goto out2;
 
-	err = graft_tree(mnt, path);
+	err = graft_tree(&mnt->mnt, path);
 	if (err) {
 		br_write_lock(vfsmount_lock);
-		umount_tree(mnt, 0, &umount_list);
+		umount_tree(&mnt->mnt, 0, &umount_list);
 		br_write_unlock(vfsmount_lock);
 	}
 out2:
@@ -2385,6 +2386,7 @@
 	struct mnt_namespace *new_ns;
 	struct vfsmount *rootmnt = NULL, *pwdmnt = NULL;
 	struct mount *p, *q;
+	struct mount *new;
 
 	new_ns = alloc_mnt_ns();
 	if (IS_ERR(new_ns))
@@ -2392,13 +2394,14 @@
 
 	down_write(&namespace_sem);
 	/* First pass: copy the tree topology */
-	new_ns->root = copy_tree(mnt_ns->root, mnt_ns->root->mnt_root,
+	new = copy_tree(mnt_ns->root, mnt_ns->root->mnt_root,
 					CL_COPY_ALL | CL_EXPIRE);
-	if (!new_ns->root) {
+	if (!new) {
 		up_write(&namespace_sem);
 		kfree(new_ns);
 		return ERR_PTR(-ENOMEM);
 	}
+	new_ns->root = &new->mnt;
 	br_write_lock(vfsmount_lock);
 	list_add_tail(&new_ns->list, &new_ns->root->mnt_list);
 	br_write_unlock(vfsmount_lock);
@@ -2409,7 +2412,7 @@
 	 * fs_struct, so tsk->fs->lock is not needed.
 	 */
 	p = real_mount(mnt_ns->root);
-	q = real_mount(new_ns->root);
+	q = new;
 	while (p) {
 		q->mnt.mnt_ns = new_ns;
 		__mnt_make_longterm(&q->mnt);
diff --git a/fs/pnode.c b/fs/pnode.c
index 4bd3721..916c8e8 100644
--- a/fs/pnode.c
+++ b/fs/pnode.c
@@ -221,7 +221,8 @@
 int propagate_mnt(struct vfsmount *dest_mnt, struct dentry *dest_dentry,
 		    struct vfsmount *source_mnt, struct list_head *tree_list)
 {
-	struct vfsmount *m, *child;
+	struct vfsmount *m;
+	struct mount *child;
 	int ret = 0;
 	struct vfsmount *prev_dest_mnt = dest_mnt;
 	struct vfsmount *prev_src_mnt  = source_mnt;
@@ -245,23 +246,23 @@
 		}
 
 		if (is_subdir(dest_dentry, m->mnt_root)) {
-			mnt_set_mountpoint(m, dest_dentry, child);
-			list_add_tail(&child->mnt_hash, tree_list);
+			mnt_set_mountpoint(m, dest_dentry, &child->mnt);
+			list_add_tail(&child->mnt.mnt_hash, tree_list);
 		} else {
 			/*
 			 * This can happen if the parent mount was bind mounted
 			 * on some subdirectory of a shared/slave mount.
 			 */
-			list_add_tail(&child->mnt_hash, &tmp_list);
+			list_add_tail(&child->mnt.mnt_hash, &tmp_list);
 		}
 		prev_dest_mnt = m;
-		prev_src_mnt  = child;
+		prev_src_mnt  = &child->mnt;
 	}
 out:
 	br_write_lock(vfsmount_lock);
 	while (!list_empty(&tmp_list)) {
-		child = list_first_entry(&tmp_list, struct vfsmount, mnt_hash);
-		umount_tree(child, 0, &umount_list);
+		child = list_first_entry(&tmp_list, struct mount, mnt.mnt_hash);
+		umount_tree(&child->mnt, 0, &umount_list);
 	}
 	br_write_unlock(vfsmount_lock);
 	release_mounts(&umount_list);
diff --git a/fs/pnode.h b/fs/pnode.h
index a2ad954..ed8a84d 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 vfsmount *, int, struct list_head *);
-struct vfsmount *copy_tree(struct vfsmount *, struct dentry *, int);
+struct mount *copy_tree(struct vfsmount *, struct dentry *, int);
 bool is_path_reachable(struct vfsmount *, struct dentry *,
 			 const struct path *root);
 #endif /* _LINUX_PNODE_H */