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));
 }
_______________________________________________
svn-src-all@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to