Commit f4afc8fe authored by Chuck Lever's avatar Chuck Lever

SUNRPC: Hoist svcxdr_init_decode() into svc_process()

Now the entire RPC Call header parsing path is handled via struct
xdr_stream-based decoders.
Reviewed-by: default avatarJeff Layton <jlayton@kernel.org>
Signed-off-by: default avatarChuck Lever <chuck.lever@oracle.com>
parent 1c59a532
...@@ -1249,7 +1249,6 @@ svc_process_common(struct svc_rqst *rqstp, struct kvec *resv) ...@@ -1249,7 +1249,6 @@ svc_process_common(struct svc_rqst *rqstp, struct kvec *resv)
svc_putnl(resv, RPC_REPLY); svc_putnl(resv, RPC_REPLY);
reply_statp = resv->iov_base + resv->iov_len; reply_statp = resv->iov_base + resv->iov_len;
svcxdr_init_decode(rqstp);
p = xdr_inline_decode(&rqstp->rq_arg_stream, XDR_UNIT * 4); p = xdr_inline_decode(&rqstp->rq_arg_stream, XDR_UNIT * 4);
if (unlikely(!p)) if (unlikely(!p))
goto err_short_len; goto err_short_len;
...@@ -1425,9 +1424,8 @@ svc_process_common(struct svc_rqst *rqstp, struct kvec *resv) ...@@ -1425,9 +1424,8 @@ svc_process_common(struct svc_rqst *rqstp, struct kvec *resv)
int int
svc_process(struct svc_rqst *rqstp) svc_process(struct svc_rqst *rqstp)
{ {
struct kvec *argv = &rqstp->rq_arg.head[0];
struct kvec *resv = &rqstp->rq_res.head[0]; struct kvec *resv = &rqstp->rq_res.head[0];
__be32 dir; __be32 *p;
#if IS_ENABLED(CONFIG_FAIL_SUNRPC) #if IS_ENABLED(CONFIG_FAIL_SUNRPC)
if (!fail_sunrpc.ignore_server_disconnect && if (!fail_sunrpc.ignore_server_disconnect &&
...@@ -1450,16 +1448,21 @@ svc_process(struct svc_rqst *rqstp) ...@@ -1450,16 +1448,21 @@ svc_process(struct svc_rqst *rqstp)
rqstp->rq_res.tail[0].iov_base = NULL; rqstp->rq_res.tail[0].iov_base = NULL;
rqstp->rq_res.tail[0].iov_len = 0; rqstp->rq_res.tail[0].iov_len = 0;
dir = svc_getu32(argv); svcxdr_init_decode(rqstp);
if (dir != rpc_call) p = xdr_inline_decode(&rqstp->rq_arg_stream, XDR_UNIT * 2);
if (unlikely(!p))
goto out_drop;
rqstp->rq_xid = *p++;
if (unlikely(*p != rpc_call))
goto out_baddir; goto out_baddir;
if (!svc_process_common(rqstp, resv)) if (!svc_process_common(rqstp, resv))
goto out_drop; goto out_drop;
return svc_send(rqstp); return svc_send(rqstp);
out_baddir: out_baddir:
svc_printk(rqstp, "bad direction 0x%08x, dropping request\n", svc_printk(rqstp, "bad direction 0x%08x, dropping request\n",
be32_to_cpu(dir)); be32_to_cpu(*p));
rqstp->rq_server->sv_stats->rpcbadfmt++; rqstp->rq_server->sv_stats->rpcbadfmt++;
out_drop: out_drop:
svc_drop(rqstp); svc_drop(rqstp);
...@@ -1476,7 +1479,6 @@ int ...@@ -1476,7 +1479,6 @@ int
bc_svc_process(struct svc_serv *serv, struct rpc_rqst *req, bc_svc_process(struct svc_serv *serv, struct rpc_rqst *req,
struct svc_rqst *rqstp) struct svc_rqst *rqstp)
{ {
struct kvec *argv = &rqstp->rq_arg.head[0];
struct kvec *resv = &rqstp->rq_res.head[0]; struct kvec *resv = &rqstp->rq_res.head[0];
struct rpc_task *task; struct rpc_task *task;
int proc_error; int proc_error;
...@@ -1511,12 +1513,16 @@ bc_svc_process(struct svc_serv *serv, struct rpc_rqst *req, ...@@ -1511,12 +1513,16 @@ bc_svc_process(struct svc_serv *serv, struct rpc_rqst *req,
/* reset result send buffer "put" position */ /* reset result send buffer "put" position */
resv->iov_len = 0; resv->iov_len = 0;
svcxdr_init_decode(rqstp);
/* /*
* Skip the next two words because they've already been * Skip the XID and calldir fields because they've already
* processed in the transport * been processed by the caller.
*/ */
svc_getu32(argv); /* XID */ if (!xdr_inline_decode(&rqstp->rq_arg_stream, XDR_UNIT * 2)) {
svc_getnl(argv); /* CALLDIR */ error = -EINVAL;
goto out;
}
/* Parse and execute the bc call */ /* Parse and execute the bc call */
proc_error = svc_process_common(rqstp, resv); proc_error = svc_process_common(rqstp, resv);
......
...@@ -890,7 +890,6 @@ int svc_recv(struct svc_rqst *rqstp, long timeout) ...@@ -890,7 +890,6 @@ int svc_recv(struct svc_rqst *rqstp, long timeout)
xprt->xpt_ops->xpo_secure_port(rqstp); xprt->xpt_ops->xpo_secure_port(rqstp);
rqstp->rq_chandle.defer = svc_defer; rqstp->rq_chandle.defer = svc_defer;
rqstp->rq_xid = svc_getu32(&rqstp->rq_arg.head[0]);
if (serv->sv_stats) if (serv->sv_stats)
serv->sv_stats->netcnt++; serv->sv_stats->netcnt++;
......
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