aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAl Viro <viro@zeniv.linux.org.uk>2011-11-24 22:19:58 -0500
committerAl Viro <viro@zeniv.linux.org.uk>2012-01-03 22:57:05 -0500
commit0714a533805a0f8ebfc6fdb6bda9f129b8c7c6d7 (patch)
tree7f34ceedc12c4a680ca3509562b09ec441a0954f
parent3376f34fff5be9954fd9a9c4fd68f4a0a36d480e (diff)
vfs: now it can be done - make mnt_parent point to struct mount
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
-rw-r--r--fs/dcache.c7
-rw-r--r--fs/mount.h4
-rw-r--r--fs/namei.c24
-rw-r--r--fs/namespace.c52
-rw-r--r--fs/pnode.c16
5 files changed, 53 insertions, 50 deletions
diff --git a/fs/dcache.c b/fs/dcache.c
index eef2d5472f9c..98b48753f77b 100644
--- a/fs/dcache.c
+++ b/fs/dcache.c
@@ -2452,6 +2452,7 @@ static int prepend_path(const struct path *path,
2452{ 2452{
2453 struct dentry *dentry = path->dentry; 2453 struct dentry *dentry = path->dentry;
2454 struct vfsmount *vfsmnt = path->mnt; 2454 struct vfsmount *vfsmnt = path->mnt;
2455 struct mount *mnt = real_mount(vfsmnt);
2455 bool slash = false; 2456 bool slash = false;
2456 int error = 0; 2457 int error = 0;
2457 2458
@@ -2460,12 +2461,12 @@ static int prepend_path(const struct path *path,
2460 struct dentry * parent; 2461 struct dentry * parent;
2461 2462
2462 if (dentry == vfsmnt->mnt_root || IS_ROOT(dentry)) { 2463 if (dentry == vfsmnt->mnt_root || IS_ROOT(dentry)) {
2463 struct mount *mnt = real_mount(vfsmnt);
2464 /* Global root? */ 2464 /* Global root? */
2465 if (!mnt_has_parent(mnt)) 2465 if (!mnt_has_parent(mnt))
2466 goto global_root; 2466 goto global_root;
2467 dentry = vfsmnt->mnt_mountpoint; 2467 dentry = mnt->mnt.mnt_mountpoint;
2468 vfsmnt = mnt->mnt_parent; 2468 mnt = mnt->mnt_parent;
2469 vfsmnt = &mnt->mnt;
2469 continue; 2470 continue;
2470 } 2471 }
2471 parent = dentry->d_parent; 2472 parent = dentry->d_parent;
diff --git a/fs/mount.h b/fs/mount.h
index 5126c0861102..201dd616e6c4 100644
--- a/fs/mount.h
+++ b/fs/mount.h
@@ -2,7 +2,7 @@
2 2
3struct mount { 3struct mount {
4 struct list_head mnt_hash; 4 struct list_head mnt_hash;
5 struct vfsmount *mnt_parent; 5 struct mount *mnt_parent;
6 struct vfsmount mnt; 6 struct vfsmount mnt;
7}; 7};
8 8
@@ -13,7 +13,7 @@ static inline struct mount *real_mount(struct vfsmount *mnt)
13 13
14static inline int mnt_has_parent(struct mount *mnt) 14static inline int mnt_has_parent(struct mount *mnt)
15{ 15{
16 return &mnt->mnt != mnt->mnt_parent; 16 return mnt != mnt->mnt_parent;
17} 17}
18 18
19extern struct mount *__lookup_mnt(struct vfsmount *, struct dentry *, int); 19extern struct mount *__lookup_mnt(struct vfsmount *, struct dentry *, int);
diff --git a/fs/namei.c b/fs/namei.c
index 89248bf1b906..2e9110a37c0e 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -677,36 +677,38 @@ follow_link(struct path *link, struct nameidata *nd, void **p)
677 677
678static int follow_up_rcu(struct path *path) 678static int follow_up_rcu(struct path *path)
679{ 679{
680 struct vfsmount *parent; 680 struct mount *mnt = real_mount(path->mnt);
681 struct mount *parent;
681 struct dentry *mountpoint; 682 struct dentry *mountpoint;
682 683
683 parent = real_mount(path->mnt)->mnt_parent; 684 parent = mnt->mnt_parent;
684 if (parent == path->mnt) 685 if (&parent->mnt == path->mnt)
685 return 0; 686 return 0;
686 mountpoint = path->mnt->mnt_mountpoint; 687 mountpoint = mnt->mnt.mnt_mountpoint;
687 path->dentry = mountpoint; 688 path->dentry = mountpoint;
688 path->mnt = parent; 689 path->mnt = &parent->mnt;
689 return 1; 690 return 1;
690} 691}
691 692
692int follow_up(struct path *path) 693int follow_up(struct path *path)
693{ 694{
694 struct vfsmount *parent; 695 struct mount *mnt = real_mount(path->mnt);
696 struct mount *parent;
695 struct dentry *mountpoint; 697 struct dentry *mountpoint;
696 698
697 br_read_lock(vfsmount_lock); 699 br_read_lock(vfsmount_lock);
698 parent = real_mount(path->mnt)->mnt_parent; 700 parent = mnt->mnt_parent;
699 if (parent == path->mnt) { 701 if (&parent->mnt == path->mnt) {
700 br_read_unlock(vfsmount_lock); 702 br_read_unlock(vfsmount_lock);
701 return 0; 703 return 0;
702 } 704 }
703 mntget(parent); 705 mntget(&parent->mnt);
704 mountpoint = dget(path->mnt->mnt_mountpoint); 706 mountpoint = dget(mnt->mnt.mnt_mountpoint);
705 br_read_unlock(vfsmount_lock); 707 br_read_unlock(vfsmount_lock);
706 dput(path->dentry); 708 dput(path->dentry);
707 path->dentry = mountpoint; 709 path->dentry = mountpoint;
708 mntput(path->mnt); 710 mntput(path->mnt);
709 path->mnt = parent; 711 path->mnt = &parent->mnt;
710 return 1; 712 return 1;
711} 713}
712 714
diff --git a/fs/namespace.c b/fs/namespace.c
index c6384bc39db1..5e700c6df579 100644
--- a/fs/namespace.c
+++ b/fs/namespace.c
@@ -476,7 +476,7 @@ struct mount *__lookup_mnt(struct vfsmount *mnt, struct dentry *dentry,
476 if (tmp == head) 476 if (tmp == head)
477 break; 477 break;
478 p = list_entry(tmp, struct mount, mnt_hash); 478 p = list_entry(tmp, struct mount, mnt_hash);
479 if (p->mnt_parent == mnt && p->mnt.mnt_mountpoint == dentry) { 479 if (&p->mnt_parent->mnt == mnt && p->mnt.mnt_mountpoint == dentry) {
480 found = p; 480 found = p;
481 break; 481 break;
482 } 482 }
@@ -558,8 +558,8 @@ static void dentry_reset_mounted(struct dentry *dentry)
558static void detach_mnt(struct mount *mnt, struct path *old_path) 558static void detach_mnt(struct mount *mnt, struct path *old_path)
559{ 559{
560 old_path->dentry = mnt->mnt.mnt_mountpoint; 560 old_path->dentry = mnt->mnt.mnt_mountpoint;
561 old_path->mnt = mnt->mnt_parent; 561 old_path->mnt = &mnt->mnt_parent->mnt;
562 mnt->mnt_parent = &mnt->mnt; 562 mnt->mnt_parent = mnt;
563 mnt->mnt.mnt_mountpoint = mnt->mnt.mnt_root; 563 mnt->mnt.mnt_mountpoint = mnt->mnt.mnt_root;
564 list_del_init(&mnt->mnt.mnt_child); 564 list_del_init(&mnt->mnt.mnt_child);
565 list_del_init(&mnt->mnt_hash); 565 list_del_init(&mnt->mnt_hash);
@@ -572,7 +572,7 @@ static void detach_mnt(struct mount *mnt, struct path *old_path)
572void mnt_set_mountpoint(struct vfsmount *mnt, struct dentry *dentry, 572void mnt_set_mountpoint(struct vfsmount *mnt, struct dentry *dentry,
573 struct mount *child_mnt) 573 struct mount *child_mnt)
574{ 574{
575 child_mnt->mnt_parent = mntget(mnt); 575 child_mnt->mnt_parent = real_mount(mntget(mnt));
576 child_mnt->mnt.mnt_mountpoint = dget(dentry); 576 child_mnt->mnt.mnt_mountpoint = dget(dentry);
577 spin_lock(&dentry->d_lock); 577 spin_lock(&dentry->d_lock);
578 dentry->d_flags |= DCACHE_MOUNTED; 578 dentry->d_flags |= DCACHE_MOUNTED;
@@ -610,12 +610,12 @@ static inline void __mnt_make_shortterm(struct vfsmount *mnt)
610 */ 610 */
611static void commit_tree(struct mount *mnt) 611static void commit_tree(struct mount *mnt)
612{ 612{
613 struct vfsmount *parent = mnt->mnt_parent; 613 struct mount *parent = mnt->mnt_parent;
614 struct vfsmount *m; 614 struct vfsmount *m;
615 LIST_HEAD(head); 615 LIST_HEAD(head);
616 struct mnt_namespace *n = parent->mnt_ns; 616 struct mnt_namespace *n = parent->mnt.mnt_ns;
617 617
618 BUG_ON(parent == &mnt->mnt); 618 BUG_ON(parent == mnt);
619 619
620 list_add_tail(&head, &mnt->mnt.mnt_list); 620 list_add_tail(&head, &mnt->mnt.mnt_list);
621 list_for_each_entry(m, &head, mnt_list) { 621 list_for_each_entry(m, &head, mnt_list) {
@@ -626,8 +626,8 @@ static void commit_tree(struct mount *mnt)
626 list_splice(&head, n->list.prev); 626 list_splice(&head, n->list.prev);
627 627
628 list_add_tail(&mnt->mnt_hash, mount_hashtable + 628 list_add_tail(&mnt->mnt_hash, mount_hashtable +
629 hash(parent, mnt->mnt.mnt_mountpoint)); 629 hash(&parent->mnt, mnt->mnt.mnt_mountpoint));
630 list_add_tail(&mnt->mnt.mnt_child, &parent->mnt_mounts); 630 list_add_tail(&mnt->mnt.mnt_child, &parent->mnt.mnt_mounts);
631 touch_mnt_namespace(n); 631 touch_mnt_namespace(n);
632} 632}
633 633
@@ -639,9 +639,9 @@ static struct mount *next_mnt(struct mount *p, struct vfsmount *root)
639 if (&p->mnt == root) 639 if (&p->mnt == root)
640 return NULL; 640 return NULL;
641 next = p->mnt.mnt_child.next; 641 next = p->mnt.mnt_child.next;
642 if (next != &p->mnt_parent->mnt_mounts) 642 if (next != &p->mnt_parent->mnt.mnt_mounts)
643 break; 643 break;
644 p = real_mount(p->mnt_parent); 644 p = p->mnt_parent;
645 } 645 }
646 } 646 }
647 return list_entry(next, struct mount, mnt.mnt_child); 647 return list_entry(next, struct mount, mnt.mnt_child);
@@ -682,7 +682,7 @@ vfs_kern_mount(struct file_system_type *type, int flags, const char *name, void
682 mnt->mnt.mnt_root = root; 682 mnt->mnt.mnt_root = root;
683 mnt->mnt.mnt_sb = root->d_sb; 683 mnt->mnt.mnt_sb = root->d_sb;
684 mnt->mnt.mnt_mountpoint = mnt->mnt.mnt_root; 684 mnt->mnt.mnt_mountpoint = mnt->mnt.mnt_root;
685 mnt->mnt_parent = &mnt->mnt; 685 mnt->mnt_parent = mnt;
686 return &mnt->mnt; 686 return &mnt->mnt;
687} 687}
688EXPORT_SYMBOL_GPL(vfs_kern_mount); 688EXPORT_SYMBOL_GPL(vfs_kern_mount);
@@ -710,7 +710,7 @@ static struct mount *clone_mnt(struct mount *old, struct dentry *root,
710 mnt->mnt.mnt_sb = sb; 710 mnt->mnt.mnt_sb = sb;
711 mnt->mnt.mnt_root = dget(root); 711 mnt->mnt.mnt_root = dget(root);
712 mnt->mnt.mnt_mountpoint = mnt->mnt.mnt_root; 712 mnt->mnt.mnt_mountpoint = mnt->mnt.mnt_root;
713 mnt->mnt_parent = &mnt->mnt; 713 mnt->mnt_parent = mnt;
714 714
715 if (flag & CL_SLAVE) { 715 if (flag & CL_SLAVE) {
716 list_add(&mnt->mnt.mnt_slave, &old->mnt.mnt_slave_list); 716 list_add(&mnt->mnt.mnt_slave, &old->mnt.mnt_slave_list);
@@ -1027,7 +1027,7 @@ static int show_mountinfo(struct seq_file *m, void *v)
1027 struct path root = p->root; 1027 struct path root = p->root;
1028 int err = 0; 1028 int err = 0;
1029 1029
1030 seq_printf(m, "%i %i %u:%u ", mnt->mnt_id, r->mnt_parent->mnt_id, 1030 seq_printf(m, "%i %i %u:%u ", mnt->mnt_id, r->mnt_parent->mnt.mnt_id,
1031 MAJOR(sb->s_dev), MINOR(sb->s_dev)); 1031 MAJOR(sb->s_dev), MINOR(sb->s_dev));
1032 if (sb->s_op->show_path) 1032 if (sb->s_op->show_path)
1033 err = sb->s_op->show_path(m, mnt); 1033 err = sb->s_op->show_path(m, mnt);
@@ -1202,9 +1202,9 @@ void release_mounts(struct list_head *head)
1202 1202
1203 br_write_lock(vfsmount_lock); 1203 br_write_lock(vfsmount_lock);
1204 dentry = mnt->mnt.mnt_mountpoint; 1204 dentry = mnt->mnt.mnt_mountpoint;
1205 m = mnt->mnt_parent; 1205 m = &mnt->mnt_parent->mnt;
1206 mnt->mnt.mnt_mountpoint = mnt->mnt.mnt_root; 1206 mnt->mnt.mnt_mountpoint = mnt->mnt.mnt_root;
1207 mnt->mnt_parent = &mnt->mnt; 1207 mnt->mnt_parent = mnt;
1208 m->mnt_ghosts--; 1208 m->mnt_ghosts--;
1209 br_write_unlock(vfsmount_lock); 1209 br_write_unlock(vfsmount_lock);
1210 dput(dentry); 1210 dput(dentry);
@@ -1237,7 +1237,7 @@ void umount_tree(struct mount *mnt, int propagate, struct list_head *kill)
1237 __mnt_make_shortterm(&p->mnt); 1237 __mnt_make_shortterm(&p->mnt);
1238 list_del_init(&p->mnt.mnt_child); 1238 list_del_init(&p->mnt.mnt_child);
1239 if (mnt_has_parent(p)) { 1239 if (mnt_has_parent(p)) {
1240 p->mnt_parent->mnt_ghosts++; 1240 p->mnt_parent->mnt.mnt_ghosts++;
1241 dentry_reset_mounted(p->mnt.mnt_mountpoint); 1241 dentry_reset_mounted(p->mnt.mnt_mountpoint);
1242 } 1242 }
1243 change_mnt_propagation(p, MS_PRIVATE); 1243 change_mnt_propagation(p, MS_PRIVATE);
@@ -1435,9 +1435,9 @@ struct mount *copy_tree(struct mount *mnt, struct dentry *dentry,
1435 s = skip_mnt_tree(s); 1435 s = skip_mnt_tree(s);
1436 continue; 1436 continue;
1437 } 1437 }
1438 while (p != real_mount(s->mnt_parent)) { 1438 while (p != s->mnt_parent) {
1439 p = real_mount(p->mnt_parent); 1439 p = p->mnt_parent;
1440 q = real_mount(q->mnt_parent); 1440 q = q->mnt_parent;
1441 } 1441 }
1442 p = s; 1442 p = s;
1443 path.mnt = &q->mnt; 1443 path.mnt = &q->mnt;
@@ -1899,7 +1899,7 @@ static int do_move_mount(struct path *path, char *old_name)
1899 /* 1899 /*
1900 * Don't move a mount residing in a shared parent. 1900 * Don't move a mount residing in a shared parent.
1901 */ 1901 */
1902 if (IS_MNT_SHARED(old->mnt_parent)) 1902 if (IS_MNT_SHARED(&old->mnt_parent->mnt))
1903 goto out1; 1903 goto out1;
1904 /* 1904 /*
1905 * Don't move a mount tree containing unbindable mounts to a destination 1905 * Don't move a mount tree containing unbindable mounts to a destination
@@ -1909,7 +1909,7 @@ static int do_move_mount(struct path *path, char *old_name)
1909 tree_contains_unbindable(old)) 1909 tree_contains_unbindable(old))
1910 goto out1; 1910 goto out1;
1911 err = -ELOOP; 1911 err = -ELOOP;
1912 for (p = real_mount(path->mnt); mnt_has_parent(p); p = real_mount(p->mnt_parent)) 1912 for (p = real_mount(path->mnt); mnt_has_parent(p); p = p->mnt_parent)
1913 if (p == old) 1913 if (p == old)
1914 goto out1; 1914 goto out1;
1915 1915
@@ -2159,7 +2159,7 @@ resume:
2159 */ 2159 */
2160 if (this_parent != parent) { 2160 if (this_parent != parent) {
2161 next = this_parent->mnt.mnt_child.next; 2161 next = this_parent->mnt.mnt_child.next;
2162 this_parent = real_mount(this_parent->mnt_parent); 2162 this_parent = this_parent->mnt_parent;
2163 goto resume; 2163 goto resume;
2164 } 2164 }
2165 return found; 2165 return found;
@@ -2565,7 +2565,7 @@ bool is_path_reachable(struct mount *mnt, struct dentry *dentry,
2565{ 2565{
2566 while (&mnt->mnt != root->mnt && mnt_has_parent(mnt)) { 2566 while (&mnt->mnt != root->mnt && mnt_has_parent(mnt)) {
2567 dentry = mnt->mnt.mnt_mountpoint; 2567 dentry = mnt->mnt.mnt_mountpoint;
2568 mnt = real_mount(mnt->mnt_parent); 2568 mnt = mnt->mnt_parent;
2569 } 2569 }
2570 return &mnt->mnt == root->mnt && is_subdir(dentry, root->dentry); 2570 return &mnt->mnt == root->mnt && is_subdir(dentry, root->dentry);
2571} 2571}
@@ -2636,8 +2636,8 @@ SYSCALL_DEFINE2(pivot_root, const char __user *, new_root,
2636 new_mnt = real_mount(new.mnt); 2636 new_mnt = real_mount(new.mnt);
2637 root_mnt = real_mount(root.mnt); 2637 root_mnt = real_mount(root.mnt);
2638 if (IS_MNT_SHARED(old.mnt) || 2638 if (IS_MNT_SHARED(old.mnt) ||
2639 IS_MNT_SHARED(new_mnt->mnt_parent) || 2639 IS_MNT_SHARED(&new_mnt->mnt_parent->mnt) ||
2640 IS_MNT_SHARED(root_mnt->mnt_parent)) 2640 IS_MNT_SHARED(&root_mnt->mnt_parent->mnt))
2641 goto out4; 2641 goto out4;
2642 if (!check_mnt(root.mnt) || !check_mnt(new.mnt)) 2642 if (!check_mnt(root.mnt) || !check_mnt(new.mnt))
2643 goto out4; 2643 goto out4;
diff --git a/fs/pnode.c b/fs/pnode.c
index 2ff4dfa018e1..7fddc671f729 100644
--- a/fs/pnode.c
+++ b/fs/pnode.c
@@ -292,10 +292,10 @@ int propagate_mount_busy(struct mount *mnt, int refcnt)
292{ 292{
293 struct vfsmount *m; 293 struct vfsmount *m;
294 struct mount *child; 294 struct mount *child;
295 struct vfsmount *parent = mnt->mnt_parent; 295 struct mount *parent = mnt->mnt_parent;
296 int ret = 0; 296 int ret = 0;
297 297
298 if (&mnt->mnt == parent) 298 if (mnt == parent)
299 return do_refcount_check(mnt, refcnt); 299 return do_refcount_check(mnt, refcnt);
300 300
301 /* 301 /*
@@ -306,8 +306,8 @@ int propagate_mount_busy(struct mount *mnt, int refcnt)
306 if (!list_empty(&mnt->mnt.mnt_mounts) || do_refcount_check(mnt, refcnt)) 306 if (!list_empty(&mnt->mnt.mnt_mounts) || do_refcount_check(mnt, refcnt))
307 return 1; 307 return 1;
308 308
309 for (m = propagation_next(parent, parent); m; 309 for (m = propagation_next(&parent->mnt, &parent->mnt); m;
310 m = propagation_next(m, parent)) { 310 m = propagation_next(m, &parent->mnt)) {
311 child = __lookup_mnt(m, mnt->mnt.mnt_mountpoint, 0); 311 child = __lookup_mnt(m, mnt->mnt.mnt_mountpoint, 0);
312 if (child && list_empty(&child->mnt.mnt_mounts) && 312 if (child && list_empty(&child->mnt.mnt_mounts) &&
313 (ret = do_refcount_check(child, 1))) 313 (ret = do_refcount_check(child, 1)))
@@ -322,13 +322,13 @@ int propagate_mount_busy(struct mount *mnt, int refcnt)
322 */ 322 */
323static void __propagate_umount(struct mount *mnt) 323static void __propagate_umount(struct mount *mnt)
324{ 324{
325 struct vfsmount *parent = mnt->mnt_parent; 325 struct mount *parent = mnt->mnt_parent;
326 struct vfsmount *m; 326 struct vfsmount *m;
327 327
328 BUG_ON(parent == &mnt->mnt); 328 BUG_ON(parent == mnt);
329 329
330 for (m = propagation_next(parent, parent); m; 330 for (m = propagation_next(&parent->mnt, &parent->mnt); m;
331 m = propagation_next(m, parent)) { 331 m = propagation_next(m, &parent->mnt)) {
332 332
333 struct mount *child = __lookup_mnt(m, 333 struct mount *child = __lookup_mnt(m,
334 mnt->mnt.mnt_mountpoint, 0); 334 mnt->mnt.mnt_mountpoint, 0);