aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndy Adamson <andros@netapp.com>2009-04-03 01:27:32 -0400
committerJ. Bruce Fields <bfields@citi.umich.edu>2009-04-03 20:41:12 -0400
commit2f425878b6a71571341dcd3f9e9d1a6f6355da9c (patch)
tree52735958c1614458bd6b459040f977dfc3c3e9a9
parent20766016329eb4985c2c8b2a1b2333e0f865fdf9 (diff)
nfsd: don't use the deferral service, return NFS4ERR_DELAY
On an NFSv4.1 server cache miss that causes an upcall, NFS4ERR_DELAY will be returned. It is up to the NFSv4.1 client to resend only the operations that have not been processed. Initialize rq_usedeferral to 1 in svc_process(). It sill be turned off in nfsd4_proc_compound() only when NFSv4.1 Sessions are used. Note: this isn't an adequate solution on its own. It's acceptable as a way to get some minimal 4.1 up and working, but we're going to have to find a way to avoid returning DELAY in all common cases before 4.1 can really be considered ready. Signed-off-by: Andy Adamson <andros@netapp.com> Signed-off-by: Benny Halevy <bhalevy@panasas.com> [nfsd41: reverse rq_nodeferral negative logic] Signed-off-by: Benny Halevy <bhalevy@panasas.com> [sunrpc: initialize rq_usedeferral] Signed-off-by: Andy Adamson <andros@netapp.com> Signed-off-by: Benny Halevy <bhalevy@panasas.com> Signed-off-by: J. Bruce Fields <bfields@citi.umich.edu>
-rw-r--r--fs/nfsd/nfs4proc.c8
-rw-r--r--include/linux/sunrpc/svc.h1
-rw-r--r--net/sunrpc/svc.c2
-rw-r--r--net/sunrpc/svc_xprt.c2
4 files changed, 12 insertions, 1 deletions
diff --git a/fs/nfsd/nfs4proc.c b/fs/nfsd/nfs4proc.c
index 249dad987a16..ded469ff08b3 100644
--- a/fs/nfsd/nfs4proc.c
+++ b/fs/nfsd/nfs4proc.c
@@ -854,6 +854,8 @@ nfsd4_proc_compound(struct svc_rqst *rqstp,
854 resp->cstate.replay_owner = NULL; 854 resp->cstate.replay_owner = NULL;
855 fh_init(&resp->cstate.current_fh, NFS4_FHSIZE); 855 fh_init(&resp->cstate.current_fh, NFS4_FHSIZE);
856 fh_init(&resp->cstate.save_fh, NFS4_FHSIZE); 856 fh_init(&resp->cstate.save_fh, NFS4_FHSIZE);
857 /* Use the deferral mechanism only for NFSv4.0 compounds */
858 rqstp->rq_usedeferral = (args->minorversion == 0);
857 859
858 /* 860 /*
859 * According to RFC3010, this takes precedence over all other errors. 861 * According to RFC3010, this takes precedence over all other errors.
@@ -933,12 +935,18 @@ encode_op:
933 935
934 nfsd4_increment_op_stats(op->opnum); 936 nfsd4_increment_op_stats(op->opnum);
935 } 937 }
938 if (!rqstp->rq_usedeferral && status == nfserr_dropit) {
939 dprintk("%s Dropit - send NFS4ERR_DELAY\n", __func__);
940 status = nfserr_jukebox;
941 }
936 942
937 fh_put(&resp->cstate.current_fh); 943 fh_put(&resp->cstate.current_fh);
938 fh_put(&resp->cstate.save_fh); 944 fh_put(&resp->cstate.save_fh);
939 BUG_ON(resp->cstate.replay_owner); 945 BUG_ON(resp->cstate.replay_owner);
940out: 946out:
941 nfsd4_release_compoundargs(args); 947 nfsd4_release_compoundargs(args);
948 /* Reset deferral mechanism for RPC deferrals */
949 rqstp->rq_usedeferral = 1;
942 dprintk("nfsv4 compound returned %d\n", ntohl(status)); 950 dprintk("nfsv4 compound returned %d\n", ntohl(status));
943 return status; 951 return status;
944} 952}
diff --git a/include/linux/sunrpc/svc.h b/include/linux/sunrpc/svc.h
index 9f9f699dd469..815dd589d4db 100644
--- a/include/linux/sunrpc/svc.h
+++ b/include/linux/sunrpc/svc.h
@@ -230,6 +230,7 @@ struct svc_rqst {
230 struct svc_cred rq_cred; /* auth info */ 230 struct svc_cred rq_cred; /* auth info */
231 void * rq_xprt_ctxt; /* transport specific context ptr */ 231 void * rq_xprt_ctxt; /* transport specific context ptr */
232 struct svc_deferred_req*rq_deferred; /* deferred request we are replaying */ 232 struct svc_deferred_req*rq_deferred; /* deferred request we are replaying */
233 int rq_usedeferral; /* use deferral */
233 234
234 size_t rq_xprt_hlen; /* xprt header len */ 235 size_t rq_xprt_hlen; /* xprt header len */
235 struct xdr_buf rq_arg; 236 struct xdr_buf rq_arg;
diff --git a/net/sunrpc/svc.c b/net/sunrpc/svc.c
index fff09a2d8960..45984cbe1bfa 100644
--- a/net/sunrpc/svc.c
+++ b/net/sunrpc/svc.c
@@ -1023,6 +1023,8 @@ svc_process(struct svc_rqst *rqstp)
1023 rqstp->rq_res.tail[0].iov_len = 0; 1023 rqstp->rq_res.tail[0].iov_len = 0;
1024 /* Will be turned off only in gss privacy case: */ 1024 /* Will be turned off only in gss privacy case: */
1025 rqstp->rq_splice_ok = 1; 1025 rqstp->rq_splice_ok = 1;
1026 /* Will be turned off only when NFSv4 Sessions are used */
1027 rqstp->rq_usedeferral = 1;
1026 1028
1027 /* Setup reply header */ 1029 /* Setup reply header */
1028 rqstp->rq_xprt->xpt_ops->xpo_prep_reply_hdr(rqstp); 1030 rqstp->rq_xprt->xpt_ops->xpo_prep_reply_hdr(rqstp);
diff --git a/net/sunrpc/svc_xprt.c b/net/sunrpc/svc_xprt.c
index 1e66f2491460..600d0918e3ae 100644
--- a/net/sunrpc/svc_xprt.c
+++ b/net/sunrpc/svc_xprt.c
@@ -974,7 +974,7 @@ static struct cache_deferred_req *svc_defer(struct cache_req *req)
974 struct svc_rqst *rqstp = container_of(req, struct svc_rqst, rq_chandle); 974 struct svc_rqst *rqstp = container_of(req, struct svc_rqst, rq_chandle);
975 struct svc_deferred_req *dr; 975 struct svc_deferred_req *dr;
976 976
977 if (rqstp->rq_arg.page_len) 977 if (rqstp->rq_arg.page_len || !rqstp->rq_usedeferral)
978 return NULL; /* if more than a page, give up FIXME */ 978 return NULL; /* if more than a page, give up FIXME */
979 if (rqstp->rq_deferred) { 979 if (rqstp->rq_deferred) {
980 dr = rqstp->rq_deferred; 980 dr = rqstp->rq_deferred;