From: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
To: linux-kernel@vger.kernel.org
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
stable@vger.kernel.org, Olga Kornievskaia <aglo@umich.edu>,
"J. Bruce Fields" <bfields@redhat.com>,
Salvatore Bonaccorso <carnil@debian.org>
Subject: [PATCH 4.9 17/24] nfsd4: fix cached replies to solo SEQUENCE compounds
Date: Wed, 13 Feb 2019 19:38:14 +0100 [thread overview]
Message-ID: <20190213183648.825258358@linuxfoundation.org> (raw)
In-Reply-To: <20190213183647.333441569@linuxfoundation.org>
4.9-stable review patch. If anyone has any objections, please let me know.
------------------
From: J. Bruce Fields <bfields@redhat.com>
commit 085def3ade52f2ffe3e31f42e98c27dcc222dd37 upstream.
Currently our handling of 4.1+ requests without "cachethis" set is
confusing and not quite correct.
Suppose a client sends a compound consisting of only a single SEQUENCE
op, and it matches the seqid in a session slot (so it's a retry), but
the previous request with that seqid did not have "cachethis" set.
The obvious thing to do might be to return NFS4ERR_RETRY_UNCACHED_REP,
but the protocol only allows that to be returned on the op following the
SEQUENCE, and there is no such op in this case.
The protocol permits us to cache replies even if the client didn't ask
us to. And it's easy to do so in the case of solo SEQUENCE compounds.
So, when we get a solo SEQUENCE, we can either return the previously
cached reply or NFSERR_SEQ_FALSE_RETRY if we notice it differs in some
way from the original call.
Currently, we're returning a corrupt reply in the case a solo SEQUENCE
matches a previous compound with more ops. This actually matters
because the Linux client recently started doing this as a way to recover
from lost replies to idempotent operations in the case the process doing
the original reply was killed: in that case it's difficult to keep the
original arguments around to do a real retry, and the client no longer
cares what the result is anyway, but it would like to make sure that the
slot's sequence id has been incremented, and the solo SEQUENCE assures
that: if the server never got the original reply, it will increment the
sequence id. If it did get the original reply, it won't increment, and
nothing else that about the reply really matters much. But we can at
least attempt to return valid xdr!
Tested-by: Olga Kornievskaia <aglo@umich.edu>
Signed-off-by: J. Bruce Fields <bfields@redhat.com>
Cc: Salvatore Bonaccorso <carnil@debian.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
fs/nfsd/nfs4state.c | 20 +++++++++++++++-----
fs/nfsd/state.h | 1 +
fs/nfsd/xdr4.h | 13 +++++++++++--
3 files changed, 27 insertions(+), 7 deletions(-)
--- a/fs/nfsd/nfs4state.c
+++ b/fs/nfsd/nfs4state.c
@@ -2344,14 +2344,16 @@ nfsd4_store_cache_entry(struct nfsd4_com
dprintk("--> %s slot %p\n", __func__, slot);
+ slot->sl_flags |= NFSD4_SLOT_INITIALIZED;
slot->sl_opcnt = resp->opcnt;
slot->sl_status = resp->cstate.status;
- slot->sl_flags |= NFSD4_SLOT_INITIALIZED;
- if (nfsd4_not_cached(resp)) {
- slot->sl_datalen = 0;
+ if (!nfsd4_cache_this(resp)) {
+ slot->sl_flags &= ~NFSD4_SLOT_CACHED;
return;
}
+ slot->sl_flags |= NFSD4_SLOT_CACHED;
+
base = resp->cstate.data_offset;
slot->sl_datalen = buf->len - base;
if (read_bytes_from_xdr_buf(buf, base, slot->sl_data, slot->sl_datalen))
@@ -2378,8 +2380,16 @@ nfsd4_enc_sequence_replay(struct nfsd4_c
op = &args->ops[resp->opcnt - 1];
nfsd4_encode_operation(resp, op);
- /* Return nfserr_retry_uncached_rep in next operation. */
- if (args->opcnt > 1 && !(slot->sl_flags & NFSD4_SLOT_CACHETHIS)) {
+ if (slot->sl_flags & NFSD4_SLOT_CACHED)
+ return op->status;
+ if (args->opcnt == 1) {
+ /*
+ * The original operation wasn't a solo sequence--we
+ * always cache those--so this retry must not match the
+ * original:
+ */
+ op->status = nfserr_seq_false_retry;
+ } else {
op = &args->ops[resp->opcnt++];
op->status = nfserr_retry_uncached_rep;
nfsd4_encode_operation(resp, op);
--- a/fs/nfsd/state.h
+++ b/fs/nfsd/state.h
@@ -174,6 +174,7 @@ struct nfsd4_slot {
#define NFSD4_SLOT_INUSE (1 << 0)
#define NFSD4_SLOT_CACHETHIS (1 << 1)
#define NFSD4_SLOT_INITIALIZED (1 << 2)
+#define NFSD4_SLOT_CACHED (1 << 3)
u8 sl_flags;
char sl_data[];
};
--- a/fs/nfsd/xdr4.h
+++ b/fs/nfsd/xdr4.h
@@ -645,9 +645,18 @@ static inline bool nfsd4_is_solo_sequenc
return resp->opcnt == 1 && args->ops[0].opnum == OP_SEQUENCE;
}
-static inline bool nfsd4_not_cached(struct nfsd4_compoundres *resp)
+/*
+ * The session reply cache only needs to cache replies that the client
+ * actually asked us to. But it's almost free for us to cache compounds
+ * consisting of only a SEQUENCE op, so we may as well cache those too.
+ * Also, the protocol doesn't give us a convenient response in the case
+ * of a replay of a solo SEQUENCE op that wasn't cached
+ * (RETRY_UNCACHED_REP can only be returned in the second op of a
+ * compound).
+ */
+static inline bool nfsd4_cache_this(struct nfsd4_compoundres *resp)
{
- return !(resp->cstate.slot->sl_flags & NFSD4_SLOT_CACHETHIS)
+ return (resp->cstate.slot->sl_flags & NFSD4_SLOT_CACHETHIS)
|| nfsd4_is_solo_sequence(resp);
}
next prev parent reply other threads:[~2019-02-13 18:56 UTC|newest]
Thread overview: 30+ messages / expand[flat|nested] mbox.gz Atom feed top
2019-02-13 18:37 [PATCH 4.9 00/24] 4.9.157-stable review Greg Kroah-Hartman
2019-02-13 18:37 ` [PATCH 4.9 01/24] mtd: rawnand: gpmi: fix MX28 bus master lockup problem Greg Kroah-Hartman
2019-02-13 18:37 ` [PATCH 4.9 02/24] iio: chemical: atlas-ph-sensor: correct IIO_TEMP values to millicelsius Greg Kroah-Hartman
2019-02-13 18:38 ` [PATCH 4.9 03/24] signal: Always notice exiting tasks Greg Kroah-Hartman
2019-02-13 18:38 ` [PATCH 4.9 04/24] signal: Better detection of synchronous signals Greg Kroah-Hartman
2019-02-13 18:38 ` [PATCH 4.9 05/24] misc: vexpress: Off by one in vexpress_syscfg_exec() Greg Kroah-Hartman
2019-02-13 18:38 ` [PATCH 4.9 06/24] samples: mei: use /dev/mei0 instead of /dev/mei Greg Kroah-Hartman
2019-02-13 18:38 ` [PATCH 4.9 07/24] debugfs: fix debugfs_rename parameter checking Greg Kroah-Hartman
2019-02-13 18:38 ` [PATCH 4.9 08/24] mips: cm: reprime error cause Greg Kroah-Hartman
2019-02-13 18:38 ` [PATCH 4.9 09/24] MIPS: OCTEON: dont set octeon_dma_bar_type if PCI is disabled Greg Kroah-Hartman
2019-02-13 18:38 ` [PATCH 4.9 10/24] MIPS: VDSO: Include $(ccflags-vdso) in o32,n32 .lds builds Greg Kroah-Hartman
2019-02-13 18:38 ` [PATCH 4.9 11/24] ARM: iop32x/n2100: fix PCI IRQ mapping Greg Kroah-Hartman
2019-02-13 18:38 ` [PATCH 4.9 12/24] ARM: tango: Improve ARCH_MULTIPLATFORM compatibility Greg Kroah-Hartman
2019-02-13 18:38 ` [PATCH 4.9 13/24] mac80211: ensure that mgmt tx skbs have tailroom for encryption Greg Kroah-Hartman
2019-02-13 18:38 ` [PATCH 4.9 14/24] drm/modes: Prevent division by zero htotal Greg Kroah-Hartman
2019-02-13 18:38 ` [PATCH 4.9 15/24] drm/vmwgfx: Fix setting of dma masks Greg Kroah-Hartman
2019-02-13 18:38 ` [PATCH 4.9 16/24] drm/vmwgfx: Return error code from vmw_execbuf_copy_fence_user Greg Kroah-Hartman
2019-02-13 18:38 ` Greg Kroah-Hartman [this message]
2019-02-13 18:38 ` [PATCH 4.9 18/24] nfsd4: catch some false session retries Greg Kroah-Hartman
2019-02-13 18:38 ` [PATCH 4.9 19/24] HID: debug: fix the ring buffer implementation Greg Kroah-Hartman
2019-02-13 18:38 ` [PATCH 4.9 20/24] Revert "cifs: In Kconfig CONFIG_CIFS_POSIX needs depends on legacy (insecure cifs)" Greg Kroah-Hartman
2019-02-13 18:38 ` [PATCH 4.9 21/24] libceph: avoid KEEPALIVE_PENDING races in ceph_con_keepalive() Greg Kroah-Hartman
2019-02-13 18:38 ` [PATCH 4.9 22/24] xfrm: refine validation of template and selector families Greg Kroah-Hartman
2019-02-13 18:38 ` [PATCH 4.9 23/24] batman-adv: Avoid WARN on net_device without parent in netns Greg Kroah-Hartman
2019-02-13 18:38 ` [PATCH 4.9 24/24] batman-adv: Force mac header to start of data on xmit Greg Kroah-Hartman
2019-02-14 3:39 ` [PATCH 4.9 00/24] 4.9.157-stable review kernelci.org bot
2019-02-14 10:04 ` Jon Hunter
2019-02-14 16:30 ` Dan Rue
2019-02-14 19:16 ` Guenter Roeck
2019-02-14 22:22 ` shuah
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20190213183648.825258358@linuxfoundation.org \
--to=gregkh@linuxfoundation.org \
--cc=aglo@umich.edu \
--cc=bfields@redhat.com \
--cc=carnil@debian.org \
--cc=linux-kernel@vger.kernel.org \
--cc=stable@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).