Commit f4afc8fe authored by Chuck Lever's avatar Chuck Lever
Browse files

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
Loading
Loading
Loading
Loading
+17 −11
Original line number Diff line number Diff line
@@ -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 @@ svc_process_common(struct svc_rqst *rqstp, struct kvec *resv)
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);
+0 −1
Original line number Diff line number Diff line
@@ -890,7 +890,6 @@ int svc_recv(struct svc_rqst *rqstp, long timeout)

	xprt->xpt_ops->xpo_secure_port(rqstp);
	rqstp->rq_chandle.defer = svc_defer;
	rqstp->rq_xid = svc_getu32(&rqstp->rq_arg.head[0]);

	if (serv->sv_stats)
		serv->sv_stats->netcnt++;