Commit 7b8a53fd authored by Al Viro's avatar Al Viro

fix old umount_tree() breakage

Expiry-related code calls umount_tree() several times with
the same list to collect vfsmounts to.  Which is fine, except
that umount_tree() implicitly assumed that the list would
be empty on each call - it moves the victims over there and
then iterates through the list kicking them out.  It's *almost*
idempotent, so everything nearly worked.  However, mnt->ghosts
handling (and thus expirability checks) had been broken - that
part was not idempotent...

The fix is trivial - use local temporary list, splice it to
the the collector list when we are through.
Signed-off-by: default avatarAl Viro <viro@zeniv.linux.org.uk>
parent b650c858
...@@ -1226,15 +1226,16 @@ void release_mounts(struct list_head *head) ...@@ -1226,15 +1226,16 @@ void release_mounts(struct list_head *head)
*/ */
void umount_tree(struct vfsmount *mnt, int propagate, struct list_head *kill) void umount_tree(struct vfsmount *mnt, int propagate, struct list_head *kill)
{ {
LIST_HEAD(tmp_list);
struct vfsmount *p; struct vfsmount *p;
for (p = mnt; p; p = next_mnt(p, mnt)) for (p = mnt; p; p = next_mnt(p, mnt))
list_move(&p->mnt_hash, kill); list_move(&p->mnt_hash, &tmp_list);
if (propagate) if (propagate)
propagate_umount(kill); propagate_umount(&tmp_list);
list_for_each_entry(p, kill, mnt_hash) { list_for_each_entry(p, &tmp_list, mnt_hash) {
list_del_init(&p->mnt_expire); list_del_init(&p->mnt_expire);
list_del_init(&p->mnt_list); list_del_init(&p->mnt_list);
__touch_mnt_namespace(p->mnt_ns); __touch_mnt_namespace(p->mnt_ns);
...@@ -1246,6 +1247,7 @@ void umount_tree(struct vfsmount *mnt, int propagate, struct list_head *kill) ...@@ -1246,6 +1247,7 @@ void umount_tree(struct vfsmount *mnt, int propagate, struct list_head *kill)
} }
change_mnt_propagation(p, MS_PRIVATE); change_mnt_propagation(p, MS_PRIVATE);
} }
list_splice(&tmp_list, kill);
} }
static void shrink_submounts(struct vfsmount *mnt, struct list_head *umounts); static void shrink_submounts(struct vfsmount *mnt, struct list_head *umounts);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment