Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 26 Jun 2016 13:18:03 +0000 (UTC)
From:      Konstantin Belousov <kib@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org
Subject:   svn commit: r302209 - stable/10/sys/nlm
Message-ID:  <201606261318.u5QDI3EV079832@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
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));
 }



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201606261318.u5QDI3EV079832>