Print this page
8040 NFSv4 client: 3-way deadlock between nfs4_bio(), nfs4_do_delegreturn(), and nfs4_flush_pages()
Reviewed by: Arne Jansen <arne@die-jansens.de>
Reviewed by: Vitaliy Gusev <gusev.vitaliy@icloud.com>
Approved by: Gordon Ross <gordon.w.ross@gmail.com>

@@ -462,39 +462,21 @@
         mutex_exit(&mi->mi_lock);
 
         rp = VTOR4(vp);
         mutex_enter(&rp->r_statelock);
         was_serial = (rp->r_serial == curthread);
-        if (rp->r_serial && !was_serial) {
-                klwp_t *lwp = ttolwp(curthread);
-
+        if (rp->r_serial != NULL && !was_serial) {
                 /*
-                 * If we're the recovery thread, then purge current attrs
-                 * and bail out to avoid potential deadlock between another
-                 * thread caching attrs (r_serial thread), recov thread,
-                 * and an async writer thread.
+                 * Purge current attrs and bail out to avoid potential deadlock
+                 * between another thread caching attrs (r_serial thread), this
+                 * thread, and a thread trying to read or write pages.
                  */
-                if (recov) {
                         PURGE_ATTRCACHE4_LOCKED(rp);
                         mutex_exit(&rp->r_statelock);
                         return;
                 }
 
-                if (lwp != NULL)
-                        lwp->lwp_nostop++;
-                while (rp->r_serial != NULL) {
-                        if (!cv_wait_sig(&rp->r_cv, &rp->r_statelock)) {
-                                mutex_exit(&rp->r_statelock);
-                                if (lwp != NULL)
-                                        lwp->lwp_nostop--;
-                                return;
-                        }
-                }
-                if (lwp != NULL)
-                        lwp->lwp_nostop--;
-        }
-
         /*
          * If there is a page flush thread, the current thread needs to
          * bail out, to prevent a possible deadlock between the current
          * thread (which might be in a start_op/end_op region), the
          * recovery thread, and the page flush thread.  Expire the