svn commit: r302020 - head/sys/nlm
Konstantin Belousov
kib at FreeBSD.org
Sun Jun 19 18:32:37 UTC 2016
Author: kib
Date: Sun Jun 19 18:32:35 2016
New Revision: 302020
URL: https://svnweb.freebsd.org/changeset/base/302020
Log:
Remote and local adv lock servers might de-synchronize (the added comment
explains the plausible scenario), resulting in EDEADLK returned on the
local registration attempt. Handle this by re-trying the local op [1].
On unmount, local registration abort is indicated as EINTR, abort the nlm
call as well.
Reported and tested by: pho
Suggested and reviewed by: dfr (previous version, [1])
Sponsored by: The FreeBSD Foundation
MFC after: 1 week
Approved by: re (delphij)
Modified:
head/sys/nlm/nlm_advlock.c
Modified: head/sys/nlm/nlm_advlock.c
==============================================================================
--- head/sys/nlm/nlm_advlock.c Sun Jun 19 18:29:43 2016 (r302019)
+++ head/sys/nlm/nlm_advlock.c Sun Jun 19 18:32:35 2016 (r302020)
@@ -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-all
mailing list