Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

nfsd: stop pretending that we cache the SEQUENCE reply.

nfsd does not cache the reply to a SEQUENCE. As the comment above
nfsd4_replay_cache_entry() says:

* The sequence operation is not cached because we can use the slot and
* session values.

The comment above nfsd4_cache_this() suggests otherwise.

* 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

The code in nfsd4_store_cache_entry() makes it clear that only responses
beyond 'cstate.data_offset' are actually cached, and data_offset is set
at the end of nfsd4_encode_sequence() *after* the sequence response has
been encoded.

This patch simplifies code and removes the confusing comments.

- nfsd4_is_solo_sequence() is discarded as not-useful.
- nfsd4_cache_this() is now trivial so it too is discarded with the
code placed in-line at the one call-site in nfsd4_store_cache_entry().
- nfsd4_enc_sequence_replay() is open-coded in to
nfsd4_replay_cache_entry(), and then simplified to (hopefully) make
the process of replaying a reply clearer.

Signed-off-by: NeilBrown <neil@brown.name>
Reviewed-by: Jeff Layton <jlayton@kernel.org>
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>

authored by

NeilBrown and committed by
Chuck Lever
fceb8734 8320b75b

+18 -61
+18 -40
fs/nfsd/nfs4state.c
··· 3508 3508 free_svc_cred(&slot->sl_cred); 3509 3509 copy_cred(&slot->sl_cred, &resp->rqstp->rq_cred); 3510 3510 3511 - if (!nfsd4_cache_this(resp)) { 3511 + if (!(resp->cstate.slot->sl_flags & NFSD4_SLOT_CACHETHIS)) { 3512 3512 slot->sl_flags &= ~NFSD4_SLOT_CACHED; 3513 3513 return; 3514 3514 } ··· 3523 3523 } 3524 3524 3525 3525 /* 3526 - * Encode the replay sequence operation from the slot values. 3527 - * If cachethis is FALSE encode the uncached rep error on the next 3528 - * operation which sets resp->p and increments resp->opcnt for 3529 - * nfs4svc_encode_compoundres. 3530 - * 3531 - */ 3532 - static __be32 3533 - nfsd4_enc_sequence_replay(struct nfsd4_compoundargs *args, 3534 - struct nfsd4_compoundres *resp) 3535 - { 3536 - struct nfsd4_op *op; 3537 - struct nfsd4_slot *slot = resp->cstate.slot; 3538 - 3539 - /* Encode the replayed sequence operation */ 3540 - op = &args->ops[resp->opcnt - 1]; 3541 - nfsd4_encode_operation(resp, op); 3542 - 3543 - if (slot->sl_flags & NFSD4_SLOT_CACHED) 3544 - return op->status; 3545 - if (args->opcnt == 1) { 3546 - /* 3547 - * The original operation wasn't a solo sequence--we 3548 - * always cache those--so this retry must not match the 3549 - * original: 3550 - */ 3551 - op->status = nfserr_seq_false_retry; 3552 - } else { 3553 - op = &args->ops[resp->opcnt++]; 3554 - op->status = nfserr_retry_uncached_rep; 3555 - nfsd4_encode_operation(resp, op); 3556 - } 3557 - return op->status; 3558 - } 3559 - 3560 - /* 3561 3526 * The sequence operation is not cached because we can use the slot and 3562 3527 * session values. 3563 3528 */ ··· 3530 3565 nfsd4_replay_cache_entry(struct nfsd4_compoundres *resp, 3531 3566 struct nfsd4_sequence *seq) 3532 3567 { 3568 + struct nfsd4_compoundargs *args = resp->rqstp->rq_argp; 3533 3569 struct nfsd4_slot *slot = resp->cstate.slot; 3534 3570 struct xdr_stream *xdr = resp->xdr; 3535 3571 __be32 *p; 3536 - __be32 status; 3537 3572 3538 3573 dprintk("--> %s slot %p\n", __func__, slot); 3539 3574 3540 - status = nfsd4_enc_sequence_replay(resp->rqstp->rq_argp, resp); 3541 - if (status) 3542 - return status; 3575 + /* Always encode the SEQUENCE response. */ 3576 + nfsd4_encode_operation(resp, &args->ops[0]); 3577 + if (args->opcnt == 1) 3578 + /* A solo SEQUENCE - nothing was cached */ 3579 + return args->ops[0].status; 3543 3580 3581 + if (!(slot->sl_flags & NFSD4_SLOT_CACHED)) { 3582 + /* We weren't asked to cache this. */ 3583 + struct nfsd4_op *op; 3584 + 3585 + op = &args->ops[resp->opcnt++]; 3586 + op->status = nfserr_retry_uncached_rep; 3587 + nfsd4_encode_operation(resp, op); 3588 + return op->status; 3589 + } 3590 + 3591 + /* return reply from cache */ 3544 3592 p = xdr_reserve_space(xdr, slot->sl_datalen); 3545 3593 if (!p) { 3546 3594 WARN_ON_ONCE(1);
-21
fs/nfsd/xdr4.h
··· 924 924 struct nfsd4_compound_state cstate; 925 925 }; 926 926 927 - static inline bool nfsd4_is_solo_sequence(struct nfsd4_compoundres *resp) 928 - { 929 - struct nfsd4_compoundargs *args = resp->rqstp->rq_argp; 930 - return resp->opcnt == 1 && args->ops[0].opnum == OP_SEQUENCE; 931 - } 932 - 933 - /* 934 - * The session reply cache only needs to cache replies that the client 935 - * actually asked us to. But it's almost free for us to cache compounds 936 - * consisting of only a SEQUENCE op, so we may as well cache those too. 937 - * Also, the protocol doesn't give us a convenient response in the case 938 - * of a replay of a solo SEQUENCE op that wasn't cached 939 - * (RETRY_UNCACHED_REP can only be returned in the second op of a 940 - * compound). 941 - */ 942 - static inline bool nfsd4_cache_this(struct nfsd4_compoundres *resp) 943 - { 944 - return (resp->cstate.slot->sl_flags & NFSD4_SLOT_CACHETHIS) 945 - || nfsd4_is_solo_sequence(resp); 946 - } 947 - 948 927 static inline bool nfsd4_last_compound_op(struct svc_rqst *rqstp) 949 928 { 950 929 struct nfsd4_compoundres *resp = rqstp->rq_resp;