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

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
...@@ -325,59 +325,34 @@ static int svc_one_sock_name(struct svc_sock *svsk, char *buf, int remaining) ...@@ -325,59 +325,34 @@ static int svc_one_sock_name(struct svc_sock *svsk, char *buf, int remaining)
/* /*
* Generic recvfrom routine. * Generic recvfrom routine.
*/ */
static int svc_recvfrom(struct svc_rqst *rqstp, struct kvec *iov, int nr, static ssize_t svc_recvfrom(struct svc_rqst *rqstp, struct kvec *iov,
int buflen) unsigned int nr, size_t buflen, unsigned int base)
{ {
struct svc_sock *svsk = struct svc_sock *svsk =
container_of(rqstp->rq_xprt, struct svc_sock, sk_xprt); container_of(rqstp->rq_xprt, struct svc_sock, sk_xprt);
struct msghdr msg = { struct msghdr msg = { NULL };
.msg_flags = MSG_DONTWAIT, ssize_t len;
};
int len;
rqstp->rq_xprt_hlen = 0; rqstp->rq_xprt_hlen = 0;
clear_bit(XPT_DATA, &svsk->sk_xprt.xpt_flags); clear_bit(XPT_DATA, &svsk->sk_xprt.xpt_flags);
iov_iter_kvec(&msg.msg_iter, READ | ITER_KVEC, iov, nr, buflen); 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 /* If we read a full record, then assume there may be more
* data to read (stream based sockets only!) * data to read (stream based sockets only!)
*/ */
if (len == buflen) if (len == buflen)
set_bit(XPT_DATA, &svsk->sk_xprt.xpt_flags); 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); svsk, iov[0].iov_base, iov[0].iov_len, len);
return 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 * 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) ...@@ -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; want = sizeof(rpc_fraghdr) - svsk->sk_tcplen;
iov.iov_base = ((char *) &svsk->sk_reclen) + svsk->sk_tcplen; iov.iov_base = ((char *) &svsk->sk_reclen) + svsk->sk_tcplen;
iov.iov_len = want; 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; goto error;
svsk->sk_tcplen += len; svsk->sk_tcplen += len;
...@@ -1088,14 +1064,13 @@ static int svc_tcp_recvfrom(struct svc_rqst *rqstp) ...@@ -1088,14 +1064,13 @@ static int svc_tcp_recvfrom(struct svc_rqst *rqstp)
vec = rqstp->rq_vec; vec = rqstp->rq_vec;
pnum = copy_pages_to_kvecs(&vec[0], &rqstp->rq_pages[0], pnum = copy_pages_to_kvecs(&vec[0], &rqstp->rq_pages[0], base + want);
svsk->sk_datalen + want);
rqstp->rq_respages = &rqstp->rq_pages[pnum]; rqstp->rq_respages = &rqstp->rq_pages[pnum];
rqstp->rq_next_page = rqstp->rq_respages + 1; rqstp->rq_next_page = rqstp->rq_respages + 1;
/* Now receive data */ /* Now receive data */
len = svc_partial_recvfrom(rqstp, vec, pnum, want, base); len = svc_recvfrom(rqstp, vec, pnum, base + want, base);
if (len >= 0) { if (len >= 0) {
svsk->sk_tcplen += len; svsk->sk_tcplen += len;
svsk->sk_datalen += len; svsk->sk_datalen += len;
......
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