- 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
This commit is contained in:
parent
97735db712
commit
804e60d4cf
@ -862,27 +862,21 @@ _vn_lock(struct vnode *vp, int flags, char *file, int line)
|
|||||||
{
|
{
|
||||||
int error;
|
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)
|
if ((flags & LK_INTERLOCK) == 0)
|
||||||
VI_LOCK(vp);
|
VI_LOCK(vp);
|
||||||
if ((flags & LK_NOWAIT || (flags & LK_TYPE_MASK) == 0) &&
|
if (vp->v_iflag & VI_DOOMED)
|
||||||
vp->v_iflag & VI_DOOMED) {
|
error = ENOENT;
|
||||||
VI_UNLOCK(vp);
|
VI_UNLOCK(vp);
|
||||||
return (ENOENT);
|
return (error);
|
||||||
}
|
}
|
||||||
/*
|
do {
|
||||||
* Just polling to check validity.
|
error = VOP_LOCK1(vp, flags, file, line);
|
||||||
*/
|
flags &= ~LK_INTERLOCK; /* Interlock is always dropped. */
|
||||||
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;
|
|
||||||
KASSERT((flags & LK_RETRY) == 0 || error == 0,
|
KASSERT((flags & LK_RETRY) == 0 || error == 0,
|
||||||
("LK_RETRY set with incompatible flags %d\n", flags));
|
("LK_RETRY set with incompatible flags %d\n", flags));
|
||||||
/*
|
/*
|
||||||
|
Loading…
x
Reference in New Issue
Block a user