diff options
-rw-r--r-- | fs/mount.h | 6 | ||||
-rw-r--r-- | fs/namespace.c | 41 | ||||
-rw-r--r-- | fs/pnode.c | 30 | ||||
-rw-r--r-- | include/linux/mount.h | 4 |
4 files changed, 41 insertions, 40 deletions
diff --git a/fs/mount.h b/fs/mount.h index d4db4c7e1815..eb62ad232e4d 100644 --- a/fs/mount.h +++ b/fs/mount.h | |||
@@ -19,7 +19,11 @@ struct mount { | |||
19 | #endif | 19 | #endif |
20 | struct list_head mnt_mounts; /* list of children, anchored here */ | 20 | struct list_head mnt_mounts; /* list of children, anchored here */ |
21 | struct list_head mnt_child; /* and going through their mnt_child */ | 21 | struct list_head mnt_child; /* and going through their mnt_child */ |
22 | /* yet to be moved - up to mnt_slave */ | 22 | /* yet to be moved - up to mnt_list */ |
23 | struct list_head mnt_expire; /* link in fs-specific expiry list */ | ||
24 | struct list_head mnt_share; /* circular list of shared mounts */ | ||
25 | struct list_head mnt_slave_list;/* list of slave mounts */ | ||
26 | struct list_head mnt_slave; /* slave list entry */ | ||
23 | struct mount *mnt_master; /* slave is on master->mnt_slave_list */ | 27 | struct mount *mnt_master; /* slave is on master->mnt_slave_list */ |
24 | }; | 28 | }; |
25 | 29 | ||
diff --git a/fs/namespace.c b/fs/namespace.c index 847b7240c512..a14750be7a70 100644 --- a/fs/namespace.c +++ b/fs/namespace.c | |||
@@ -203,10 +203,10 @@ static struct mount *alloc_vfsmnt(const char *name) | |||
203 | INIT_LIST_HEAD(&p->mnt_child); | 203 | INIT_LIST_HEAD(&p->mnt_child); |
204 | INIT_LIST_HEAD(&p->mnt_mounts); | 204 | INIT_LIST_HEAD(&p->mnt_mounts); |
205 | INIT_LIST_HEAD(&mnt->mnt_list); | 205 | INIT_LIST_HEAD(&mnt->mnt_list); |
206 | INIT_LIST_HEAD(&mnt->mnt_expire); | 206 | INIT_LIST_HEAD(&p->mnt_expire); |
207 | INIT_LIST_HEAD(&mnt->mnt_share); | 207 | INIT_LIST_HEAD(&p->mnt_share); |
208 | INIT_LIST_HEAD(&mnt->mnt_slave_list); | 208 | INIT_LIST_HEAD(&p->mnt_slave_list); |
209 | INIT_LIST_HEAD(&mnt->mnt_slave); | 209 | INIT_LIST_HEAD(&p->mnt_slave); |
210 | #ifdef CONFIG_FSNOTIFY | 210 | #ifdef CONFIG_FSNOTIFY |
211 | INIT_HLIST_HEAD(&mnt->mnt_fsnotify_marks); | 211 | INIT_HLIST_HEAD(&mnt->mnt_fsnotify_marks); |
212 | #endif | 212 | #endif |
@@ -714,14 +714,14 @@ static struct mount *clone_mnt(struct mount *old, struct dentry *root, | |||
714 | mnt->mnt_parent = mnt; | 714 | mnt->mnt_parent = mnt; |
715 | 715 | ||
716 | if (flag & CL_SLAVE) { | 716 | if (flag & CL_SLAVE) { |
717 | list_add(&mnt->mnt.mnt_slave, &old->mnt.mnt_slave_list); | 717 | list_add(&mnt->mnt_slave, &old->mnt_slave_list); |
718 | mnt->mnt_master = old; | 718 | mnt->mnt_master = old; |
719 | CLEAR_MNT_SHARED(&mnt->mnt); | 719 | CLEAR_MNT_SHARED(&mnt->mnt); |
720 | } else if (!(flag & CL_PRIVATE)) { | 720 | } else if (!(flag & CL_PRIVATE)) { |
721 | if ((flag & CL_MAKE_SHARED) || IS_MNT_SHARED(&old->mnt)) | 721 | if ((flag & CL_MAKE_SHARED) || IS_MNT_SHARED(&old->mnt)) |
722 | list_add(&mnt->mnt.mnt_share, &old->mnt.mnt_share); | 722 | list_add(&mnt->mnt_share, &old->mnt_share); |
723 | if (IS_MNT_SLAVE(old)) | 723 | if (IS_MNT_SLAVE(old)) |
724 | list_add(&mnt->mnt.mnt_slave, &old->mnt.mnt_slave); | 724 | list_add(&mnt->mnt_slave, &old->mnt_slave); |
725 | mnt->mnt_master = old->mnt_master; | 725 | mnt->mnt_master = old->mnt_master; |
726 | } | 726 | } |
727 | if (flag & CL_MAKE_SHARED) | 727 | if (flag & CL_MAKE_SHARED) |
@@ -730,8 +730,8 @@ static struct mount *clone_mnt(struct mount *old, struct dentry *root, | |||
730 | /* stick the duplicate mount on the same expiry list | 730 | /* stick the duplicate mount on the same expiry list |
731 | * as the original if that was on one */ | 731 | * as the original if that was on one */ |
732 | if (flag & CL_EXPIRE) { | 732 | if (flag & CL_EXPIRE) { |
733 | if (!list_empty(&old->mnt.mnt_expire)) | 733 | if (!list_empty(&old->mnt_expire)) |
734 | list_add(&mnt->mnt.mnt_expire, &old->mnt.mnt_expire); | 734 | list_add(&mnt->mnt_expire, &old->mnt_expire); |
735 | } | 735 | } |
736 | } | 736 | } |
737 | return mnt; | 737 | return mnt; |
@@ -1233,7 +1233,7 @@ void umount_tree(struct mount *mnt, int propagate, struct list_head *kill) | |||
1233 | propagate_umount(&tmp_list); | 1233 | propagate_umount(&tmp_list); |
1234 | 1234 | ||
1235 | list_for_each_entry(p, &tmp_list, mnt_hash) { | 1235 | list_for_each_entry(p, &tmp_list, mnt_hash) { |
1236 | list_del_init(&p->mnt.mnt_expire); | 1236 | list_del_init(&p->mnt_expire); |
1237 | list_del_init(&p->mnt.mnt_list); | 1237 | list_del_init(&p->mnt.mnt_list); |
1238 | __touch_mnt_namespace(p->mnt.mnt_ns); | 1238 | __touch_mnt_namespace(p->mnt.mnt_ns); |
1239 | p->mnt.mnt_ns = NULL; | 1239 | p->mnt.mnt_ns = NULL; |
@@ -1921,7 +1921,7 @@ static int do_move_mount(struct path *path, char *old_name) | |||
1921 | 1921 | ||
1922 | /* if the mount is moved, it should no longer be expire | 1922 | /* if the mount is moved, it should no longer be expire |
1923 | * automatically */ | 1923 | * automatically */ |
1924 | list_del_init(&old_path.mnt->mnt_expire); | 1924 | list_del_init(&old->mnt_expire); |
1925 | out1: | 1925 | out1: |
1926 | unlock_mount(path); | 1926 | unlock_mount(path); |
1927 | out: | 1927 | out: |
@@ -2033,11 +2033,12 @@ static int do_new_mount(struct path *path, char *type, int flags, | |||
2033 | 2033 | ||
2034 | int finish_automount(struct vfsmount *m, struct path *path) | 2034 | int finish_automount(struct vfsmount *m, struct path *path) |
2035 | { | 2035 | { |
2036 | struct mount *mnt = real_mount(m); | ||
2036 | int err; | 2037 | int err; |
2037 | /* The new mount record should have at least 2 refs to prevent it being | 2038 | /* The new mount record should have at least 2 refs to prevent it being |
2038 | * expired before we get a chance to add it | 2039 | * expired before we get a chance to add it |
2039 | */ | 2040 | */ |
2040 | BUG_ON(mnt_get_count(real_mount(m)) < 2); | 2041 | BUG_ON(mnt_get_count(mnt) < 2); |
2041 | 2042 | ||
2042 | if (m->mnt_sb == path->mnt->mnt_sb && | 2043 | if (m->mnt_sb == path->mnt->mnt_sb && |
2043 | m->mnt_root == path->dentry) { | 2044 | m->mnt_root == path->dentry) { |
@@ -2050,10 +2051,10 @@ int finish_automount(struct vfsmount *m, struct path *path) | |||
2050 | return 0; | 2051 | return 0; |
2051 | fail: | 2052 | fail: |
2052 | /* remove m from any expiration list it may be on */ | 2053 | /* remove m from any expiration list it may be on */ |
2053 | if (!list_empty(&m->mnt_expire)) { | 2054 | if (!list_empty(&mnt->mnt_expire)) { |
2054 | down_write(&namespace_sem); | 2055 | down_write(&namespace_sem); |
2055 | br_write_lock(vfsmount_lock); | 2056 | br_write_lock(vfsmount_lock); |
2056 | list_del_init(&m->mnt_expire); | 2057 | list_del_init(&mnt->mnt_expire); |
2057 | br_write_unlock(vfsmount_lock); | 2058 | br_write_unlock(vfsmount_lock); |
2058 | up_write(&namespace_sem); | 2059 | up_write(&namespace_sem); |
2059 | } | 2060 | } |
@@ -2072,7 +2073,7 @@ void mnt_set_expiry(struct vfsmount *mnt, struct list_head *expiry_list) | |||
2072 | down_write(&namespace_sem); | 2073 | down_write(&namespace_sem); |
2073 | br_write_lock(vfsmount_lock); | 2074 | br_write_lock(vfsmount_lock); |
2074 | 2075 | ||
2075 | list_add_tail(&mnt->mnt_expire, expiry_list); | 2076 | list_add_tail(&real_mount(mnt)->mnt_expire, expiry_list); |
2076 | 2077 | ||
2077 | br_write_unlock(vfsmount_lock); | 2078 | br_write_unlock(vfsmount_lock); |
2078 | up_write(&namespace_sem); | 2079 | up_write(&namespace_sem); |
@@ -2102,14 +2103,14 @@ void mark_mounts_for_expiry(struct list_head *mounts) | |||
2102 | * - still marked for expiry (marked on the last call here; marks are | 2103 | * - still marked for expiry (marked on the last call here; marks are |
2103 | * cleared by mntput()) | 2104 | * cleared by mntput()) |
2104 | */ | 2105 | */ |
2105 | list_for_each_entry_safe(mnt, next, mounts, mnt.mnt_expire) { | 2106 | list_for_each_entry_safe(mnt, next, mounts, mnt_expire) { |
2106 | if (!xchg(&mnt->mnt.mnt_expiry_mark, 1) || | 2107 | if (!xchg(&mnt->mnt.mnt_expiry_mark, 1) || |
2107 | propagate_mount_busy(mnt, 1)) | 2108 | propagate_mount_busy(mnt, 1)) |
2108 | continue; | 2109 | continue; |
2109 | list_move(&mnt->mnt.mnt_expire, &graveyard); | 2110 | list_move(&mnt->mnt_expire, &graveyard); |
2110 | } | 2111 | } |
2111 | while (!list_empty(&graveyard)) { | 2112 | while (!list_empty(&graveyard)) { |
2112 | mnt = list_first_entry(&graveyard, struct mount, mnt.mnt_expire); | 2113 | mnt = list_first_entry(&graveyard, struct mount, mnt_expire); |
2113 | touch_mnt_namespace(mnt->mnt.mnt_ns); | 2114 | touch_mnt_namespace(mnt->mnt.mnt_ns); |
2114 | umount_tree(mnt, 1, &umounts); | 2115 | umount_tree(mnt, 1, &umounts); |
2115 | } | 2116 | } |
@@ -2152,7 +2153,7 @@ resume: | |||
2152 | } | 2153 | } |
2153 | 2154 | ||
2154 | if (!propagate_mount_busy(mnt, 1)) { | 2155 | if (!propagate_mount_busy(mnt, 1)) { |
2155 | list_move_tail(&mnt->mnt.mnt_expire, graveyard); | 2156 | list_move_tail(&mnt->mnt_expire, graveyard); |
2156 | found++; | 2157 | found++; |
2157 | } | 2158 | } |
2158 | } | 2159 | } |
@@ -2182,7 +2183,7 @@ static void shrink_submounts(struct mount *mnt, struct list_head *umounts) | |||
2182 | while (select_submounts(mnt, &graveyard)) { | 2183 | while (select_submounts(mnt, &graveyard)) { |
2183 | while (!list_empty(&graveyard)) { | 2184 | while (!list_empty(&graveyard)) { |
2184 | m = list_first_entry(&graveyard, struct mount, | 2185 | m = list_first_entry(&graveyard, struct mount, |
2185 | mnt.mnt_expire); | 2186 | mnt_expire); |
2186 | touch_mnt_namespace(m->mnt.mnt_ns); | 2187 | touch_mnt_namespace(m->mnt.mnt_ns); |
2187 | umount_tree(m, 1, umounts); | 2188 | umount_tree(m, 1, umounts); |
2188 | } | 2189 | } |
diff --git a/fs/pnode.c b/fs/pnode.c index 9bf22b61f8fb..12cc1518e0cd 100644 --- a/fs/pnode.c +++ b/fs/pnode.c | |||
@@ -15,17 +15,17 @@ | |||
15 | /* return the next shared peer mount of @p */ | 15 | /* return the next shared peer mount of @p */ |
16 | static inline struct mount *next_peer(struct mount *p) | 16 | static inline struct mount *next_peer(struct mount *p) |
17 | { | 17 | { |
18 | return list_entry(p->mnt.mnt_share.next, struct mount, mnt.mnt_share); | 18 | return list_entry(p->mnt_share.next, struct mount, mnt_share); |
19 | } | 19 | } |
20 | 20 | ||
21 | static inline struct mount *first_slave(struct mount *p) | 21 | static inline struct mount *first_slave(struct mount *p) |
22 | { | 22 | { |
23 | return list_entry(p->mnt.mnt_slave_list.next, struct mount, mnt.mnt_slave); | 23 | return list_entry(p->mnt_slave_list.next, struct mount, mnt_slave); |
24 | } | 24 | } |
25 | 25 | ||
26 | static inline struct mount *next_slave(struct mount *p) | 26 | static inline struct mount *next_slave(struct mount *p) |
27 | { | 27 | { |
28 | return list_entry(p->mnt.mnt_slave.next, struct mount, mnt.mnt_slave); | 28 | return list_entry(p->mnt_slave.next, struct mount, mnt_slave); |
29 | } | 29 | } |
30 | 30 | ||
31 | static struct mount *get_peer_under_root(struct mount *mnt, | 31 | static struct mount *get_peer_under_root(struct mount *mnt, |
@@ -82,27 +82,27 @@ static int do_make_slave(struct mount *mnt) | |||
82 | if (peer_mnt == mnt) | 82 | if (peer_mnt == mnt) |
83 | peer_mnt = NULL; | 83 | peer_mnt = NULL; |
84 | } | 84 | } |
85 | if (IS_MNT_SHARED(&mnt->mnt) && list_empty(&mnt->mnt.mnt_share)) | 85 | if (IS_MNT_SHARED(&mnt->mnt) && list_empty(&mnt->mnt_share)) |
86 | mnt_release_group_id(mnt); | 86 | mnt_release_group_id(mnt); |
87 | 87 | ||
88 | list_del_init(&mnt->mnt.mnt_share); | 88 | list_del_init(&mnt->mnt_share); |
89 | mnt->mnt.mnt_group_id = 0; | 89 | mnt->mnt.mnt_group_id = 0; |
90 | 90 | ||
91 | if (peer_mnt) | 91 | if (peer_mnt) |
92 | master = peer_mnt; | 92 | master = peer_mnt; |
93 | 93 | ||
94 | if (master) { | 94 | if (master) { |
95 | list_for_each_entry(slave_mnt, &mnt->mnt.mnt_slave_list, mnt.mnt_slave) | 95 | list_for_each_entry(slave_mnt, &mnt->mnt_slave_list, mnt_slave) |
96 | slave_mnt->mnt_master = master; | 96 | slave_mnt->mnt_master = master; |
97 | list_move(&mnt->mnt.mnt_slave, &master->mnt.mnt_slave_list); | 97 | list_move(&mnt->mnt_slave, &master->mnt_slave_list); |
98 | list_splice(&mnt->mnt.mnt_slave_list, master->mnt.mnt_slave_list.prev); | 98 | list_splice(&mnt->mnt_slave_list, master->mnt_slave_list.prev); |
99 | INIT_LIST_HEAD(&mnt->mnt.mnt_slave_list); | 99 | INIT_LIST_HEAD(&mnt->mnt_slave_list); |
100 | } else { | 100 | } else { |
101 | struct list_head *p = &mnt->mnt.mnt_slave_list; | 101 | struct list_head *p = &mnt->mnt_slave_list; |
102 | while (!list_empty(p)) { | 102 | while (!list_empty(p)) { |
103 | slave_mnt = list_first_entry(p, | 103 | slave_mnt = list_first_entry(p, |
104 | struct mount, mnt.mnt_slave); | 104 | struct mount, mnt_slave); |
105 | list_del_init(&slave_mnt->mnt.mnt_slave); | 105 | list_del_init(&slave_mnt->mnt_slave); |
106 | slave_mnt->mnt_master = NULL; | 106 | slave_mnt->mnt_master = NULL; |
107 | } | 107 | } |
108 | } | 108 | } |
@@ -122,7 +122,7 @@ void change_mnt_propagation(struct mount *mnt, int type) | |||
122 | } | 122 | } |
123 | do_make_slave(mnt); | 123 | do_make_slave(mnt); |
124 | if (type != MS_SLAVE) { | 124 | if (type != MS_SLAVE) { |
125 | list_del_init(&mnt->mnt.mnt_slave); | 125 | list_del_init(&mnt->mnt_slave); |
126 | mnt->mnt_master = NULL; | 126 | mnt->mnt_master = NULL; |
127 | if (type == MS_UNBINDABLE) | 127 | if (type == MS_UNBINDABLE) |
128 | mnt->mnt.mnt_flags |= MNT_UNBINDABLE; | 128 | mnt->mnt.mnt_flags |= MNT_UNBINDABLE; |
@@ -145,7 +145,7 @@ static struct mount *propagation_next(struct mount *m, | |||
145 | struct mount *origin) | 145 | struct mount *origin) |
146 | { | 146 | { |
147 | /* are there any slaves of this mount? */ | 147 | /* are there any slaves of this mount? */ |
148 | if (!IS_MNT_NEW(&m->mnt) && !list_empty(&m->mnt.mnt_slave_list)) | 148 | if (!IS_MNT_NEW(&m->mnt) && !list_empty(&m->mnt_slave_list)) |
149 | return first_slave(m); | 149 | return first_slave(m); |
150 | 150 | ||
151 | while (1) { | 151 | while (1) { |
@@ -154,7 +154,7 @@ static struct mount *propagation_next(struct mount *m, | |||
154 | if (master == origin->mnt_master) { | 154 | if (master == origin->mnt_master) { |
155 | struct mount *next = next_peer(m); | 155 | struct mount *next = next_peer(m); |
156 | return (next == origin) ? NULL : next; | 156 | return (next == origin) ? NULL : next; |
157 | } else if (m->mnt.mnt_slave.next != &master->mnt.mnt_slave_list) | 157 | } else if (m->mnt_slave.next != &master->mnt_slave_list) |
158 | return next_slave(m); | 158 | return next_slave(m); |
159 | 159 | ||
160 | /* back at master */ | 160 | /* back at master */ |
diff --git a/include/linux/mount.h b/include/linux/mount.h index 2d5beb5e3a8c..2f5f3ae3bd2d 100644 --- a/include/linux/mount.h +++ b/include/linux/mount.h | |||
@@ -58,10 +58,6 @@ struct vfsmount { | |||
58 | #endif | 58 | #endif |
59 | const char *mnt_devname; /* Name of device e.g. /dev/dsk/hda1 */ | 59 | const char *mnt_devname; /* Name of device e.g. /dev/dsk/hda1 */ |
60 | struct list_head mnt_list; | 60 | struct list_head mnt_list; |
61 | struct list_head mnt_expire; /* link in fs-specific expiry list */ | ||
62 | struct list_head mnt_share; /* circular list of shared mounts */ | ||
63 | struct list_head mnt_slave_list;/* list of slave mounts */ | ||
64 | struct list_head mnt_slave; /* slave list entry */ | ||
65 | struct mnt_namespace *mnt_ns; /* containing namespace */ | 61 | struct mnt_namespace *mnt_ns; /* containing namespace */ |
66 | int mnt_id; /* mount identifier */ | 62 | int mnt_id; /* mount identifier */ |
67 | int mnt_group_id; /* peer group identifier */ | 63 | int mnt_group_id; /* peer group identifier */ |