diff options
author | jeff <jeff@FreeBSD.org> | 2008-03-24 04:17:35 +0000 |
---|---|---|
committer | jeff <jeff@FreeBSD.org> | 2008-03-24 04:17:35 +0000 |
commit | 1bf44343e2274c517fe62ccd58a5fecf8f64e5da (patch) | |
tree | 87eeb0612db339bcbd7fdd7e47ddc14423ce65bc | |
parent | 955d594912f6c2359a899523e6e3097a542d4a70 (diff) | |
download | FreeBSD-src-1bf44343e2274c517fe62ccd58a5fecf8f64e5da.zip FreeBSD-src-1bf44343e2274c517fe62ccd58a5fecf8f64e5da.tar.gz |
- Don't acquire the vnode interlock in _vn_lock() unless no lock type
is requested. Handle this case specially before the while loop.
- Use the held vnode lock to check for VI_DOOMED. The vnode lock and
interlock must both be held to set VI_DOOMED so either one held, even
shared, is sufficient to check it.
No objection by: kib
-rw-r--r-- | sys/kern/vfs_vnops.c | 32 |
1 files changed, 13 insertions, 19 deletions
diff --git a/sys/kern/vfs_vnops.c b/sys/kern/vfs_vnops.c index 3102c02..7d2a132 100644 --- a/sys/kern/vfs_vnops.c +++ b/sys/kern/vfs_vnops.c @@ -862,27 +862,21 @@ _vn_lock(struct vnode *vp, int flags, char *file, int line) { int error; - do { + /* + * With no lock type requested we're just polling for validity. + */ + if ((flags & LK_TYPE_MASK) == 0) { + error = 0; if ((flags & LK_INTERLOCK) == 0) VI_LOCK(vp); - if ((flags & LK_NOWAIT || (flags & LK_TYPE_MASK) == 0) && - vp->v_iflag & VI_DOOMED) { - VI_UNLOCK(vp); - return (ENOENT); - } - /* - * Just polling to check validity. - */ - if ((flags & LK_TYPE_MASK) == 0) { - VI_UNLOCK(vp); - return (0); - } - /* - * lockmgr drops interlock before it will return for - * any reason. So force the code above to relock it. - */ - error = VOP_LOCK1(vp, flags | LK_INTERLOCK, file, line); - flags &= ~LK_INTERLOCK; + if (vp->v_iflag & VI_DOOMED) + error = ENOENT; + VI_UNLOCK(vp); + return (error); + } + do { + error = VOP_LOCK1(vp, flags, file, line); + flags &= ~LK_INTERLOCK; /* Interlock is always dropped. */ KASSERT((flags & LK_RETRY) == 0 || error == 0, ("LK_RETRY set with incompatible flags %d\n", flags)); /* |