mirror of
				https://github.com/torvalds/linux.git
				synced 2025-11-03 18:20:25 +02:00 
			
		
		
		
	SUNRPC: Refactor RPC server dispatch method
Currently, svcauth_gss_accept() pre-reserves response buffer space for the RPC payload length and GSS sequence number before returning to the dispatcher, which then adds the header's accept_stat field. The problem is the accept_stat field is supposed to go before the length and seq_num fields. So svcauth_gss_release() has to relocate the accept_stat value (see svcauth_gss_prepare_to_wrap()). To enable these fields to be added to the response buffer in the correct (final) order, the pointer to the accept_stat has to be made available to svcauth_gss_accept() so that it can set it before reserving space for the length and seq_num fields. As a first step, move the pointer to the location of the accept_stat field into struct svc_rqst. Reviewed-by: Jeff Layton <jlayton@kernel.org> Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
This commit is contained in:
		
							parent
							
								
									5df25676de
								
							
						
					
					
						commit
						cee4db1945
					
				
					 7 changed files with 16 additions and 15 deletions
				
			
		| 
						 | 
				
			
			@ -685,15 +685,15 @@ module_exit(exit_nlm);
 | 
			
		|||
/**
 | 
			
		||||
 * nlmsvc_dispatch - Process an NLM Request
 | 
			
		||||
 * @rqstp: incoming request
 | 
			
		||||
 * @statp: pointer to location of accept_stat field in RPC Reply buffer
 | 
			
		||||
 *
 | 
			
		||||
 * Return values:
 | 
			
		||||
 *  %0: Processing complete; do not send a Reply
 | 
			
		||||
 *  %1: Processing complete; send Reply in rqstp->rq_res
 | 
			
		||||
 */
 | 
			
		||||
static int nlmsvc_dispatch(struct svc_rqst *rqstp, __be32 *statp)
 | 
			
		||||
static int nlmsvc_dispatch(struct svc_rqst *rqstp)
 | 
			
		||||
{
 | 
			
		||||
	const struct svc_procedure *procp = rqstp->rq_procinfo;
 | 
			
		||||
	__be32 *statp = rqstp->rq_accept_statp;
 | 
			
		||||
 | 
			
		||||
	if (!procp->pc_decode(rqstp, &rqstp->rq_arg_stream))
 | 
			
		||||
		goto out_decode_err;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -980,11 +980,11 @@ static __be32 nfs4_callback_compound(struct svc_rqst *rqstp)
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
static int
 | 
			
		||||
nfs_callback_dispatch(struct svc_rqst *rqstp, __be32 *statp)
 | 
			
		||||
nfs_callback_dispatch(struct svc_rqst *rqstp)
 | 
			
		||||
{
 | 
			
		||||
	const struct svc_procedure *procp = rqstp->rq_procinfo;
 | 
			
		||||
 | 
			
		||||
	*statp = procp->pc_func(rqstp);
 | 
			
		||||
	*rqstp->rq_accept_statp = procp->pc_func(rqstp);
 | 
			
		||||
	return 1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -509,7 +509,7 @@ int nfsd_cache_lookup(struct svc_rqst *rqstp)
 | 
			
		|||
 * nfsd_cache_update - Update an entry in the duplicate reply cache.
 | 
			
		||||
 * @rqstp: svc_rqst with a finished Reply
 | 
			
		||||
 * @cachetype: which cache to update
 | 
			
		||||
 * @statp: Reply's status code
 | 
			
		||||
 * @statp: pointer to Reply's NFS status code, or NULL
 | 
			
		||||
 *
 | 
			
		||||
 * This is called from nfsd_dispatch when the procedure has been
 | 
			
		||||
 * executed and the complete reply is in rqstp->rq_res.
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -86,7 +86,7 @@ bool		nfssvc_encode_voidres(struct svc_rqst *rqstp,
 | 
			
		|||
 * Function prototypes.
 | 
			
		||||
 */
 | 
			
		||||
int		nfsd_svc(int nrservs, struct net *net, const struct cred *cred);
 | 
			
		||||
int		nfsd_dispatch(struct svc_rqst *rqstp, __be32 *statp);
 | 
			
		||||
int		nfsd_dispatch(struct svc_rqst *rqstp);
 | 
			
		||||
 | 
			
		||||
int		nfsd_nrthreads(struct net *);
 | 
			
		||||
int		nfsd_nrpools(struct net *);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1022,7 +1022,6 @@ nfsd(void *vrqstp)
 | 
			
		|||
/**
 | 
			
		||||
 * nfsd_dispatch - Process an NFS or NFSACL Request
 | 
			
		||||
 * @rqstp: incoming request
 | 
			
		||||
 * @statp: pointer to location of accept_stat field in RPC Reply buffer
 | 
			
		||||
 *
 | 
			
		||||
 * This RPC dispatcher integrates the NFS server's duplicate reply cache.
 | 
			
		||||
 *
 | 
			
		||||
| 
						 | 
				
			
			@ -1030,9 +1029,10 @@ nfsd(void *vrqstp)
 | 
			
		|||
 *  %0: Processing complete; do not send a Reply
 | 
			
		||||
 *  %1: Processing complete; send Reply in rqstp->rq_res
 | 
			
		||||
 */
 | 
			
		||||
int nfsd_dispatch(struct svc_rqst *rqstp, __be32 *statp)
 | 
			
		||||
int nfsd_dispatch(struct svc_rqst *rqstp)
 | 
			
		||||
{
 | 
			
		||||
	const struct svc_procedure *proc = rqstp->rq_procinfo;
 | 
			
		||||
	__be32 *statp = rqstp->rq_accept_statp;
 | 
			
		||||
 | 
			
		||||
	/*
 | 
			
		||||
	 * Give the xdr decoder a chance to change this if it wants
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -251,6 +251,7 @@ struct svc_rqst {
 | 
			
		|||
 | 
			
		||||
	void *			rq_argp;	/* decoded arguments */
 | 
			
		||||
	void *			rq_resp;	/* xdr'd results */
 | 
			
		||||
	__be32			*rq_accept_statp;
 | 
			
		||||
	void *			rq_auth_data;	/* flavor-specific data */
 | 
			
		||||
	__be32			rq_auth_stat;	/* authentication status */
 | 
			
		||||
	int			rq_auth_slack;	/* extra space xdr code
 | 
			
		||||
| 
						 | 
				
			
			@ -337,7 +338,7 @@ struct svc_deferred_req {
 | 
			
		|||
 | 
			
		||||
struct svc_process_info {
 | 
			
		||||
	union {
 | 
			
		||||
		int  (*dispatch)(struct svc_rqst *, __be32 *);
 | 
			
		||||
		int  (*dispatch)(struct svc_rqst *rqstp);
 | 
			
		||||
		struct {
 | 
			
		||||
			unsigned int lovers;
 | 
			
		||||
			unsigned int hivers;
 | 
			
		||||
| 
						 | 
				
			
			@ -389,7 +390,7 @@ struct svc_version {
 | 
			
		|||
	bool			vs_need_cong_ctrl;
 | 
			
		||||
 | 
			
		||||
	/* Dispatch function */
 | 
			
		||||
	int			(*vs_dispatch)(struct svc_rqst *, __be32 *);
 | 
			
		||||
	int			(*vs_dispatch)(struct svc_rqst *rqstp);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1232,9 +1232,9 @@ svc_process_common(struct svc_rqst *rqstp)
 | 
			
		|||
	const struct svc_procedure *procp = NULL;
 | 
			
		||||
	struct svc_serv		*serv = rqstp->rq_server;
 | 
			
		||||
	struct svc_process_info process;
 | 
			
		||||
	__be32			*p, *statp;
 | 
			
		||||
	int			auth_res, rc;
 | 
			
		||||
	unsigned int		aoffset;
 | 
			
		||||
	__be32			*p;
 | 
			
		||||
 | 
			
		||||
	/* Will be turned off by GSS integrity and privacy services */
 | 
			
		||||
	set_bit(RQ_SPLICE_OK, &rqstp->rq_flags);
 | 
			
		||||
| 
						 | 
				
			
			@ -1314,8 +1314,8 @@ svc_process_common(struct svc_rqst *rqstp)
 | 
			
		|||
	trace_svc_process(rqstp, progp->pg_name);
 | 
			
		||||
 | 
			
		||||
	aoffset = xdr_stream_pos(xdr);
 | 
			
		||||
	statp = xdr_reserve_space(&rqstp->rq_res_stream, XDR_UNIT);
 | 
			
		||||
	*statp = rpc_success;
 | 
			
		||||
	rqstp->rq_accept_statp = xdr_reserve_space(&rqstp->rq_res_stream, XDR_UNIT);
 | 
			
		||||
	*rqstp->rq_accept_statp = rpc_success;
 | 
			
		||||
 | 
			
		||||
	/* un-reserve some of the out-queue now that we have a
 | 
			
		||||
	 * better idea of reply size
 | 
			
		||||
| 
						 | 
				
			
			@ -1324,7 +1324,7 @@ svc_process_common(struct svc_rqst *rqstp)
 | 
			
		|||
		svc_reserve_auth(rqstp, procp->pc_xdrressize<<2);
 | 
			
		||||
 | 
			
		||||
	/* Call the function that processes the request. */
 | 
			
		||||
	rc = process.dispatch(rqstp, statp);
 | 
			
		||||
	rc = process.dispatch(rqstp);
 | 
			
		||||
	if (procp->pc_release)
 | 
			
		||||
		procp->pc_release(rqstp);
 | 
			
		||||
	if (!rc)
 | 
			
		||||
| 
						 | 
				
			
			@ -1332,7 +1332,7 @@ svc_process_common(struct svc_rqst *rqstp)
 | 
			
		|||
	if (rqstp->rq_auth_stat != rpc_auth_ok)
 | 
			
		||||
		goto err_bad_auth;
 | 
			
		||||
 | 
			
		||||
	if (*statp != rpc_success)
 | 
			
		||||
	if (*rqstp->rq_accept_statp != rpc_success)
 | 
			
		||||
		xdr_truncate_encode(xdr, aoffset);
 | 
			
		||||
 | 
			
		||||
	if (procp->pc_encode == NULL)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in a new issue