diff options
author | truckman <truckman@FreeBSD.org> | 2003-05-16 19:46:51 +0000 |
---|---|---|
committer | truckman <truckman@FreeBSD.org> | 2003-05-16 19:46:51 +0000 |
commit | 80040f21a37a2d2eef35514413b78a71a3e10e1a (patch) | |
tree | 2fc687109c77609add7b5d6c4f67a9fa6a40d277 | |
parent | c2a920683cbc3535c29dd87abea005f24d433681 (diff) | |
download | FreeBSD-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.c | 11 |
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)) { |