svn commit: r316717 - head/sys/fs/nfsclient

Rick Macklem rmacklem at FreeBSD.org
Tue Apr 11 20:28:16 UTC 2017


Author: rmacklem
Date: Tue Apr 11 20:28:15 2017
New Revision: 316717
URL: https://svnweb.freebsd.org/changeset/base/316717

Log:
  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.
  
  Reported by:	cperciva
  Tested by:	cperciva
  PR:		216088
  MFC after:	2 weeks

Modified:
  head/sys/fs/nfsclient/nfs_clstate.c

Modified: head/sys/fs/nfsclient/nfs_clstate.c
==============================================================================
--- head/sys/fs/nfsclient/nfs_clstate.c	Tue Apr 11 19:23:25 2017	(r316716)
+++ head/sys/fs/nfsclient/nfs_clstate.c	Tue Apr 11 20:28:15 2017	(r316717)
@@ -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;


More information about the svn-src-head mailing list