diff options
author | Andy Adamson <andros@netapp.com> | 2010-01-14 17:45:08 -0500 |
---|---|---|
committer | Trond Myklebust <Trond.Myklebust@netapp.com> | 2010-02-10 08:30:58 -0500 |
commit | 4911096f1a5df73c12c287a42ece4e7b5d9c19ec (patch) | |
tree | 4e59b70fe7bfbea730ebcf829312f2bce7350040 | |
parent | b2f28bd78354b9bbcd178bf6bbf6b2277cd9b761 (diff) |
nfs41: back channel drc minimal implementation
For now the back channel ca_maxresponsesize_cached is 0 and there is no
backchannel DRC. Return NFS4ERR_REP_TOO_BIG_TO_CACHE when a cb_sequence
cachethis is true. When it is false, return NFS4ERR_RETRY_UNCACHED_REP as the
next operation error.
Remember the replay error accross compound operation processing.
Signed-off-by: Andy Adamson <andros@netapp.com>
Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
-rw-r--r-- | fs/nfs/callback_proc.c | 25 | ||||
-rw-r--r-- | fs/nfs/callback_xdr.c | 19 |
2 files changed, 32 insertions, 12 deletions
diff --git a/fs/nfs/callback_proc.c b/fs/nfs/callback_proc.c index 3d7edd65577b..4062f7690a33 100644 --- a/fs/nfs/callback_proc.c +++ b/fs/nfs/callback_proc.c | |||
@@ -143,9 +143,8 @@ int nfs41_validate_delegation_stateid(struct nfs_delegation *delegation, const n | |||
143 | * Return success if the sequenceID is one more than what we last saw on | 143 | * Return success if the sequenceID is one more than what we last saw on |
144 | * this slot, accounting for wraparound. Increments the slot's sequence. | 144 | * this slot, accounting for wraparound. Increments the slot's sequence. |
145 | * | 145 | * |
146 | * We don't yet implement a duplicate request cache, so at this time | 146 | * We don't yet implement a duplicate request cache, instead we set the |
147 | * we will log replays, and process them as if we had not seen them before, | 147 | * back channel ca_maxresponsesize_cached to zero. This is OK for now |
148 | * but we don't bump the sequence in the slot. Not too worried about it, | ||
149 | * since we only currently implement idempotent callbacks anyway. | 148 | * since we only currently implement idempotent callbacks anyway. |
150 | * | 149 | * |
151 | * We have a single slot backchannel at this time, so we don't bother | 150 | * We have a single slot backchannel at this time, so we don't bother |
@@ -174,9 +173,15 @@ validate_seqid(struct nfs4_slot_table *tbl, struct cb_sequenceargs * args) | |||
174 | 173 | ||
175 | /* Replay */ | 174 | /* Replay */ |
176 | if (args->csa_sequenceid == slot->seq_nr) { | 175 | if (args->csa_sequenceid == slot->seq_nr) { |
177 | dprintk("%s seqid %d is a replay - no DRC available\n", | 176 | dprintk("%s seqid %d is a replay\n", |
178 | __func__, args->csa_sequenceid); | 177 | __func__, args->csa_sequenceid); |
179 | return htonl(NFS4_OK); | 178 | /* Signal process_op to set this error on next op */ |
179 | if (args->csa_cachethis == 0) | ||
180 | return htonl(NFS4ERR_RETRY_UNCACHED_REP); | ||
181 | |||
182 | /* The ca_maxresponsesize_cached is 0 with no DRC */ | ||
183 | else if (args->csa_cachethis == 1) | ||
184 | return htonl(NFS4ERR_REP_TOO_BIG_TO_CACHE); | ||
180 | } | 185 | } |
181 | 186 | ||
182 | /* Wraparound */ | 187 | /* Wraparound */ |
@@ -319,9 +324,13 @@ out: | |||
319 | kfree(args->csa_rclists[i].rcl_refcalls); | 324 | kfree(args->csa_rclists[i].rcl_refcalls); |
320 | kfree(args->csa_rclists); | 325 | kfree(args->csa_rclists); |
321 | 326 | ||
322 | dprintk("%s: exit with status = %d\n", __func__, ntohl(status)); | 327 | if (status == htonl(NFS4ERR_RETRY_UNCACHED_REP)) |
323 | res->csr_status = status; | 328 | res->csr_status = 0; |
324 | return res->csr_status; | 329 | else |
330 | res->csr_status = status; | ||
331 | dprintk("%s: exit with status = %d res->csr_status %d\n", __func__, | ||
332 | ntohl(status), ntohl(res->csr_status)); | ||
333 | return status; | ||
325 | } | 334 | } |
326 | 335 | ||
327 | unsigned nfs4_callback_recallany(struct cb_recallanyargs *args, void *dummy) | 336 | unsigned nfs4_callback_recallany(struct cb_recallanyargs *args, void *dummy) |
diff --git a/fs/nfs/callback_xdr.c b/fs/nfs/callback_xdr.c index a6f2ded72b17..08b430d922c4 100644 --- a/fs/nfs/callback_xdr.c +++ b/fs/nfs/callback_xdr.c | |||
@@ -605,7 +605,7 @@ preprocess_nfs4_op(unsigned int op_nr, struct callback_op **op) | |||
605 | static __be32 process_op(uint32_t minorversion, int nop, | 605 | static __be32 process_op(uint32_t minorversion, int nop, |
606 | struct svc_rqst *rqstp, | 606 | struct svc_rqst *rqstp, |
607 | struct xdr_stream *xdr_in, void *argp, | 607 | struct xdr_stream *xdr_in, void *argp, |
608 | struct xdr_stream *xdr_out, void *resp) | 608 | struct xdr_stream *xdr_out, void *resp, int* drc_status) |
609 | { | 609 | { |
610 | struct callback_op *op = &callback_ops[0]; | 610 | struct callback_op *op = &callback_ops[0]; |
611 | unsigned int op_nr; | 611 | unsigned int op_nr; |
@@ -628,6 +628,11 @@ static __be32 process_op(uint32_t minorversion, int nop, | |||
628 | if (status) | 628 | if (status) |
629 | goto encode_hdr; | 629 | goto encode_hdr; |
630 | 630 | ||
631 | if (*drc_status) { | ||
632 | status = *drc_status; | ||
633 | goto encode_hdr; | ||
634 | } | ||
635 | |||
631 | maxlen = xdr_out->end - xdr_out->p; | 636 | maxlen = xdr_out->end - xdr_out->p; |
632 | if (maxlen > 0 && maxlen < PAGE_SIZE) { | 637 | if (maxlen > 0 && maxlen < PAGE_SIZE) { |
633 | status = op->decode_args(rqstp, xdr_in, argp); | 638 | status = op->decode_args(rqstp, xdr_in, argp); |
@@ -636,6 +641,12 @@ static __be32 process_op(uint32_t minorversion, int nop, | |||
636 | } else | 641 | } else |
637 | status = htonl(NFS4ERR_RESOURCE); | 642 | status = htonl(NFS4ERR_RESOURCE); |
638 | 643 | ||
644 | /* Only set by OP_CB_SEQUENCE processing */ | ||
645 | if (status == htonl(NFS4ERR_RETRY_UNCACHED_REP)) { | ||
646 | *drc_status = status; | ||
647 | status = 0; | ||
648 | } | ||
649 | |||
639 | encode_hdr: | 650 | encode_hdr: |
640 | res = encode_op_hdr(xdr_out, op_nr, status); | 651 | res = encode_op_hdr(xdr_out, op_nr, status); |
641 | if (unlikely(res)) | 652 | if (unlikely(res)) |
@@ -655,7 +666,7 @@ static __be32 nfs4_callback_compound(struct svc_rqst *rqstp, void *argp, void *r | |||
655 | struct cb_compound_hdr_res hdr_res = { NULL }; | 666 | struct cb_compound_hdr_res hdr_res = { NULL }; |
656 | struct xdr_stream xdr_in, xdr_out; | 667 | struct xdr_stream xdr_in, xdr_out; |
657 | __be32 *p; | 668 | __be32 *p; |
658 | __be32 status; | 669 | __be32 status, drc_status = 0; |
659 | unsigned int nops = 0; | 670 | unsigned int nops = 0; |
660 | 671 | ||
661 | dprintk("%s: start\n", __func__); | 672 | dprintk("%s: start\n", __func__); |
@@ -675,8 +686,8 @@ static __be32 nfs4_callback_compound(struct svc_rqst *rqstp, void *argp, void *r | |||
675 | return rpc_system_err; | 686 | return rpc_system_err; |
676 | 687 | ||
677 | while (status == 0 && nops != hdr_arg.nops) { | 688 | while (status == 0 && nops != hdr_arg.nops) { |
678 | status = process_op(hdr_arg.minorversion, nops, | 689 | status = process_op(hdr_arg.minorversion, nops, rqstp, |
679 | rqstp, &xdr_in, argp, &xdr_out, resp); | 690 | &xdr_in, argp, &xdr_out, resp, &drc_status); |
680 | nops++; | 691 | nops++; |
681 | } | 692 | } |
682 | 693 | ||