summaryrefslogtreecommitdiff
path: root/sys/kern
diff options
context:
space:
mode:
authorAlexander Bluhm <bluhm@cvs.openbsd.org>2018-05-08 10:53:36 +0000
committerAlexander Bluhm <bluhm@cvs.openbsd.org>2018-05-08 10:53:36 +0000
commit90dc32cceb02a00bfd0abde863c7f40be04db7b1 (patch)
tree26366f9a6187cbcce41f76fc1147110caaf6c047 /sys/kern
parent6faf5e04ac771ee419ade4d3426a8fb812669559 (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.c10
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) {