aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
Diffstat (limited to 'fs')
-rw-r--r--fs/namespace.c39
-rw-r--r--fs/pnode.c15
-rw-r--r--fs/pnode.h2
3 files changed, 30 insertions, 26 deletions
diff --git a/fs/namespace.c b/fs/namespace.c
index c7fa75f0fd92..6051a034db96 100644
--- a/fs/namespace.c
+++ b/fs/namespace.c
@@ -687,7 +687,7 @@ vfs_kern_mount(struct file_system_type *type, int flags, const char *name, void
687} 687}
688EXPORT_SYMBOL_GPL(vfs_kern_mount); 688EXPORT_SYMBOL_GPL(vfs_kern_mount);
689 689
690static struct vfsmount *clone_mnt(struct vfsmount *old, struct dentry *root, 690static struct mount *clone_mnt(struct vfsmount *old, struct dentry *root,
691 int flag) 691 int flag)
692{ 692{
693 struct super_block *sb = old->mnt_sb; 693 struct super_block *sb = old->mnt_sb;
@@ -733,7 +733,7 @@ static struct vfsmount *clone_mnt(struct vfsmount *old, struct dentry *root,
733 list_add(&mnt->mnt.mnt_expire, &old->mnt_expire); 733 list_add(&mnt->mnt.mnt_expire, &old->mnt_expire);
734 } 734 }
735 } 735 }
736 return &mnt->mnt; 736 return mnt;
737 737
738 out_free: 738 out_free:
739 free_vfsmnt(mnt); 739 free_vfsmnt(mnt);
@@ -1408,10 +1408,11 @@ static int mount_is_safe(struct path *path)
1408#endif 1408#endif
1409} 1409}
1410 1410
1411struct vfsmount *copy_tree(struct vfsmount *mnt, struct dentry *dentry, 1411struct mount *copy_tree(struct vfsmount *mnt, struct dentry *dentry,
1412 int flag) 1412 int flag)
1413{ 1413{
1414 struct vfsmount *res, *p, *q, *r; 1414 struct mount *res, *q;
1415 struct vfsmount *p, *r;
1415 struct path path; 1416 struct path path;
1416 1417
1417 if (!(flag & CL_COPY_ALL) && IS_MNT_UNBINDABLE(mnt)) 1418 if (!(flag & CL_COPY_ALL) && IS_MNT_UNBINDABLE(mnt))
@@ -1420,7 +1421,7 @@ struct vfsmount *copy_tree(struct vfsmount *mnt, struct dentry *dentry,
1420 res = q = clone_mnt(mnt, dentry, flag); 1421 res = q = clone_mnt(mnt, dentry, flag);
1421 if (!q) 1422 if (!q)
1422 goto Enomem; 1423 goto Enomem;
1423 q->mnt_mountpoint = mnt->mnt_mountpoint; 1424 q->mnt.mnt_mountpoint = mnt->mnt_mountpoint;
1424 1425
1425 p = mnt; 1426 p = mnt;
1426 list_for_each_entry(r, &mnt->mnt_mounts, mnt_child) { 1427 list_for_each_entry(r, &mnt->mnt_mounts, mnt_child) {
@@ -1435,17 +1436,17 @@ struct vfsmount *copy_tree(struct vfsmount *mnt, struct dentry *dentry,
1435 } 1436 }
1436 while (p != s->mnt.mnt_parent) { 1437 while (p != s->mnt.mnt_parent) {
1437 p = p->mnt_parent; 1438 p = p->mnt_parent;
1438 q = q->mnt_parent; 1439 q = real_mount(q->mnt.mnt_parent);
1439 } 1440 }
1440 p = &s->mnt; 1441 p = &s->mnt;
1441 path.mnt = q; 1442 path.mnt = &q->mnt;
1442 path.dentry = p->mnt_mountpoint; 1443 path.dentry = p->mnt_mountpoint;
1443 q = clone_mnt(p, p->mnt_root, flag); 1444 q = clone_mnt(p, p->mnt_root, flag);
1444 if (!q) 1445 if (!q)
1445 goto Enomem; 1446 goto Enomem;
1446 br_write_lock(vfsmount_lock); 1447 br_write_lock(vfsmount_lock);
1447 list_add_tail(&q->mnt_list, &res->mnt_list); 1448 list_add_tail(&q->mnt.mnt_list, &res->mnt.mnt_list);
1448 attach_mnt(real_mount(q), &path); 1449 attach_mnt(q, &path);
1449 br_write_unlock(vfsmount_lock); 1450 br_write_unlock(vfsmount_lock);
1450 } 1451 }
1451 } 1452 }
@@ -1454,7 +1455,7 @@ Enomem:
1454 if (res) { 1455 if (res) {
1455 LIST_HEAD(umount_list); 1456 LIST_HEAD(umount_list);
1456 br_write_lock(vfsmount_lock); 1457 br_write_lock(vfsmount_lock);
1457 umount_tree(res, 0, &umount_list); 1458 umount_tree(&res->mnt, 0, &umount_list);
1458 br_write_unlock(vfsmount_lock); 1459 br_write_unlock(vfsmount_lock);
1459 release_mounts(&umount_list); 1460 release_mounts(&umount_list);
1460 } 1461 }
@@ -1463,11 +1464,11 @@ Enomem:
1463 1464
1464struct vfsmount *collect_mounts(struct path *path) 1465struct vfsmount *collect_mounts(struct path *path)
1465{ 1466{
1466 struct vfsmount *tree; 1467 struct mount *tree;
1467 down_write(&namespace_sem); 1468 down_write(&namespace_sem);
1468 tree = copy_tree(path->mnt, path->dentry, CL_COPY_ALL | CL_PRIVATE); 1469 tree = copy_tree(path->mnt, path->dentry, CL_COPY_ALL | CL_PRIVATE);
1469 up_write(&namespace_sem); 1470 up_write(&namespace_sem);
1470 return tree; 1471 return tree ? &tree->mnt : NULL;
1471} 1472}
1472 1473
1473void drop_collected_mounts(struct vfsmount *mnt) 1474void drop_collected_mounts(struct vfsmount *mnt)
@@ -1739,7 +1740,7 @@ static int do_loopback(struct path *path, char *old_name,
1739{ 1740{
1740 LIST_HEAD(umount_list); 1741 LIST_HEAD(umount_list);
1741 struct path old_path; 1742 struct path old_path;
1742 struct vfsmount *mnt = NULL; 1743 struct mount *mnt = NULL;
1743 int err = mount_is_safe(path); 1744 int err = mount_is_safe(path);
1744 if (err) 1745 if (err)
1745 return err; 1746 return err;
@@ -1769,10 +1770,10 @@ static int do_loopback(struct path *path, char *old_name,
1769 if (!mnt) 1770 if (!mnt)
1770 goto out2; 1771 goto out2;
1771 1772
1772 err = graft_tree(mnt, path); 1773 err = graft_tree(&mnt->mnt, path);
1773 if (err) { 1774 if (err) {
1774 br_write_lock(vfsmount_lock); 1775 br_write_lock(vfsmount_lock);
1775 umount_tree(mnt, 0, &umount_list); 1776 umount_tree(&mnt->mnt, 0, &umount_list);
1776 br_write_unlock(vfsmount_lock); 1777 br_write_unlock(vfsmount_lock);
1777 } 1778 }
1778out2: 1779out2:
@@ -2385,6 +2386,7 @@ static struct mnt_namespace *dup_mnt_ns(struct mnt_namespace *mnt_ns,
2385 struct mnt_namespace *new_ns; 2386 struct mnt_namespace *new_ns;
2386 struct vfsmount *rootmnt = NULL, *pwdmnt = NULL; 2387 struct vfsmount *rootmnt = NULL, *pwdmnt = NULL;
2387 struct mount *p, *q; 2388 struct mount *p, *q;
2389 struct mount *new;
2388 2390
2389 new_ns = alloc_mnt_ns(); 2391 new_ns = alloc_mnt_ns();
2390 if (IS_ERR(new_ns)) 2392 if (IS_ERR(new_ns))
@@ -2392,13 +2394,14 @@ static struct mnt_namespace *dup_mnt_ns(struct mnt_namespace *mnt_ns,
2392 2394
2393 down_write(&namespace_sem); 2395 down_write(&namespace_sem);
2394 /* First pass: copy the tree topology */ 2396 /* First pass: copy the tree topology */
2395 new_ns->root = copy_tree(mnt_ns->root, mnt_ns->root->mnt_root, 2397 new = copy_tree(mnt_ns->root, mnt_ns->root->mnt_root,
2396 CL_COPY_ALL | CL_EXPIRE); 2398 CL_COPY_ALL | CL_EXPIRE);
2397 if (!new_ns->root) { 2399 if (!new) {
2398 up_write(&namespace_sem); 2400 up_write(&namespace_sem);
2399 kfree(new_ns); 2401 kfree(new_ns);
2400 return ERR_PTR(-ENOMEM); 2402 return ERR_PTR(-ENOMEM);
2401 } 2403 }
2404 new_ns->root = &new->mnt;
2402 br_write_lock(vfsmount_lock); 2405 br_write_lock(vfsmount_lock);
2403 list_add_tail(&new_ns->list, &new_ns->root->mnt_list); 2406 list_add_tail(&new_ns->list, &new_ns->root->mnt_list);
2404 br_write_unlock(vfsmount_lock); 2407 br_write_unlock(vfsmount_lock);
@@ -2409,7 +2412,7 @@ static struct mnt_namespace *dup_mnt_ns(struct mnt_namespace *mnt_ns,
2409 * fs_struct, so tsk->fs->lock is not needed. 2412 * fs_struct, so tsk->fs->lock is not needed.
2410 */ 2413 */
2411 p = real_mount(mnt_ns->root); 2414 p = real_mount(mnt_ns->root);
2412 q = real_mount(new_ns->root); 2415 q = new;
2413 while (p) { 2416 while (p) {
2414 q->mnt.mnt_ns = new_ns; 2417 q->mnt.mnt_ns = new_ns;
2415 __mnt_make_longterm(&q->mnt); 2418 __mnt_make_longterm(&q->mnt);
diff --git a/fs/pnode.c b/fs/pnode.c
index 4bd3721867a7..916c8e87cf4e 100644
--- a/fs/pnode.c
+++ b/fs/pnode.c
@@ -221,7 +221,8 @@ static struct vfsmount *get_source(struct vfsmount *dest,
221int propagate_mnt(struct vfsmount *dest_mnt, struct dentry *dest_dentry, 221int propagate_mnt(struct vfsmount *dest_mnt, struct dentry *dest_dentry,
222 struct vfsmount *source_mnt, struct list_head *tree_list) 222 struct vfsmount *source_mnt, struct list_head *tree_list)
223{ 223{
224 struct vfsmount *m, *child; 224 struct vfsmount *m;
225 struct mount *child;
225 int ret = 0; 226 int ret = 0;
226 struct vfsmount *prev_dest_mnt = dest_mnt; 227 struct vfsmount *prev_dest_mnt = dest_mnt;
227 struct vfsmount *prev_src_mnt = source_mnt; 228 struct vfsmount *prev_src_mnt = source_mnt;
@@ -245,23 +246,23 @@ int propagate_mnt(struct vfsmount *dest_mnt, struct dentry *dest_dentry,
245 } 246 }
246 247
247 if (is_subdir(dest_dentry, m->mnt_root)) { 248 if (is_subdir(dest_dentry, m->mnt_root)) {
248 mnt_set_mountpoint(m, dest_dentry, child); 249 mnt_set_mountpoint(m, dest_dentry, &child->mnt);
249 list_add_tail(&child->mnt_hash, tree_list); 250 list_add_tail(&child->mnt.mnt_hash, tree_list);
250 } else { 251 } else {
251 /* 252 /*
252 * This can happen if the parent mount was bind mounted 253 * This can happen if the parent mount was bind mounted
253 * on some subdirectory of a shared/slave mount. 254 * on some subdirectory of a shared/slave mount.
254 */ 255 */
255 list_add_tail(&child->mnt_hash, &tmp_list); 256 list_add_tail(&child->mnt.mnt_hash, &tmp_list);
256 } 257 }
257 prev_dest_mnt = m; 258 prev_dest_mnt = m;
258 prev_src_mnt = child; 259 prev_src_mnt = &child->mnt;
259 } 260 }
260out: 261out:
261 br_write_lock(vfsmount_lock); 262 br_write_lock(vfsmount_lock);
262 while (!list_empty(&tmp_list)) { 263 while (!list_empty(&tmp_list)) {
263 child = list_first_entry(&tmp_list, struct vfsmount, mnt_hash); 264 child = list_first_entry(&tmp_list, struct mount, mnt.mnt_hash);
264 umount_tree(child, 0, &umount_list); 265 umount_tree(&child->mnt, 0, &umount_list);
265 } 266 }
266 br_write_unlock(vfsmount_lock); 267 br_write_unlock(vfsmount_lock);
267 release_mounts(&umount_list); 268 release_mounts(&umount_list);
diff --git a/fs/pnode.h b/fs/pnode.h
index a2ad95435c48..ed8a84d6d78f 100644
--- a/fs/pnode.h
+++ b/fs/pnode.h
@@ -41,7 +41,7 @@ void mnt_set_mountpoint(struct vfsmount *, struct dentry *,
41 struct vfsmount *); 41 struct vfsmount *);
42void release_mounts(struct list_head *); 42void release_mounts(struct list_head *);
43void umount_tree(struct vfsmount *, int, struct list_head *); 43void umount_tree(struct vfsmount *, int, struct list_head *);
44struct vfsmount *copy_tree(struct vfsmount *, struct dentry *, int); 44struct mount *copy_tree(struct vfsmount *, struct dentry *, int);
45bool is_path_reachable(struct vfsmount *, struct dentry *, 45bool is_path_reachable(struct vfsmount *, struct dentry *,
46 const struct path *root); 46 const struct path *root);
47#endif /* _LINUX_PNODE_H */ 47#endif /* _LINUX_PNODE_H */