diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c index 88f6c0a0d8b3..db79eba61bbf 100644 --- a/fs/nfsd/nfs4state.c +++ b/fs/nfsd/nfs4state.c @@ -5170,6 +5170,7 @@ nfsd4_sequence(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, slot->sl_flags &= ~NFSD4_SLOT_CACHETHIS; cstate->slot = slot; + cstate->slot_owned = true; cstate->session = session; cstate->clp = clp; @@ -5244,7 +5245,11 @@ nfsd4_sequence_done(struct nfsd4_compoundres *resp) struct nfsd4_compound_state *cs = &resp->cstate; if (nfsd4_has_session(cs)) { - if (cs->status != nfserr_replay_cache) { + /* + * Only the request that claimed the slot may update its + * cached reply and clear NFSD4_SLOT_INUSE. + */ + if (cs->slot_owned) { nfsd4_store_cache_entry(resp); cs->slot->sl_flags &= ~NFSD4_SLOT_INUSE; } diff --git a/fs/nfsd/xdr4.h b/fs/nfsd/xdr4.h index de43a0da9668..ec198993429e 100644 --- a/fs/nfsd/xdr4.h +++ b/fs/nfsd/xdr4.h @@ -62,6 +62,7 @@ struct nfsd4_compound_state { struct nfsd4_slot *slot; int data_offset; bool spo_must_allowed; + bool slot_owned; size_t iovlen; u32 minorversion; __be32 status;