- Fix interlock handling in vn_lock(). Previously, vn_lock() could return
with interlock held in error conditions when the caller did not specify LK_INTERLOCK. - Add several comments to vn_lock() describing the rational behind the code flow since it was not immediately obvious.
This commit is contained in:
parent
1e39ba8620
commit
820f26ad86
@ -843,25 +843,27 @@ debug_vn_lock(vp, flags, td, filename, line)
|
||||
vp->v_iflag |= VI_XWANT;
|
||||
msleep(vp, VI_MTX(vp), PINOD | PDROP,
|
||||
"vn_lock", 0);
|
||||
mp_fixme("interlock not released.");
|
||||
/*
|
||||
* Since we're just going to return, unlock interlock
|
||||
* if the caller didn't call us with it held.
|
||||
*/
|
||||
if ((flags & (LK_INTERLOCK|LK_RETRY)) == 0)
|
||||
VI_UNLOCK(vp);
|
||||
error = ENOENT;
|
||||
} else {
|
||||
#if 0
|
||||
/* this can now occur in normal operation */
|
||||
if (vp->v_vxproc != NULL)
|
||||
log(LOG_INFO, "VXLOCK interlock avoided in vn_lock\n");
|
||||
#endif
|
||||
#ifdef DEBUG_LOCKS
|
||||
vp->filename = filename;
|
||||
vp->line = line;
|
||||
#endif
|
||||
/*
|
||||
* lockmgr drops interlock before it will return for
|
||||
* any reason. So force the code above to relock it.
|
||||
*/
|
||||
error = VOP_LOCK(vp,
|
||||
flags | LK_NOPAUSE | LK_INTERLOCK, td);
|
||||
if (error == 0)
|
||||
return (error);
|
||||
flags &= ~LK_INTERLOCK;
|
||||
}
|
||||
flags &= ~LK_INTERLOCK;
|
||||
} while (flags & LK_RETRY);
|
||||
} while (flags & LK_RETRY && error != 0);
|
||||
return (error);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user