From owner-dev-commits-src-all@freebsd.org Tue Apr 27 23:19:39 2021 Return-Path: Delivered-To: dev-commits-src-all@mailman.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mailman.nyi.freebsd.org (Postfix) with ESMTP id 074ED6252C3; Tue, 27 Apr 2021 23:19:39 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "R3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4FVHlt6ng8z3Gfl; Tue, 27 Apr 2021 23:19:38 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id DBFA023707; Tue, 27 Apr 2021 23:19:38 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org ([127.0.1.44]) by gitrepo.freebsd.org (8.16.1/8.16.1) with ESMTP id 13RNJcHV045120; Tue, 27 Apr 2021 23:19:38 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.16.1/8.16.1/Submit) id 13RNJc6M045119; Tue, 27 Apr 2021 23:19:38 GMT (envelope-from git) Date: Tue, 27 Apr 2021 23:19:38 GMT Message-Id: <202104272319.13RNJc6M045119@gitrepo.freebsd.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-branches@FreeBSD.org From: Rick Macklem Subject: git: b2cb7574420e - stable/11 - nfsd: fix replies from session cache for multiple retries MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: rmacklem X-Git-Repository: src X-Git-Refname: refs/heads/stable/11 X-Git-Reftype: branch X-Git-Commit: b2cb7574420ed01f7b3ef99cade7b5dd935b9890 Auto-Submitted: auto-generated X-BeenThere: dev-commits-src-all@freebsd.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: Commit messages for all branches of the src repository List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 27 Apr 2021 23:19:39 -0000 The branch stable/11 has been updated by rmacklem: URL: https://cgit.FreeBSD.org/src/commit/?id=b2cb7574420ed01f7b3ef99cade7b5dd935b9890 commit b2cb7574420ed01f7b3ef99cade7b5dd935b9890 Author: Rick Macklem AuthorDate: 2021-04-10 22:50:25 +0000 Commit: Rick Macklem CommitDate: 2021-04-27 23:16:07 +0000 nfsd: fix replies from session cache for multiple retries 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. Commit 05a39c2c1c18 fixed replying with the cached reply in in the session slot if same session slot sequence#. However, the code uses the reply and, as such, will fail for a subsequent retry of the RPC. A subsequent retry would be an extremely rare event, but this patch fixes this, so long as m_copym(..M_NOWAIT) does not fail, which should also be a rare event. This fix affects the exceedingly rare case where a NFSv4 client retries a non-idempotent RPC, such as a lock operation, multiple times. Note that retries only occur after the client has needed to create a new TCP connection, with a new TCP connection for each retry. (cherry picked from commit 22cefe3d8378f58adcdbb2c7589b9f30c2a38315) --- sys/fs/nfs/nfs_commonsubs.c | 34 ++++++++++++++++++++++++++++++---- 1 file changed, 30 insertions(+), 4 deletions(-) diff --git a/sys/fs/nfs/nfs_commonsubs.c b/sys/fs/nfs/nfs_commonsubs.c index 03f1676ecd6d..096614565a5e 100644 --- a/sys/fs/nfs/nfs_commonsubs.c +++ b/sys/fs/nfs/nfs_commonsubs.c @@ -4145,6 +4145,7 @@ int nfsv4_seqsession(uint32_t seqid, uint32_t slotid, uint32_t highslot, struct nfsslot *slots, struct mbuf **reply, uint16_t maxslot) { + struct mbuf *m; int error; error = 0; @@ -4158,8 +4159,14 @@ nfsv4_seqsession(uint32_t seqid, uint32_t slotid, uint32_t highslot, error = NFSERR_DELAY; else if (slots[slotid].nfssl_reply != NULL) { if (reply != NULL) { - *reply = slots[slotid].nfssl_reply; - slots[slotid].nfssl_reply = NULL; + m = m_copym(slots[slotid].nfssl_reply, 0, + M_COPYALL, M_NOWAIT); + if (m != NULL) + *reply = m; + else { + *reply = slots[slotid].nfssl_reply; + slots[slotid].nfssl_reply = NULL; + } } slots[slotid].nfssl_inprog = 1; error = NFSERR_REPLYFROMCACHE; @@ -4186,10 +4193,29 @@ void nfsv4_seqsess_cacherep(uint32_t slotid, struct nfsslot *slots, int repstat, struct mbuf **rep) { + struct mbuf *m; if (repstat == NFSERR_REPLYFROMCACHE) { - *rep = slots[slotid].nfssl_reply; - slots[slotid].nfssl_reply = NULL; + if (slots[slotid].nfssl_reply != NULL) { + /* + * We cannot sleep here, but copy will usually + * succeed. + */ + m = m_copym(slots[slotid].nfssl_reply, 0, M_COPYALL, + M_NOWAIT); + if (m != NULL) + *rep = m; + else { + /* + * Multiple retries would be extremely rare, + * so using the cached reply will likely + * be ok. + */ + *rep = slots[slotid].nfssl_reply; + slots[slotid].nfssl_reply = NULL; + } + } else + *rep = NULL; } else { if (slots[slotid].nfssl_reply != NULL) m_freem(slots[slotid].nfssl_reply);