summaryrefslogtreecommitdiffstats
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
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)
-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