summaryrefslogtreecommitdiff
path: root/net/sunrpc/svc.c
diff options
context:
space:
mode:
authorChuck Lever <chuck.lever@oracle.com>2023-01-02 12:08:04 -0500
committerChuck Lever <chuck.lever@oracle.com>2023-02-20 09:20:21 -0500
commitf4afc8fead386c81fda2593ad6162271d26667f8 (patch)
treed3b36caf58cd3080ce2ef3f3cc5389e3019be33b /net/sunrpc/svc.c
parent1c59a532ae38cc4472a7096d7a50703bce9a153f (diff)
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: Jeff Layton <jlayton@kernel.org> Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
Diffstat (limited to 'net/sunrpc/svc.c')
-rw-r--r--net/sunrpc/svc.c28
1 files changed, 17 insertions, 11 deletions
diff --git a/net/sunrpc/svc.c b/net/sunrpc/svc.c
index c75bd7a5e871..8da444cfcc43 100644
--- a/net/sunrpc/svc.c
+++ b/net/sunrpc/svc.c
@@ -1249,7 +1249,6 @@ svc_process_common(struct svc_rqst *rqstp, struct kvec *resv)
svc_putnl(resv, RPC_REPLY);
reply_statp = resv->iov_base + resv->iov_len;
- svcxdr_init_decode(rqstp);
p = xdr_inline_decode(&rqstp->rq_arg_stream, XDR_UNIT * 4);
if (unlikely(!p))
goto err_short_len;
@@ -1425,9 +1424,8 @@ err_bad:
int
svc_process(struct svc_rqst *rqstp)
{
- struct kvec *argv = &rqstp->rq_arg.head[0];
struct kvec *resv = &rqstp->rq_res.head[0];
- __be32 dir;
+ __be32 *p;
#if IS_ENABLED(CONFIG_FAIL_SUNRPC)
if (!fail_sunrpc.ignore_server_disconnect &&
@@ -1450,16 +1448,21 @@ svc_process(struct svc_rqst *rqstp)
rqstp->rq_res.tail[0].iov_base = NULL;
rqstp->rq_res.tail[0].iov_len = 0;
- dir = svc_getu32(argv);
- if (dir != rpc_call)
+ svcxdr_init_decode(rqstp);
+ 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;
+
if (!svc_process_common(rqstp, resv))
goto out_drop;
return svc_send(rqstp);
out_baddir:
svc_printk(rqstp, "bad direction 0x%08x, dropping request\n",
- be32_to_cpu(dir));
+ be32_to_cpu(*p));
rqstp->rq_server->sv_stats->rpcbadfmt++;
out_drop:
svc_drop(rqstp);
@@ -1476,7 +1479,6 @@ int
bc_svc_process(struct svc_serv *serv, struct rpc_rqst *req,
struct svc_rqst *rqstp)
{
- struct kvec *argv = &rqstp->rq_arg.head[0];
struct kvec *resv = &rqstp->rq_res.head[0];
struct rpc_task *task;
int proc_error;
@@ -1511,12 +1513,16 @@ bc_svc_process(struct svc_serv *serv, struct rpc_rqst *req,
/* reset result send buffer "put" position */
resv->iov_len = 0;
+ svcxdr_init_decode(rqstp);
+
/*
- * Skip the next two words because they've already been
- * processed in the transport
+ * Skip the XID and calldir fields because they've already
+ * been processed by the caller.
*/
- svc_getu32(argv); /* XID */
- svc_getnl(argv); /* CALLDIR */
+ if (!xdr_inline_decode(&rqstp->rq_arg_stream, XDR_UNIT * 2)) {
+ error = -EINVAL;
+ goto out;
+ }
/* Parse and execute the bc call */
proc_error = svc_process_common(rqstp, resv);