Correct the problem reported by test16 from
tools/regression/file/flock/flock.c, which completes the fix in r192685. When the lock was stolen from us, retry the whole lock sequence in kernel, instead of returning EINTR to usermode and hoping that application would handle it correctly by restarting the lock acquire. Tested by: pho Sponsored by: The FreeBSD Foundation MFC after: 2 weeks
This commit is contained in:
@@ -469,6 +469,9 @@ lf_advlockasync(struct vop_advlockasync_args *ap, struct lockf **statep,
|
||||
return (EOVERFLOW);
|
||||
end = start + oadd;
|
||||
}
|
||||
|
||||
retry_setlock:
|
||||
|
||||
/*
|
||||
* Avoid the common case of unlocking when inode has no locks.
|
||||
*/
|
||||
@@ -744,6 +747,11 @@ lf_advlockasync(struct vop_advlockasync_args *ap, struct lockf **statep,
|
||||
sx_destroy(&freestate->ls_lock);
|
||||
free(freestate, M_LOCKF);
|
||||
}
|
||||
|
||||
if (error == EDOOFUS) {
|
||||
KASSERT(ap->a_op == F_SETLK, ("EDOOFUS"));
|
||||
goto retry_setlock;
|
||||
}
|
||||
return (error);
|
||||
}
|
||||
|
||||
@@ -1459,7 +1467,7 @@ lf_setlock(struct lockf *state, struct lockf_entry *lock, struct vnode *vp,
|
||||
lock->lf_refs++;
|
||||
error = sx_sleep(lock, &state->ls_lock, priority, lockstr, 0);
|
||||
if (lf_free_lock(lock)) {
|
||||
error = EINTR;
|
||||
error = EDOOFUS;
|
||||
goto out;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user