In lf_advlockasync(), recheck for doomed vnode after the state->ls_lock
is acquired. In the lf_purgelocks(), assert that vnode is doomed and set *statep to NULL before clearing ls_pending list. Otherwise, we allow for the thread executing lf_advlockasync() to put new pending entry after state->ls_lock is dropped in lf_purgelocks(). Reviewed by: dfr Tested by: pho MFC after: 1 month
This commit is contained in:
parent
47e6a3971f
commit
b33d617717
@ -633,7 +633,20 @@ lf_advlockasync(struct vop_advlockasync_args *ap, struct lockf **statep,
|
||||
}
|
||||
|
||||
sx_xlock(&state->ls_lock);
|
||||
switch(ap->a_op) {
|
||||
/*
|
||||
* Recheck the doomed vnode after state->ls_lock is
|
||||
* locked. lf_purgelocks() requires that no new threads add
|
||||
* pending locks when vnode is marked by VI_DOOMED flag.
|
||||
*/
|
||||
VI_LOCK(vp);
|
||||
if (vp->v_iflag & VI_DOOMED) {
|
||||
VI_UNLOCK(vp);
|
||||
lf_free_lock(lock);
|
||||
return (ENOENT);
|
||||
}
|
||||
VI_UNLOCK(vp);
|
||||
|
||||
switch (ap->a_op) {
|
||||
case F_SETLK:
|
||||
error = lf_setlock(state, lock, vp, ap->a_cookiep);
|
||||
break;
|
||||
@ -755,8 +768,11 @@ lf_purgelocks(struct vnode *vp, struct lockf **statep)
|
||||
* the remaining locks.
|
||||
*/
|
||||
VI_LOCK(vp);
|
||||
KASSERT(vp->v_iflag & VI_DOOMED,
|
||||
("lf_purgelocks: vp %p has not vgone yet", vp));
|
||||
state = *statep;
|
||||
if (state) {
|
||||
*statep = NULL;
|
||||
state->ls_threads++;
|
||||
VI_UNLOCK(vp);
|
||||
|
||||
@ -789,7 +805,6 @@ lf_purgelocks(struct vnode *vp, struct lockf **statep)
|
||||
VI_LOCK(vp);
|
||||
while (state->ls_threads > 1)
|
||||
msleep(state, VI_MTX(vp), 0, "purgelocks", 0);
|
||||
*statep = 0;
|
||||
VI_UNLOCK(vp);
|
||||
|
||||
/*
|
||||
|
Loading…
x
Reference in New Issue
Block a user