svn commit: r302209 - stable/10/sys/nlm
Konstantin Belousov
kib at FreeBSD.org
Sun Jun 26 13:18:05 UTC 2016
Author: kib
Date: Sun Jun 26 13:18:03 2016
New Revision: 302209
URL: https://svnweb.freebsd.org/changeset/base/302209
Log:
MFC r302020:
Handle EDEADLK and EINTR from local adv lock manager.
Modified:
stable/10/sys/nlm/nlm_advlock.c
Directory Properties:
stable/10/ (props changed)
Modified: stable/10/sys/nlm/nlm_advlock.c
==============================================================================
--- stable/10/sys/nlm/nlm_advlock.c Sun Jun 26 13:16:02 2016 (r302208)
+++ stable/10/sys/nlm/nlm_advlock.c Sun Jun 26 13:18:03 2016 (r302209)
@@ -713,7 +713,37 @@ nlm_record_lock(struct vnode *vp, int op
newfl.l_pid = svid;
newfl.l_sysid = NLM_SYSID_CLIENT | sysid;
- error = lf_advlockasync(&a, &vp->v_lockf, size);
+ for (;;) {
+ error = lf_advlockasync(&a, &vp->v_lockf, size);
+ if (error == EDEADLK) {
+ /*
+ * Locks are associated with the processes and
+ * not with threads. Suppose we have two
+ * threads A1 A2 in one process, A1 locked
+ * file f1, A2 is locking file f2, and A1 is
+ * unlocking f1. Then remote server may
+ * already unlocked f1, while local still not
+ * yet scheduled A1 to make the call to local
+ * advlock manager. The process B owns lock on
+ * f2 and issued the lock on f1. Remote would
+ * grant B the request on f1, but local would
+ * return EDEADLK.
+ */
+ pause("nlmdlk", 1);
+ /* XXXKIB allow suspend */
+ } else if (error == EINTR) {
+ /*
+ * lf_purgelocks() might wake up the lock
+ * waiter and removed our lock graph edges.
+ * There is no sense in re-trying recording
+ * the lock to the local manager after
+ * reclaim.
+ */
+ error = 0;
+ break;
+ } else
+ break;
+ }
KASSERT(error == 0 || error == ENOENT,
("Failed to register NFS lock locally - error=%d", error));
}
More information about the svn-src-stable-10
mailing list