diff options
Diffstat (limited to 'fs')
-rw-r--r-- | fs/dcache.c | 2 | ||||
-rw-r--r-- | fs/mount.h | 3 | ||||
-rw-r--r-- | fs/namei.c | 4 | ||||
-rw-r--r-- | fs/namespace.c | 45 | ||||
-rw-r--r-- | fs/pnode.c | 4 |
5 files changed, 30 insertions, 28 deletions
diff --git a/fs/dcache.c b/fs/dcache.c index 1834e715f814..eef2d5472f9c 100644 --- a/fs/dcache.c +++ b/fs/dcache.c | |||
@@ -2465,7 +2465,7 @@ static int prepend_path(const struct path *path, | |||
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 = vfsmnt->mnt_mountpoint; |
2468 | vfsmnt = vfsmnt->mnt_parent; | 2468 | vfsmnt = mnt->mnt_parent; |
2469 | continue; | 2469 | continue; |
2470 | } | 2470 | } |
2471 | parent = dentry->d_parent; | 2471 | parent = dentry->d_parent; |
diff --git a/fs/mount.h b/fs/mount.h index 541daf568f63..5126c0861102 100644 --- a/fs/mount.h +++ b/fs/mount.h | |||
@@ -2,6 +2,7 @@ | |||
2 | 2 | ||
3 | struct mount { | 3 | struct mount { |
4 | struct list_head mnt_hash; | 4 | struct list_head mnt_hash; |
5 | struct vfsmount *mnt_parent; | ||
5 | struct vfsmount mnt; | 6 | struct vfsmount mnt; |
6 | }; | 7 | }; |
7 | 8 | ||
@@ -12,7 +13,7 @@ static inline struct mount *real_mount(struct vfsmount *mnt) | |||
12 | 13 | ||
13 | static inline int mnt_has_parent(struct mount *mnt) | 14 | static inline int mnt_has_parent(struct mount *mnt) |
14 | { | 15 | { |
15 | return &mnt->mnt != mnt->mnt.mnt_parent; | 16 | return &mnt->mnt != mnt->mnt_parent; |
16 | } | 17 | } |
17 | 18 | ||
18 | extern struct mount *__lookup_mnt(struct vfsmount *, struct dentry *, int); | 19 | extern struct mount *__lookup_mnt(struct vfsmount *, struct dentry *, int); |
diff --git a/fs/namei.c b/fs/namei.c index d1c6a559f8f0..89248bf1b906 100644 --- a/fs/namei.c +++ b/fs/namei.c | |||
@@ -680,7 +680,7 @@ static int follow_up_rcu(struct path *path) | |||
680 | struct vfsmount *parent; | 680 | struct vfsmount *parent; |
681 | struct dentry *mountpoint; | 681 | struct dentry *mountpoint; |
682 | 682 | ||
683 | parent = path->mnt->mnt_parent; | 683 | parent = real_mount(path->mnt)->mnt_parent; |
684 | if (parent == path->mnt) | 684 | if (parent == path->mnt) |
685 | return 0; | 685 | return 0; |
686 | mountpoint = path->mnt->mnt_mountpoint; | 686 | mountpoint = path->mnt->mnt_mountpoint; |
@@ -695,7 +695,7 @@ int follow_up(struct path *path) | |||
695 | struct dentry *mountpoint; | 695 | struct dentry *mountpoint; |
696 | 696 | ||
697 | br_read_lock(vfsmount_lock); | 697 | br_read_lock(vfsmount_lock); |
698 | parent = path->mnt->mnt_parent; | 698 | parent = real_mount(path->mnt)->mnt_parent; |
699 | if (parent == path->mnt) { | 699 | if (parent == path->mnt) { |
700 | br_read_unlock(vfsmount_lock); | 700 | br_read_unlock(vfsmount_lock); |
701 | return 0; | 701 | return 0; |
diff --git a/fs/namespace.c b/fs/namespace.c index b117d94fcdc1..c6384bc39db1 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.mnt_parent == mnt && p->mnt.mnt_mountpoint == dentry) { | 479 | if (p->mnt_parent == 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) | |||
558 | static void detach_mnt(struct mount *mnt, struct path *old_path) | 558 | static 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.mnt_parent; | 561 | old_path->mnt = mnt->mnt_parent; |
562 | mnt->mnt.mnt_parent = &mnt->mnt; | 562 | mnt->mnt_parent = &mnt->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) | |||
572 | void mnt_set_mountpoint(struct vfsmount *mnt, struct dentry *dentry, | 572 | void 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.mnt_parent = mntget(mnt); | 575 | child_mnt->mnt_parent = 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,7 +610,7 @@ static inline void __mnt_make_shortterm(struct vfsmount *mnt) | |||
610 | */ | 610 | */ |
611 | static void commit_tree(struct mount *mnt) | 611 | static void commit_tree(struct mount *mnt) |
612 | { | 612 | { |
613 | struct vfsmount *parent = mnt->mnt.mnt_parent; | 613 | struct vfsmount *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_ns; |
@@ -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.mnt_parent->mnt_mounts) | 642 | if (next != &p->mnt_parent->mnt_mounts) |
643 | break; | 643 | break; |
644 | p = real_mount(p->mnt.mnt_parent); | 644 | p = real_mount(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.mnt_parent = &mnt->mnt; | 685 | mnt->mnt_parent = &mnt->mnt; |
686 | return &mnt->mnt; | 686 | return &mnt->mnt; |
687 | } | 687 | } |
688 | EXPORT_SYMBOL_GPL(vfs_kern_mount); | 688 | EXPORT_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.mnt_parent = &mnt->mnt; | 713 | mnt->mnt_parent = &mnt->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); |
@@ -1021,12 +1021,13 @@ static int show_mountinfo(struct seq_file *m, void *v) | |||
1021 | { | 1021 | { |
1022 | struct proc_mounts *p = m->private; | 1022 | struct proc_mounts *p = m->private; |
1023 | struct vfsmount *mnt = list_entry(v, struct vfsmount, mnt_list); | 1023 | struct vfsmount *mnt = list_entry(v, struct vfsmount, mnt_list); |
1024 | struct mount *r = real_mount(mnt); | ||
1024 | struct super_block *sb = mnt->mnt_sb; | 1025 | struct super_block *sb = mnt->mnt_sb; |
1025 | struct path mnt_path = { .dentry = mnt->mnt_root, .mnt = mnt }; | 1026 | struct path mnt_path = { .dentry = mnt->mnt_root, .mnt = mnt }; |
1026 | struct path root = p->root; | 1027 | struct path root = p->root; |
1027 | int err = 0; | 1028 | int err = 0; |
1028 | 1029 | ||
1029 | seq_printf(m, "%i %i %u:%u ", mnt->mnt_id, mnt->mnt_parent->mnt_id, | 1030 | seq_printf(m, "%i %i %u:%u ", mnt->mnt_id, r->mnt_parent->mnt_id, |
1030 | MAJOR(sb->s_dev), MINOR(sb->s_dev)); | 1031 | MAJOR(sb->s_dev), MINOR(sb->s_dev)); |
1031 | if (sb->s_op->show_path) | 1032 | if (sb->s_op->show_path) |
1032 | err = sb->s_op->show_path(m, mnt); | 1033 | err = sb->s_op->show_path(m, mnt); |
@@ -1201,9 +1202,9 @@ void release_mounts(struct list_head *head) | |||
1201 | 1202 | ||
1202 | br_write_lock(vfsmount_lock); | 1203 | br_write_lock(vfsmount_lock); |
1203 | dentry = mnt->mnt.mnt_mountpoint; | 1204 | dentry = mnt->mnt.mnt_mountpoint; |
1204 | m = mnt->mnt.mnt_parent; | 1205 | m = mnt->mnt_parent; |
1205 | mnt->mnt.mnt_mountpoint = mnt->mnt.mnt_root; | 1206 | mnt->mnt.mnt_mountpoint = mnt->mnt.mnt_root; |
1206 | mnt->mnt.mnt_parent = &mnt->mnt; | 1207 | mnt->mnt_parent = &mnt->mnt; |
1207 | m->mnt_ghosts--; | 1208 | m->mnt_ghosts--; |
1208 | br_write_unlock(vfsmount_lock); | 1209 | br_write_unlock(vfsmount_lock); |
1209 | dput(dentry); | 1210 | dput(dentry); |
@@ -1236,7 +1237,7 @@ void umount_tree(struct mount *mnt, int propagate, struct list_head *kill) | |||
1236 | __mnt_make_shortterm(&p->mnt); | 1237 | __mnt_make_shortterm(&p->mnt); |
1237 | list_del_init(&p->mnt.mnt_child); | 1238 | list_del_init(&p->mnt.mnt_child); |
1238 | if (mnt_has_parent(p)) { | 1239 | if (mnt_has_parent(p)) { |
1239 | p->mnt.mnt_parent->mnt_ghosts++; | 1240 | p->mnt_parent->mnt_ghosts++; |
1240 | dentry_reset_mounted(p->mnt.mnt_mountpoint); | 1241 | dentry_reset_mounted(p->mnt.mnt_mountpoint); |
1241 | } | 1242 | } |
1242 | change_mnt_propagation(p, MS_PRIVATE); | 1243 | change_mnt_propagation(p, MS_PRIVATE); |
@@ -1434,9 +1435,9 @@ struct mount *copy_tree(struct mount *mnt, struct dentry *dentry, | |||
1434 | s = skip_mnt_tree(s); | 1435 | s = skip_mnt_tree(s); |
1435 | continue; | 1436 | continue; |
1436 | } | 1437 | } |
1437 | while (p != real_mount(s->mnt.mnt_parent)) { | 1438 | while (p != real_mount(s->mnt_parent)) { |
1438 | p = real_mount(p->mnt.mnt_parent); | 1439 | p = real_mount(p->mnt_parent); |
1439 | q = real_mount(q->mnt.mnt_parent); | 1440 | q = real_mount(q->mnt_parent); |
1440 | } | 1441 | } |
1441 | p = s; | 1442 | p = s; |
1442 | path.mnt = &q->mnt; | 1443 | path.mnt = &q->mnt; |
@@ -1898,7 +1899,7 @@ static int do_move_mount(struct path *path, char *old_name) | |||
1898 | /* | 1899 | /* |
1899 | * Don't move a mount residing in a shared parent. | 1900 | * Don't move a mount residing in a shared parent. |
1900 | */ | 1901 | */ |
1901 | if (IS_MNT_SHARED(old_path.mnt->mnt_parent)) | 1902 | if (IS_MNT_SHARED(old->mnt_parent)) |
1902 | goto out1; | 1903 | goto out1; |
1903 | /* | 1904 | /* |
1904 | * 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 |
@@ -1908,7 +1909,7 @@ static int do_move_mount(struct path *path, char *old_name) | |||
1908 | tree_contains_unbindable(old)) | 1909 | tree_contains_unbindable(old)) |
1909 | goto out1; | 1910 | goto out1; |
1910 | err = -ELOOP; | 1911 | err = -ELOOP; |
1911 | for (p = real_mount(path->mnt); mnt_has_parent(p); p = real_mount(p->mnt.mnt_parent)) | 1912 | for (p = real_mount(path->mnt); mnt_has_parent(p); p = real_mount(p->mnt_parent)) |
1912 | if (p == old) | 1913 | if (p == old) |
1913 | goto out1; | 1914 | goto out1; |
1914 | 1915 | ||
@@ -2158,7 +2159,7 @@ resume: | |||
2158 | */ | 2159 | */ |
2159 | if (this_parent != parent) { | 2160 | if (this_parent != parent) { |
2160 | next = this_parent->mnt.mnt_child.next; | 2161 | next = this_parent->mnt.mnt_child.next; |
2161 | this_parent = real_mount(this_parent->mnt.mnt_parent); | 2162 | this_parent = real_mount(this_parent->mnt_parent); |
2162 | goto resume; | 2163 | goto resume; |
2163 | } | 2164 | } |
2164 | return found; | 2165 | return found; |
@@ -2564,7 +2565,7 @@ bool is_path_reachable(struct mount *mnt, struct dentry *dentry, | |||
2564 | { | 2565 | { |
2565 | while (&mnt->mnt != root->mnt && mnt_has_parent(mnt)) { | 2566 | while (&mnt->mnt != root->mnt && mnt_has_parent(mnt)) { |
2566 | dentry = mnt->mnt.mnt_mountpoint; | 2567 | dentry = mnt->mnt.mnt_mountpoint; |
2567 | mnt = real_mount(mnt->mnt.mnt_parent); | 2568 | mnt = real_mount(mnt->mnt_parent); |
2568 | } | 2569 | } |
2569 | return &mnt->mnt == root->mnt && is_subdir(dentry, root->dentry); | 2570 | return &mnt->mnt == root->mnt && is_subdir(dentry, root->dentry); |
2570 | } | 2571 | } |
@@ -2635,8 +2636,8 @@ SYSCALL_DEFINE2(pivot_root, const char __user *, new_root, | |||
2635 | new_mnt = real_mount(new.mnt); | 2636 | new_mnt = real_mount(new.mnt); |
2636 | root_mnt = real_mount(root.mnt); | 2637 | root_mnt = real_mount(root.mnt); |
2637 | if (IS_MNT_SHARED(old.mnt) || | 2638 | if (IS_MNT_SHARED(old.mnt) || |
2638 | IS_MNT_SHARED(new.mnt->mnt_parent) || | 2639 | IS_MNT_SHARED(new_mnt->mnt_parent) || |
2639 | IS_MNT_SHARED(root.mnt->mnt_parent)) | 2640 | IS_MNT_SHARED(root_mnt->mnt_parent)) |
2640 | goto out4; | 2641 | goto out4; |
2641 | if (!check_mnt(root.mnt) || !check_mnt(new.mnt)) | 2642 | if (!check_mnt(root.mnt) || !check_mnt(new.mnt)) |
2642 | goto out4; | 2643 | goto out4; |
diff --git a/fs/pnode.c b/fs/pnode.c index 25f74b53dea6..2ff4dfa018e1 100644 --- a/fs/pnode.c +++ b/fs/pnode.c | |||
@@ -292,7 +292,7 @@ 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.mnt_parent; | 295 | struct vfsmount *parent = mnt->mnt_parent; |
296 | int ret = 0; | 296 | int ret = 0; |
297 | 297 | ||
298 | if (&mnt->mnt == parent) | 298 | if (&mnt->mnt == parent) |
@@ -322,7 +322,7 @@ int propagate_mount_busy(struct mount *mnt, int refcnt) | |||
322 | */ | 322 | */ |
323 | static void __propagate_umount(struct mount *mnt) | 323 | static void __propagate_umount(struct mount *mnt) |
324 | { | 324 | { |
325 | struct vfsmount *parent = mnt->mnt.mnt_parent; | 325 | struct vfsmount *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->mnt); |