summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorjeff <jeff@FreeBSD.org>2008-03-24 04:17:35 +0000
committerjeff <jeff@FreeBSD.org>2008-03-24 04:17:35 +0000
commit1bf44343e2274c517fe62ccd58a5fecf8f64e5da (patch)
tree87eeb0612db339bcbd7fdd7e47ddc14423ce65bc
parent955d594912f6c2359a899523e6e3097a542d4a70 (diff)
downloadFreeBSD-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.c32
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));
/*
OpenPOWER on IntegriCloud