diff options
author | Andy Adamson <andros@netapp.com> | 2009-04-03 01:27:32 -0400 |
---|---|---|
committer | J. Bruce Fields <bfields@citi.umich.edu> | 2009-04-03 20:41:12 -0400 |
commit | 2f425878b6a71571341dcd3f9e9d1a6f6355da9c (patch) | |
tree | 52735958c1614458bd6b459040f977dfc3c3e9a9 | |
parent | 20766016329eb4985c2c8b2a1b2333e0f865fdf9 (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.c | 8 | ||||
-rw-r--r-- | include/linux/sunrpc/svc.h | 1 | ||||
-rw-r--r-- | net/sunrpc/svc.c | 2 | ||||
-rw-r--r-- | net/sunrpc/svc_xprt.c | 2 |
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); |
940 | out: | 946 | out: |
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; |