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>
This commit is contained in:
		
							parent
							
								
									2076601632
								
							
						
					
					
						commit
						2f425878b6
					
				| @ -854,6 +854,8 @@ nfsd4_proc_compound(struct svc_rqst *rqstp, | ||||
| 	resp->cstate.replay_owner = NULL; | ||||
| 	fh_init(&resp->cstate.current_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. | ||||
| @ -933,12 +935,18 @@ encode_op: | ||||
| 
 | ||||
| 		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.save_fh); | ||||
| 	BUG_ON(resp->cstate.replay_owner); | ||||
| out: | ||||
| 	nfsd4_release_compoundargs(args); | ||||
| 	/* Reset deferral mechanism for RPC deferrals */ | ||||
| 	rqstp->rq_usedeferral = 1; | ||||
| 	dprintk("nfsv4 compound returned %d\n", ntohl(status)); | ||||
| 	return status; | ||||
| } | ||||
|  | ||||
| @ -230,6 +230,7 @@ struct svc_rqst { | ||||
| 	struct svc_cred		rq_cred;	/* auth info */ | ||||
| 	void *			rq_xprt_ctxt;	/* transport specific context ptr */ | ||||
| 	struct svc_deferred_req*rq_deferred;	/* deferred request we are replaying */ | ||||
| 	int			rq_usedeferral;	/* use deferral */ | ||||
| 
 | ||||
| 	size_t			rq_xprt_hlen;	/* xprt header len */ | ||||
| 	struct xdr_buf		rq_arg; | ||||
|  | ||||
| @ -1023,6 +1023,8 @@ svc_process(struct svc_rqst *rqstp) | ||||
| 	rqstp->rq_res.tail[0].iov_len = 0; | ||||
| 	/* Will be turned off only in gss privacy case: */ | ||||
| 	rqstp->rq_splice_ok = 1; | ||||
| 	/* Will be turned off only when NFSv4 Sessions are used */ | ||||
| 	rqstp->rq_usedeferral = 1; | ||||
| 
 | ||||
| 	/* Setup reply header */ | ||||
| 	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) | ||||
| 	struct svc_rqst *rqstp = container_of(req, struct svc_rqst, rq_chandle); | ||||
| 	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 */ | ||||
| 	if (rqstp->rq_deferred) { | ||||
| 		dr = rqstp->rq_deferred; | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user