diff options
Diffstat (limited to 'fs/pnode.c')
-rw-r--r-- | fs/pnode.c | 25 |
1 files changed, 14 insertions, 11 deletions
diff --git a/fs/pnode.c b/fs/pnode.c index c524fdddc7fb..99899705b105 100644 --- a/fs/pnode.c +++ b/fs/pnode.c | |||
@@ -198,7 +198,7 @@ static struct mount *next_group(struct mount *m, struct mount *origin) | |||
198 | 198 | ||
199 | /* all accesses are serialized by namespace_sem */ | 199 | /* all accesses are serialized by namespace_sem */ |
200 | static struct user_namespace *user_ns; | 200 | static struct user_namespace *user_ns; |
201 | static struct mount *last_dest, *last_source, *dest_master; | 201 | static struct mount *last_dest, *first_source, *last_source, *dest_master; |
202 | static struct mountpoint *mp; | 202 | static struct mountpoint *mp; |
203 | static struct hlist_head *list; | 203 | static struct hlist_head *list; |
204 | 204 | ||
@@ -221,20 +221,22 @@ static int propagate_one(struct mount *m) | |||
221 | type = CL_MAKE_SHARED; | 221 | type = CL_MAKE_SHARED; |
222 | } else { | 222 | } else { |
223 | struct mount *n, *p; | 223 | struct mount *n, *p; |
224 | bool done; | ||
224 | for (n = m; ; n = p) { | 225 | for (n = m; ; n = p) { |
225 | p = n->mnt_master; | 226 | p = n->mnt_master; |
226 | if (p == dest_master || IS_MNT_MARKED(p)) { | 227 | if (p == dest_master || IS_MNT_MARKED(p)) |
227 | while (last_dest->mnt_master != p) { | ||
228 | last_source = last_source->mnt_master; | ||
229 | last_dest = last_source->mnt_parent; | ||
230 | } | ||
231 | if (!peers(n, last_dest)) { | ||
232 | last_source = last_source->mnt_master; | ||
233 | last_dest = last_source->mnt_parent; | ||
234 | } | ||
235 | break; | 228 | break; |
236 | } | ||
237 | } | 229 | } |
230 | do { | ||
231 | struct mount *parent = last_source->mnt_parent; | ||
232 | if (last_source == first_source) | ||
233 | break; | ||
234 | done = parent->mnt_master == p; | ||
235 | if (done && peers(n, parent)) | ||
236 | break; | ||
237 | last_source = last_source->mnt_master; | ||
238 | } while (!done); | ||
239 | |||
238 | type = CL_SLAVE; | 240 | type = CL_SLAVE; |
239 | /* beginning of peer group among the slaves? */ | 241 | /* beginning of peer group among the slaves? */ |
240 | if (IS_MNT_SHARED(m)) | 242 | if (IS_MNT_SHARED(m)) |
@@ -286,6 +288,7 @@ int propagate_mnt(struct mount *dest_mnt, struct mountpoint *dest_mp, | |||
286 | */ | 288 | */ |
287 | user_ns = current->nsproxy->mnt_ns->user_ns; | 289 | user_ns = current->nsproxy->mnt_ns->user_ns; |
288 | last_dest = dest_mnt; | 290 | last_dest = dest_mnt; |
291 | first_source = source_mnt; | ||
289 | last_source = source_mnt; | 292 | last_source = source_mnt; |
290 | mp = dest_mp; | 293 | mp = dest_mp; |
291 | list = tree_list; | 294 | list = tree_list; |