summaryrefslogtreecommitdiffstats
path: root/sys/kern/vfs_subr.c
diff options
context:
space:
mode:
authortruckman <truckman@FreeBSD.org>2003-05-16 19:46:51 +0000
committertruckman <truckman@FreeBSD.org>2003-05-16 19:46:51 +0000
commit80040f21a37a2d2eef35514413b78a71a3e10e1a (patch)
tree2fc687109c77609add7b5d6c4f67a9fa6a40d277 /sys/kern/vfs_subr.c
parentc2a920683cbc3535c29dd87abea005f24d433681 (diff)
downloadFreeBSD-src-80040f21a37a2d2eef35514413b78a71a3e10e1a.zip
FreeBSD-src-80040f21a37a2d2eef35514413b78a71a3e10e1a.tar.gz
Detect that a vnode has been reclaimed while vflush() was waiting to lock
the vnode and restart the loop. Vflush() is vulnerable since it does not hold a reference to the vnode and it holds no other locks while waiting for the vnode lock. The vnode will no longer be on the list when the loop is restarted. Approved by: re (rwatson)
Diffstat (limited to 'sys/kern/vfs_subr.c')
-rw-r--r--sys/kern/vfs_subr.c11
1 files changed, 11 insertions, 0 deletions
diff --git a/sys/kern/vfs_subr.c b/sys/kern/vfs_subr.c
index ae9ef7f..14c2923 100644
--- a/sys/kern/vfs_subr.c
+++ b/sys/kern/vfs_subr.c
@@ -2398,6 +2398,17 @@ loop:
mtx_unlock(&mntvnode_mtx);
vn_lock(vp, LK_INTERLOCK | LK_EXCLUSIVE | LK_RETRY, td);
/*
+ * This vnode could have been reclaimed while we were
+ * waiting for the lock since we are not holding a
+ * reference.
+ * Start over if the vnode was reclaimed.
+ */
+ if (vp->v_mount != mp) {
+ VOP_UNLOCK(vp, 0, td);
+ mtx_lock(&mntvnode_mtx);
+ goto loop;
+ }
+ /*
* Skip over a vnodes marked VV_SYSTEM.
*/
if ((flags & SKIPSYSTEM) && (vp->v_vflag & VV_SYSTEM)) {
OpenPOWER on IntegriCloud