Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 4c8e5537 authored by Trond Myklebust's avatar Trond Myklebust Committed by J. Bruce Fields
Browse files

SUNRPC: Simplify TCP receive code



Use the fact that the iov iterators already have functionality for
skipping a base offset.

Signed-off-by: default avatarTrond Myklebust <trond.myklebust@hammerspace.com>
Signed-off-by: default avatarJ. Bruce Fields <bfields@redhat.com>
parent 1863d77f
Loading
Loading
Loading
Loading
+14 −39
Original line number Diff line number Diff line
@@ -325,59 +325,34 @@ static int svc_one_sock_name(struct svc_sock *svsk, char *buf, int remaining)
/*
 * Generic recvfrom routine.
 */
static int svc_recvfrom(struct svc_rqst *rqstp, struct kvec *iov, int nr,
			int buflen)
static ssize_t svc_recvfrom(struct svc_rqst *rqstp, struct kvec *iov,
			    unsigned int nr, size_t buflen, unsigned int base)
{
	struct svc_sock *svsk =
		container_of(rqstp->rq_xprt, struct svc_sock, sk_xprt);
	struct msghdr msg = {
		.msg_flags	= MSG_DONTWAIT,
	};
	int len;
	struct msghdr msg = { NULL };
	ssize_t len;

	rqstp->rq_xprt_hlen = 0;

	clear_bit(XPT_DATA, &svsk->sk_xprt.xpt_flags);
	iov_iter_kvec(&msg.msg_iter, READ | ITER_KVEC, iov, nr, buflen);
	len = sock_recvmsg(svsk->sk_sock, &msg, msg.msg_flags);
	if (base != 0) {
		iov_iter_advance(&msg.msg_iter, base);
		buflen -= base;
	}
	len = sock_recvmsg(svsk->sk_sock, &msg, MSG_DONTWAIT);
	/* If we read a full record, then assume there may be more
	 * data to read (stream based sockets only!)
	 */
	if (len == buflen)
		set_bit(XPT_DATA, &svsk->sk_xprt.xpt_flags);

	dprintk("svc: socket %p recvfrom(%p, %zu) = %d\n",
	dprintk("svc: socket %p recvfrom(%p, %zu) = %zd\n",
		svsk, iov[0].iov_base, iov[0].iov_len, len);
	return len;
}

static int svc_partial_recvfrom(struct svc_rqst *rqstp,
				struct kvec *iov, int nr,
				int buflen, unsigned int base)
{
	size_t save_iovlen;
	void *save_iovbase;
	unsigned int i;
	int ret;

	if (base == 0)
		return svc_recvfrom(rqstp, iov, nr, buflen);

	for (i = 0; i < nr; i++) {
		if (iov[i].iov_len > base)
			break;
		base -= iov[i].iov_len;
	}
	save_iovlen = iov[i].iov_len;
	save_iovbase = iov[i].iov_base;
	iov[i].iov_len -= base;
	iov[i].iov_base += base;
	ret = svc_recvfrom(rqstp, &iov[i], nr - i, buflen);
	iov[i].iov_len = save_iovlen;
	iov[i].iov_base = save_iovbase;
	return ret;
}

/*
 * Set socket snd and rcv buffer lengths
 */
@@ -962,7 +937,8 @@ static int svc_tcp_recv_record(struct svc_sock *svsk, struct svc_rqst *rqstp)
		want = sizeof(rpc_fraghdr) - svsk->sk_tcplen;
		iov.iov_base = ((char *) &svsk->sk_reclen) + svsk->sk_tcplen;
		iov.iov_len  = want;
		if ((len = svc_recvfrom(rqstp, &iov, 1, want)) < 0)
		len = svc_recvfrom(rqstp, &iov, 1, want, 0);
		if (len < 0)
			goto error;
		svsk->sk_tcplen += len;

@@ -1088,14 +1064,13 @@ static int svc_tcp_recvfrom(struct svc_rqst *rqstp)

	vec = rqstp->rq_vec;

	pnum = copy_pages_to_kvecs(&vec[0], &rqstp->rq_pages[0],
						svsk->sk_datalen + want);
	pnum = copy_pages_to_kvecs(&vec[0], &rqstp->rq_pages[0], base + want);

	rqstp->rq_respages = &rqstp->rq_pages[pnum];
	rqstp->rq_next_page = rqstp->rq_respages + 1;

	/* Now receive data */
	len = svc_partial_recvfrom(rqstp, vec, pnum, want, base);
	len = svc_recvfrom(rqstp, vec, pnum, base + want, base);
	if (len >= 0) {
		svsk->sk_tcplen += len;
		svsk->sk_datalen += len;