Commit cee4db19 authored by Chuck Lever's avatar Chuck Lever

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: default avatarJeff Layton <jlayton@kernel.org>
Signed-off-by: default avatarChuck Lever <chuck.lever@oracle.com>
parent 5df25676
...@@ -685,15 +685,15 @@ module_exit(exit_nlm); ...@@ -685,15 +685,15 @@ module_exit(exit_nlm);
/** /**
* nlmsvc_dispatch - Process an NLM Request * nlmsvc_dispatch - Process an NLM Request
* @rqstp: incoming request * @rqstp: incoming request
* @statp: pointer to location of accept_stat field in RPC Reply buffer
* *
* Return values: * Return values:
* %0: Processing complete; do not send a Reply * %0: Processing complete; do not send a Reply
* %1: Processing complete; send Reply in rqstp->rq_res * %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; const struct svc_procedure *procp = rqstp->rq_procinfo;
__be32 *statp = rqstp->rq_accept_statp;
if (!procp->pc_decode(rqstp, &rqstp->rq_arg_stream)) if (!procp->pc_decode(rqstp, &rqstp->rq_arg_stream))
goto out_decode_err; goto out_decode_err;
......
...@@ -980,11 +980,11 @@ static __be32 nfs4_callback_compound(struct svc_rqst *rqstp) ...@@ -980,11 +980,11 @@ static __be32 nfs4_callback_compound(struct svc_rqst *rqstp)
} }
static int 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; const struct svc_procedure *procp = rqstp->rq_procinfo;
*statp = procp->pc_func(rqstp); *rqstp->rq_accept_statp = procp->pc_func(rqstp);
return 1; return 1;
} }
......
...@@ -509,7 +509,7 @@ int nfsd_cache_lookup(struct svc_rqst *rqstp) ...@@ -509,7 +509,7 @@ int nfsd_cache_lookup(struct svc_rqst *rqstp)
* nfsd_cache_update - Update an entry in the duplicate reply cache. * nfsd_cache_update - Update an entry in the duplicate reply cache.
* @rqstp: svc_rqst with a finished Reply * @rqstp: svc_rqst with a finished Reply
* @cachetype: which cache to update * @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 * This is called from nfsd_dispatch when the procedure has been
* executed and the complete reply is in rqstp->rq_res. * executed and the complete reply is in rqstp->rq_res.
......
...@@ -86,7 +86,7 @@ bool nfssvc_encode_voidres(struct svc_rqst *rqstp, ...@@ -86,7 +86,7 @@ bool nfssvc_encode_voidres(struct svc_rqst *rqstp,
* Function prototypes. * Function prototypes.
*/ */
int nfsd_svc(int nrservs, struct net *net, const struct cred *cred); 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_nrthreads(struct net *);
int nfsd_nrpools(struct net *); int nfsd_nrpools(struct net *);
......
...@@ -1022,7 +1022,6 @@ nfsd(void *vrqstp) ...@@ -1022,7 +1022,6 @@ nfsd(void *vrqstp)
/** /**
* nfsd_dispatch - Process an NFS or NFSACL Request * nfsd_dispatch - Process an NFS or NFSACL Request
* @rqstp: incoming 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. * This RPC dispatcher integrates the NFS server's duplicate reply cache.
* *
...@@ -1030,9 +1029,10 @@ nfsd(void *vrqstp) ...@@ -1030,9 +1029,10 @@ nfsd(void *vrqstp)
* %0: Processing complete; do not send a Reply * %0: Processing complete; do not send a Reply
* %1: Processing complete; send Reply in rqstp->rq_res * %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; 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 * Give the xdr decoder a chance to change this if it wants
......
...@@ -251,6 +251,7 @@ struct svc_rqst { ...@@ -251,6 +251,7 @@ struct svc_rqst {
void * rq_argp; /* decoded arguments */ void * rq_argp; /* decoded arguments */
void * rq_resp; /* xdr'd results */ void * rq_resp; /* xdr'd results */
__be32 *rq_accept_statp;
void * rq_auth_data; /* flavor-specific data */ void * rq_auth_data; /* flavor-specific data */
__be32 rq_auth_stat; /* authentication status */ __be32 rq_auth_stat; /* authentication status */
int rq_auth_slack; /* extra space xdr code int rq_auth_slack; /* extra space xdr code
...@@ -337,7 +338,7 @@ struct svc_deferred_req { ...@@ -337,7 +338,7 @@ struct svc_deferred_req {
struct svc_process_info { struct svc_process_info {
union { union {
int (*dispatch)(struct svc_rqst *, __be32 *); int (*dispatch)(struct svc_rqst *rqstp);
struct { struct {
unsigned int lovers; unsigned int lovers;
unsigned int hivers; unsigned int hivers;
...@@ -389,7 +390,7 @@ struct svc_version { ...@@ -389,7 +390,7 @@ struct svc_version {
bool vs_need_cong_ctrl; bool vs_need_cong_ctrl;
/* Dispatch function */ /* 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) ...@@ -1232,9 +1232,9 @@ svc_process_common(struct svc_rqst *rqstp)
const struct svc_procedure *procp = NULL; const struct svc_procedure *procp = NULL;
struct svc_serv *serv = rqstp->rq_server; struct svc_serv *serv = rqstp->rq_server;
struct svc_process_info process; struct svc_process_info process;
__be32 *p, *statp;
int auth_res, rc; int auth_res, rc;
unsigned int aoffset; unsigned int aoffset;
__be32 *p;
/* Will be turned off by GSS integrity and privacy services */ /* Will be turned off by GSS integrity and privacy services */
set_bit(RQ_SPLICE_OK, &rqstp->rq_flags); set_bit(RQ_SPLICE_OK, &rqstp->rq_flags);
...@@ -1314,8 +1314,8 @@ svc_process_common(struct svc_rqst *rqstp) ...@@ -1314,8 +1314,8 @@ svc_process_common(struct svc_rqst *rqstp)
trace_svc_process(rqstp, progp->pg_name); trace_svc_process(rqstp, progp->pg_name);
aoffset = xdr_stream_pos(xdr); aoffset = xdr_stream_pos(xdr);
statp = xdr_reserve_space(&rqstp->rq_res_stream, XDR_UNIT); rqstp->rq_accept_statp = xdr_reserve_space(&rqstp->rq_res_stream, XDR_UNIT);
*statp = rpc_success; *rqstp->rq_accept_statp = rpc_success;
/* un-reserve some of the out-queue now that we have a /* un-reserve some of the out-queue now that we have a
* better idea of reply size * better idea of reply size
...@@ -1324,7 +1324,7 @@ svc_process_common(struct svc_rqst *rqstp) ...@@ -1324,7 +1324,7 @@ svc_process_common(struct svc_rqst *rqstp)
svc_reserve_auth(rqstp, procp->pc_xdrressize<<2); svc_reserve_auth(rqstp, procp->pc_xdrressize<<2);
/* Call the function that processes the request. */ /* Call the function that processes the request. */
rc = process.dispatch(rqstp, statp); rc = process.dispatch(rqstp);
if (procp->pc_release) if (procp->pc_release)
procp->pc_release(rqstp); procp->pc_release(rqstp);
if (!rc) if (!rc)
...@@ -1332,7 +1332,7 @@ svc_process_common(struct svc_rqst *rqstp) ...@@ -1332,7 +1332,7 @@ svc_process_common(struct svc_rqst *rqstp)
if (rqstp->rq_auth_stat != rpc_auth_ok) if (rqstp->rq_auth_stat != rpc_auth_ok)
goto err_bad_auth; goto err_bad_auth;
if (*statp != rpc_success) if (*rqstp->rq_accept_statp != rpc_success)
xdr_truncate_encode(xdr, aoffset); xdr_truncate_encode(xdr, aoffset);
if (procp->pc_encode == NULL) if (procp->pc_encode == NULL)
......
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