Author: rmacklem
Date: Wed Apr 26 22:53:29 2017
New Revision: 317474
URL: https://svnweb.freebsd.org/changeset/base/317474

Log:
  MFC: r316717
  During a server crash recovery, fix the NFSv4.1 client for a NFSERR_BADSESSION
  during recovery.
  
  If the NFSv4.1 client gets a NFSv4.1 NFSERR_BADSESSION reply to an Open/Lock
  operation while recovering from the server crash/reboot, allow the opens
  to be retained for a subsequent recovery attempt. Since NFSv4.1 servers
  should only reply NFSERR_BADSESSION after a crash/reboot that has lost
  state, this case should almost never happen.
  However, for the AmazonEFS file service, this has been observed when
  the client does a fresh TCP connection for RPCs.

Modified:
  stable/10/sys/fs/nfsclient/nfs_clstate.c
Directory Properties:
  stable/10/   (props changed)

Modified: stable/10/sys/fs/nfsclient/nfs_clstate.c
==============================================================================
--- stable/10/sys/fs/nfsclient/nfs_clstate.c    Wed Apr 26 22:40:08 2017        
(r317473)
+++ stable/10/sys/fs/nfsclient/nfs_clstate.c    Wed Apr 26 22:53:29 2017        
(r317474)
@@ -1981,7 +1981,7 @@ nfscl_recover(struct nfsclclient *clp, s
            op = LIST_FIRST(&owp->nfsow_open);
            while (op != NULL) {
                nop = LIST_NEXT(op, nfso_list);
-               if (error != NFSERR_NOGRACE) {
+               if (error != NFSERR_NOGRACE && error != NFSERR_BADSESSION) {
                    /* Search for a delegation to reclaim with the open */
                    TAILQ_FOREACH(dp, &clp->nfsc_deleg, nfsdl_list) {
                        if (!(dp->nfsdl_flags & NFSCLDL_NEEDRECLAIM))
@@ -2050,11 +2050,10 @@ nfscl_recover(struct nfsclclient *clp, s
                                    len = NFS64BITSSET;
                                else
                                    len = lop->nfslo_end - lop->nfslo_first;
-                               if (error != NFSERR_NOGRACE)
-                                   error = nfscl_trylock(nmp, NULL,
-                                       op->nfso_fh, op->nfso_fhlen, lp,
-                                       firstlock, 1, lop->nfslo_first, len,
-                                       lop->nfslo_type, tcred, p);
+                               error = nfscl_trylock(nmp, NULL,
+                                   op->nfso_fh, op->nfso_fhlen, lp,
+                                   firstlock, 1, lop->nfslo_first, len,
+                                   lop->nfslo_type, tcred, p);
                                if (error != 0)
                                    nfscl_freelock(lop, 0);
                                else
@@ -2066,10 +2065,10 @@ nfscl_recover(struct nfsclclient *clp, s
                                nfscl_freelockowner(lp, 0);
                            lp = nlp;
                        }
-                   } else {
-                       nfscl_freeopen(op, 0);
                    }
                }
+               if (error != 0 && error != NFSERR_BADSESSION)
+                   nfscl_freeopen(op, 0);
                op = nop;
            }
            owp = nowp;
@@ -2100,7 +2099,7 @@ nfscl_recover(struct nfsclclient *clp, s
                    nfscl_lockinit(&nowp->nfsow_rwlock);
                }
                nop = NULL;
-               if (error != NFSERR_NOGRACE) {
+               if (error != NFSERR_NOGRACE && error != NFSERR_BADSESSION) {
                    MALLOC(nop, struct nfsclopen *, sizeof (struct nfsclopen) +
                        dp->nfsdl_fhlen - 1, M_NFSCLOPEN, M_WAITOK);
                    nop->nfso_own = nowp;
_______________________________________________
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