git: 8f4a5fc6bc6c - main - nfscl: Do not call nfscl_hasexpired() for NFSv4.1/4.2

From: Rick Macklem <rmacklem_at_FreeBSD.org>
Date: Sun, 10 Jul 2022 20:59:38 UTC
The branch main has been updated by rmacklem:

URL: https://cgit.FreeBSD.org/src/commit/?id=8f4a5fc6bc6c4e9e0739326199d73ee4401ebd58

commit 8f4a5fc6bc6c4e9e0739326199d73ee4401ebd58
Author:     Rick Macklem <rmacklem@FreeBSD.org>
AuthorDate: 2022-07-10 20:56:38 +0000
Commit:     Rick Macklem <rmacklem@FreeBSD.org>
CommitDate: 2022-07-10 20:56:38 +0000

    nfscl: Do not call nfscl_hasexpired() for NFSv4.1/4.2
    
    Commit 981ef32230b2 enabled marking of potentially bad
    session slots when an RPC is interrupted if the "intr"
    mount option is used.  As such, it no longer makes
    sense to call nfscl_hasexpired() for I/O operations that
    reply NFSERR_BADSTATEID for NFSv4.1/4.2, which does a full
    recovery of NFSv4 open state, destroying all byte range locks.
    Recovery of open state should not be usually needed, since
    the session slot has been marked potentially bad and,
    although opens for the process that has been terminated via
    a signal may be broken, locks for other processes will still
    be valid.
    
    This patch disables calls to nfscl_hasexpired for NFSv4.1/4.2
    mounts, when I/O RPCs receive NFSERR_BADSTATEID replies.
    It does not affect the behaviour of NFSv4.0 mounts nor
    hard (non "intr") mounts.
    
    PR: 260011
    MFC after:      2 weeks
---
 sys/fs/nfsclient/nfs_clrpcops.c | 42 ++++++++++++++++++++++++++++++-----------
 1 file changed, 31 insertions(+), 11 deletions(-)

diff --git a/sys/fs/nfsclient/nfs_clrpcops.c b/sys/fs/nfsclient/nfs_clrpcops.c
index ffb81b699017..187136746e3a 100644
--- a/sys/fs/nfsclient/nfs_clrpcops.c
+++ b/sys/fs/nfsclient/nfs_clrpcops.c
@@ -1333,8 +1333,12 @@ nfsrpc_setattr(vnode_t vp, struct vattr *vap, NFSACL_T *aclp,
 		    error == NFSERR_OLDSTATEID || error == NFSERR_BADSESSION) {
 			(void) nfs_catnap(PZERO, error, "nfs_setattr");
 		} else if ((error == NFSERR_EXPIRED ||
-		    error == NFSERR_BADSTATEID) && clidrev != 0) {
+		    ((!NFSHASINT(nmp) || !NFSHASNFSV4N(nmp)) &&
+		    error == NFSERR_BADSTATEID)) && clidrev != 0) {
 			expireret = nfscl_hasexpired(nmp->nm_clp, clidrev, p);
+		} else if (error == NFSERR_BADSTATEID && NFSHASINT(nmp) &&
+		    NFSHASNFSV4N(nmp)) {
+			error = EIO;
 		}
 		retrycnt++;
 	} while (error == NFSERR_GRACE || error == NFSERR_STALESTATEID ||
@@ -1732,8 +1736,12 @@ nfsrpc_read(vnode_t vp, struct uio *uiop, struct ucred *cred,
 		    error == NFSERR_OLDSTATEID || error == NFSERR_BADSESSION) {
 			(void) nfs_catnap(PZERO, error, "nfs_read");
 		} else if ((error == NFSERR_EXPIRED ||
-		    error == NFSERR_BADSTATEID) && clidrev != 0) {
+		    ((!NFSHASINT(nmp) || !NFSHASNFSV4N(nmp)) &&
+		    error == NFSERR_BADSTATEID)) && clidrev != 0) {
 			expireret = nfscl_hasexpired(nmp->nm_clp, clidrev, p);
+		} else if (error == NFSERR_BADSTATEID && NFSHASINT(nmp) &&
+		    NFSHASNFSV4N(nmp)) {
+			error = EIO;
 		}
 		retrycnt++;
 	} while (error == NFSERR_GRACE || error == NFSERR_STALESTATEID ||
@@ -1904,8 +1912,12 @@ nfsrpc_write(vnode_t vp, struct uio *uiop, int *iomode, int *must_commit,
 		    error == NFSERR_OLDSTATEID || error == NFSERR_BADSESSION) {
 			(void) nfs_catnap(PZERO, error, "nfs_write");
 		} else if ((error == NFSERR_EXPIRED ||
-		    error == NFSERR_BADSTATEID) && clidrev != 0) {
+		    ((!NFSHASINT(nmp) || !NFSHASNFSV4N(nmp)) &&
+		    error == NFSERR_BADSTATEID)) && clidrev != 0) {
 			expireret = nfscl_hasexpired(nmp->nm_clp, clidrev, p);
+		} else if (error == NFSERR_BADSTATEID && NFSHASINT(nmp) &&
+		    NFSHASNFSV4N(nmp)) {
+			error = EIO;
 		}
 		retrycnt++;
 	} while (error == NFSERR_GRACE || error == NFSERR_DELAY ||
@@ -2196,9 +2208,11 @@ nfsrpc_deallocate(vnode_t vp, off_t offs, off_t len, struct nfsvattr *nap,
 		    error == NFSERR_STALEDONTRECOVER || error == NFSERR_DELAY ||
 		    error == NFSERR_OLDSTATEID || error == NFSERR_BADSESSION) {
 			(void) nfs_catnap(PZERO, error, "nfs_deallocate");
-		} else if ((error == NFSERR_EXPIRED ||
-		    error == NFSERR_BADSTATEID) && clidrev != 0) {
+		} else if ((error == NFSERR_EXPIRED || (!NFSHASINT(nmp) &&
+		    error == NFSERR_BADSTATEID)) && clidrev != 0) {
 			expireret = nfscl_hasexpired(nmp->nm_clp, clidrev, p);
+		} else if (error == NFSERR_BADSTATEID && NFSHASINT(nmp)) {
+			error = EIO;
 		}
 		retrycnt++;
 	} while (error == NFSERR_GRACE || error == NFSERR_STALESTATEID ||
@@ -7415,9 +7429,11 @@ nfsrpc_allocate(vnode_t vp, off_t off, off_t len, struct nfsvattr *nap,
 		    error == NFSERR_STALEDONTRECOVER || error == NFSERR_DELAY ||
 		    error == NFSERR_OLDSTATEID || error == NFSERR_BADSESSION) {
 			(void) nfs_catnap(PZERO, error, "nfs_allocate");
-		} else if ((error == NFSERR_EXPIRED ||
-		    error == NFSERR_BADSTATEID) && clidrev != 0) {
+		} else if ((error == NFSERR_EXPIRED || (!NFSHASINT(nmp) &&
+		    error == NFSERR_BADSTATEID)) && clidrev != 0) {
 			expireret = nfscl_hasexpired(nmp->nm_clp, clidrev, p);
+		} else if (error == NFSERR_BADSTATEID && NFSHASINT(nmp)) {
+			error = EIO;
 		}
 		retrycnt++;
 	} while (error == NFSERR_GRACE || error == NFSERR_DELAY ||
@@ -8515,10 +8531,12 @@ nfsrpc_copy_file_range(vnode_t invp, off_t *inoffp, vnode_t outvp,
 		    error == NFSERR_STALEDONTRECOVER || error == NFSERR_DELAY ||
 		    error == NFSERR_OLDSTATEID || error == NFSERR_BADSESSION) {
 			(void) nfs_catnap(PZERO, error, "nfs_cfr");
-		} else if ((error == NFSERR_EXPIRED ||
-		    error == NFSERR_BADSTATEID) && clidrev != 0) {
+		} else if ((error == NFSERR_EXPIRED || (!NFSHASINT(nmp) &&
+		    error == NFSERR_BADSTATEID)) && clidrev != 0) {
 			expireret = nfscl_hasexpired(nmp->nm_clp, clidrev,
 			    curthread);
+		} else if (error == NFSERR_BADSTATEID && NFSHASINT(nmp)) {
+			error = EIO;
 		}
 		retrycnt++;
 	} while (error == NFSERR_GRACE || error == NFSERR_DELAY ||
@@ -8692,10 +8710,12 @@ nfsrpc_seek(vnode_t vp, off_t *offp, bool *eofp, int content,
 		    error == NFSERR_STALEDONTRECOVER || error == NFSERR_DELAY ||
 		    error == NFSERR_OLDSTATEID || error == NFSERR_BADSESSION) {
 			(void) nfs_catnap(PZERO, error, "nfs_seek");
-		} else if ((error == NFSERR_EXPIRED ||
-		    error == NFSERR_BADSTATEID) && clidrev != 0) {
+		} else if ((error == NFSERR_EXPIRED || (!NFSHASINT(nmp) &&
+		    error == NFSERR_BADSTATEID)) && clidrev != 0) {
 			expireret = nfscl_hasexpired(nmp->nm_clp, clidrev,
 			    curthread);
+		} else if (error == NFSERR_BADSTATEID && NFSHASINT(nmp)) {
+			error = EIO;
 		}
 		retrycnt++;
 	} while (error == NFSERR_GRACE || error == NFSERR_STALESTATEID ||