Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 22 Apr 2021 14:03:32 GMT
From:      Rick Macklem <rmacklem@FreeBSD.org>
To:        src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-branches@FreeBSD.org
Subject:   git: a47c2ca8ae6a - stable/12 - nfsd: fix replies from session cache for retried RPCs
Message-ID:  <202104221403.13ME3Wkn027843@gitrepo.freebsd.org>

next in thread | raw e-mail | index | archive | help
The branch stable/12 has been updated by rmacklem:

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

commit a47c2ca8ae6ab5065ca625fbad41bd642eba1105
Author:     Rick Macklem <rmacklem@FreeBSD.org>
AuthorDate: 2021-04-08 21:04:22 +0000
Commit:     Rick Macklem <rmacklem@FreeBSD.org>
CommitDate: 2021-04-22 13:59:34 +0000

    nfsd: fix replies from session cache for retried RPCs
    
    Recent testing of network partitioning a FreeBSD NFSv4.1
    server from a Linux NFSv4.1 client identified problems
    with both the FreeBSD server and Linux client.
    
    The FreeBSD server failec to reply using the cached
    reply in the session slot when an RPC was retried on
    the session slot, as indicated by same slot sequence#.
    
    This patch fixes this.  It should also fix a similar
    failure for NFSv4.0 mounts, when the sequence# in
    the open/lock_owner requires a reply be done from
    an entry locked into the DRC.
    
    This fix affects the fairly rare case where a NFSv4
    client retries a non-idempotent RPC, such as a lock
    operation.  Note that retries only occur after the
    client has needed to create a new TCP connection.
    
    (cherry picked from commit 05a39c2c1c18cd0c4382a4f58e0952d3f77e7dfa)
---
 sys/fs/nfsserver/nfs_nfsdkrpc.c | 7 ++++++-
 sys/fs/nfsserver/nfs_nfsdsubs.c | 2 ++
 2 files changed, 8 insertions(+), 1 deletion(-)

diff --git a/sys/fs/nfsserver/nfs_nfsdkrpc.c b/sys/fs/nfsserver/nfs_nfsdkrpc.c
index 566c5260ed09..e727dc4127c0 100644
--- a/sys/fs/nfsserver/nfs_nfsdkrpc.c
+++ b/sys/fs/nfsserver/nfs_nfsdkrpc.c
@@ -395,8 +395,13 @@ nfs_proc(struct nfsrv_descript *nd, u_int32_t xid, SVCXPRT *xprt,
 				m = NULL;
 			if ((nd->nd_flag & ND_HASSEQUENCE) != 0)
 				nfsrv_cache_session(nd, &m);
-			if (nd->nd_repstat == NFSERR_REPLYFROMCACHE)
+			if (nd->nd_repstat == NFSERR_REPLYFROMCACHE) {
 				nd->nd_repstat = 0;
+				if (m != NULL) {
+					m_freem(nd->nd_mreq);
+					nd->nd_mreq = m;
+				}
+			}
 			cacherep = RC_REPLY;
 		} else {
 			if (nd->nd_repstat == NFSERR_DONTREPLY)
diff --git a/sys/fs/nfsserver/nfs_nfsdsubs.c b/sys/fs/nfsserver/nfs_nfsdsubs.c
index b90d0b586ef4..9ab5ca174b29 100644
--- a/sys/fs/nfsserver/nfs_nfsdsubs.c
+++ b/sys/fs/nfsserver/nfs_nfsdsubs.c
@@ -1515,6 +1515,8 @@ nfsd_errmap(struct nfsrv_descript *nd)
 		else if (nd->nd_repstat == NFSERR_MINORVERMISMATCH ||
 			 nd->nd_repstat == NFSERR_OPILLEGAL)
 			return (txdr_unsigned(nd->nd_repstat));
+		else if (nd->nd_repstat == NFSERR_REPLYFROMCACHE)
+			return (txdr_unsigned(NFSERR_IO));
 		else if ((nd->nd_flag & ND_NFSV41) != 0) {
 			if (nd->nd_repstat == EOPNOTSUPP)
 				nd->nd_repstat = NFSERR_NOTSUPP;



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202104221403.13ME3Wkn027843>