aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfs/callback_xdr.c
diff options
context:
space:
mode:
authorAndy Adamson <andros@netapp.com>2010-01-14 17:45:08 -0500
committerTrond Myklebust <Trond.Myklebust@netapp.com>2010-02-10 08:30:58 -0500
commit4911096f1a5df73c12c287a42ece4e7b5d9c19ec (patch)
tree4e59b70fe7bfbea730ebcf829312f2bce7350040 /fs/nfs/callback_xdr.c
parentb2f28bd78354b9bbcd178bf6bbf6b2277cd9b761 (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>
Diffstat (limited to 'fs/nfs/callback_xdr.c')
-rw-r--r--fs/nfs/callback_xdr.c19
1 files changed, 15 insertions, 4 deletions
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)
605static __be32 process_op(uint32_t minorversion, int nop, 605static __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
639encode_hdr: 650encode_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