Commit 2f425878 authored by Andy Adamson's avatar Andy Adamson Committed by J. Bruce Fields

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: default avatarAndy Adamson <andros@netapp.com>
Signed-off-by: default avatarBenny Halevy <bhalevy@panasas.com>
[nfsd41: reverse rq_nodeferral negative logic]
Signed-off-by: default avatarBenny Halevy <bhalevy@panasas.com>
[sunrpc: initialize rq_usedeferral]
Signed-off-by: default avatarAndy Adamson <andros@netapp.com>
Signed-off-by: default avatarBenny Halevy <bhalevy@panasas.com>
Signed-off-by: default avatarJ. Bruce Fields <bfields@citi.umich.edu>
parent 20766016
...@@ -854,6 +854,8 @@ nfsd4_proc_compound(struct svc_rqst *rqstp, ...@@ -854,6 +854,8 @@ nfsd4_proc_compound(struct svc_rqst *rqstp,
resp->cstate.replay_owner = NULL; resp->cstate.replay_owner = NULL;
fh_init(&resp->cstate.current_fh, NFS4_FHSIZE); fh_init(&resp->cstate.current_fh, NFS4_FHSIZE);
fh_init(&resp->cstate.save_fh, NFS4_FHSIZE); fh_init(&resp->cstate.save_fh, NFS4_FHSIZE);
/* Use the deferral mechanism only for NFSv4.0 compounds */
rqstp->rq_usedeferral = (args->minorversion == 0);
/* /*
* According to RFC3010, this takes precedence over all other errors. * According to RFC3010, this takes precedence over all other errors.
...@@ -933,12 +935,18 @@ nfsd4_proc_compound(struct svc_rqst *rqstp, ...@@ -933,12 +935,18 @@ nfsd4_proc_compound(struct svc_rqst *rqstp,
nfsd4_increment_op_stats(op->opnum); nfsd4_increment_op_stats(op->opnum);
} }
if (!rqstp->rq_usedeferral && status == nfserr_dropit) {
dprintk("%s Dropit - send NFS4ERR_DELAY\n", __func__);
status = nfserr_jukebox;
}
fh_put(&resp->cstate.current_fh); fh_put(&resp->cstate.current_fh);
fh_put(&resp->cstate.save_fh); fh_put(&resp->cstate.save_fh);
BUG_ON(resp->cstate.replay_owner); BUG_ON(resp->cstate.replay_owner);
out: out:
nfsd4_release_compoundargs(args); nfsd4_release_compoundargs(args);
/* Reset deferral mechanism for RPC deferrals */
rqstp->rq_usedeferral = 1;
dprintk("nfsv4 compound returned %d\n", ntohl(status)); dprintk("nfsv4 compound returned %d\n", ntohl(status));
return status; return status;
} }
......
...@@ -230,6 +230,7 @@ struct svc_rqst { ...@@ -230,6 +230,7 @@ struct svc_rqst {
struct svc_cred rq_cred; /* auth info */ struct svc_cred rq_cred; /* auth info */
void * rq_xprt_ctxt; /* transport specific context ptr */ void * rq_xprt_ctxt; /* transport specific context ptr */
struct svc_deferred_req*rq_deferred; /* deferred request we are replaying */ struct svc_deferred_req*rq_deferred; /* deferred request we are replaying */
int rq_usedeferral; /* use deferral */
size_t rq_xprt_hlen; /* xprt header len */ size_t rq_xprt_hlen; /* xprt header len */
struct xdr_buf rq_arg; struct xdr_buf rq_arg;
......
...@@ -1023,6 +1023,8 @@ svc_process(struct svc_rqst *rqstp) ...@@ -1023,6 +1023,8 @@ svc_process(struct svc_rqst *rqstp)
rqstp->rq_res.tail[0].iov_len = 0; rqstp->rq_res.tail[0].iov_len = 0;
/* Will be turned off only in gss privacy case: */ /* Will be turned off only in gss privacy case: */
rqstp->rq_splice_ok = 1; rqstp->rq_splice_ok = 1;
/* Will be turned off only when NFSv4 Sessions are used */
rqstp->rq_usedeferral = 1;
/* Setup reply header */ /* Setup reply header */
rqstp->rq_xprt->xpt_ops->xpo_prep_reply_hdr(rqstp); rqstp->rq_xprt->xpt_ops->xpo_prep_reply_hdr(rqstp);
......
...@@ -974,7 +974,7 @@ static struct cache_deferred_req *svc_defer(struct cache_req *req) ...@@ -974,7 +974,7 @@ static struct cache_deferred_req *svc_defer(struct cache_req *req)
struct svc_rqst *rqstp = container_of(req, struct svc_rqst, rq_chandle); struct svc_rqst *rqstp = container_of(req, struct svc_rqst, rq_chandle);
struct svc_deferred_req *dr; struct svc_deferred_req *dr;
if (rqstp->rq_arg.page_len) if (rqstp->rq_arg.page_len || !rqstp->rq_usedeferral)
return NULL; /* if more than a page, give up FIXME */ return NULL; /* if more than a page, give up FIXME */
if (rqstp->rq_deferred) { if (rqstp->rq_deferred) {
dr = rqstp->rq_deferred; dr = rqstp->rq_deferred;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment