diff options
author | Alexander Bluhm <bluhm@cvs.openbsd.org> | 2018-05-08 10:53:36 +0000 |
---|---|---|
committer | Alexander Bluhm <bluhm@cvs.openbsd.org> | 2018-05-08 10:53:36 +0000 |
commit | 90dc32cceb02a00bfd0abde863c7f40be04db7b1 (patch) | |
tree | 26366f9a6187cbcce41f76fc1147110caaf6c047 /sys/kern | |
parent | 6faf5e04ac771ee419ade4d3426a8fb812669559 (diff) |
When looping over mount points, the FOREACH SAVE macro is not save.
The loop variable mp is protected by vfs_busy() so that it cannot
be unmounted. But the next mount point nmp could be unmounted while
VFS_SYNC() sleeps. As the loop in vfs_stall() does not destroy the
mount point, TAILQ_FOREACH_REVERSE without _SAVE is the correct
macro to use.
OK deraadt@ visa@
Diffstat (limited to 'sys/kern')
-rw-r--r-- | sys/kern/vfs_subr.c | 10 |
1 files changed, 7 insertions, 3 deletions
diff --git a/sys/kern/vfs_subr.c b/sys/kern/vfs_subr.c index 149819a0664..ac2310268ee 100644 --- a/sys/kern/vfs_subr.c +++ b/sys/kern/vfs_subr.c @@ -1,4 +1,4 @@ -/* $OpenBSD: vfs_subr.c,v 1.271 2018/05/08 08:58:49 mpi Exp $ */ +/* $OpenBSD: vfs_subr.c,v 1.272 2018/05/08 10:53:35 bluhm Exp $ */ /* $NetBSD: vfs_subr.c,v 1.53 1996/04/22 01:39:13 christos Exp $ */ /* @@ -1590,13 +1590,17 @@ struct rwlock vfs_stall_lock = RWLOCK_INITIALIZER("vfs_stall"); int vfs_stall(struct proc *p, int stall) { - struct mount *mp, *nmp; + struct mount *mp; int allerror = 0, error; if (stall) rw_enter_write(&vfs_stall_lock); - TAILQ_FOREACH_REVERSE_SAFE(mp, &mountlist, mntlist, mnt_list, nmp) { + /* + * The loop variable mp is protected by vfs_busy() so that it cannot + * be unmounted while VFS_SYNC() sleeps. + */ + TAILQ_FOREACH_REVERSE(mp, &mountlist, mntlist, mnt_list) { if (stall) { error = vfs_busy(mp, VB_WRITE|VB_WAIT); if (error) { |