Commit fff1ebb2 authored by Chuck Lever's avatar Chuck Lever

SUNRPC: Restructure svc_udp_recvfrom()

Clean up. At this point, we are not ready yet to support bio_vecs in
the UDP transport implementation. However, we can clean up
svc_udp_recvfrom() to match the tracing and straight-lining recently
changes made in svc_tcp_recvfrom().
Signed-off-by: default avatarChuck Lever <chuck.lever@oracle.com>
parent ca07eda3
...@@ -1501,6 +1501,8 @@ DECLARE_EVENT_CLASS(svcsock_class, ...@@ -1501,6 +1501,8 @@ DECLARE_EVENT_CLASS(svcsock_class,
TP_ARGS(xprt, result)) TP_ARGS(xprt, result))
DEFINE_SVCSOCK_EVENT(udp_send); DEFINE_SVCSOCK_EVENT(udp_send);
DEFINE_SVCSOCK_EVENT(udp_recv);
DEFINE_SVCSOCK_EVENT(udp_recv_err);
DEFINE_SVCSOCK_EVENT(tcp_send); DEFINE_SVCSOCK_EVENT(tcp_send);
DEFINE_SVCSOCK_EVENT(tcp_recv); DEFINE_SVCSOCK_EVENT(tcp_recv);
DEFINE_SVCSOCK_EVENT(tcp_recv_eagain); DEFINE_SVCSOCK_EVENT(tcp_recv_eagain);
......
...@@ -425,8 +425,15 @@ static int svc_udp_get_dest_address(struct svc_rqst *rqstp, ...@@ -425,8 +425,15 @@ static int svc_udp_get_dest_address(struct svc_rqst *rqstp,
return 0; return 0;
} }
/* /**
* Receive a datagram from a UDP socket. * svc_udp_recvfrom - Receive a datagram from a UDP socket.
* @rqstp: request structure into which to receive an RPC Call
*
* Called in a loop when XPT_DATA has been set.
*
* Returns:
* On success, the number of bytes in a received RPC Call, or
* %0 if a complete RPC Call message was not ready to return
*/ */
static int svc_udp_recvfrom(struct svc_rqst *rqstp) static int svc_udp_recvfrom(struct svc_rqst *rqstp)
{ {
...@@ -460,20 +467,14 @@ static int svc_udp_recvfrom(struct svc_rqst *rqstp) ...@@ -460,20 +467,14 @@ static int svc_udp_recvfrom(struct svc_rqst *rqstp)
svc_sock_setbufsize(svsk, serv->sv_nrthreads + 3); svc_sock_setbufsize(svsk, serv->sv_nrthreads + 3);
clear_bit(XPT_DATA, &svsk->sk_xprt.xpt_flags); clear_bit(XPT_DATA, &svsk->sk_xprt.xpt_flags);
skb = NULL;
err = kernel_recvmsg(svsk->sk_sock, &msg, NULL, err = kernel_recvmsg(svsk->sk_sock, &msg, NULL,
0, 0, MSG_PEEK | MSG_DONTWAIT); 0, 0, MSG_PEEK | MSG_DONTWAIT);
if (err >= 0) if (err < 0)
skb = skb_recv_udp(svsk->sk_sk, 0, 1, &err); goto out_recv_err;
skb = skb_recv_udp(svsk->sk_sk, 0, 1, &err);
if (skb == NULL) { if (!skb)
if (err != -EAGAIN) { goto out_recv_err;
/* possibly an icmp error */
dprintk("svc: recvfrom returned error %d\n", -err);
set_bit(XPT_DATA, &svsk->sk_xprt.xpt_flags);
}
return 0;
}
len = svc_addr_len(svc_addr(rqstp)); len = svc_addr_len(svc_addr(rqstp));
rqstp->rq_addrlen = len; rqstp->rq_addrlen = len;
if (skb->tstamp == 0) { if (skb->tstamp == 0) {
...@@ -484,26 +485,21 @@ static int svc_udp_recvfrom(struct svc_rqst *rqstp) ...@@ -484,26 +485,21 @@ static int svc_udp_recvfrom(struct svc_rqst *rqstp)
sock_write_timestamp(svsk->sk_sk, skb->tstamp); sock_write_timestamp(svsk->sk_sk, skb->tstamp);
set_bit(XPT_DATA, &svsk->sk_xprt.xpt_flags); /* there may be more data... */ set_bit(XPT_DATA, &svsk->sk_xprt.xpt_flags); /* there may be more data... */
len = skb->len; len = skb->len;
rqstp->rq_arg.len = len; rqstp->rq_arg.len = len;
trace_svcsock_udp_recv(&svsk->sk_xprt, len);
rqstp->rq_prot = IPPROTO_UDP; rqstp->rq_prot = IPPROTO_UDP;
if (!svc_udp_get_dest_address(rqstp, cmh)) { if (!svc_udp_get_dest_address(rqstp, cmh))
net_warn_ratelimited("svc: received unknown control message %d/%d; dropping RPC reply datagram\n", goto out_cmsg_err;
cmh->cmsg_level, cmh->cmsg_type);
goto out_free;
}
rqstp->rq_daddrlen = svc_addr_len(svc_daddr(rqstp)); rqstp->rq_daddrlen = svc_addr_len(svc_daddr(rqstp));
if (skb_is_nonlinear(skb)) { if (skb_is_nonlinear(skb)) {
/* we have to copy */ /* we have to copy */
local_bh_disable(); local_bh_disable();
if (csum_partial_copy_to_xdr(&rqstp->rq_arg, skb)) { if (csum_partial_copy_to_xdr(&rqstp->rq_arg, skb))
local_bh_enable(); goto out_bh_enable;
/* checksum error */
goto out_free;
}
local_bh_enable(); local_bh_enable();
consume_skb(skb); consume_skb(skb);
} else { } else {
...@@ -531,6 +527,20 @@ static int svc_udp_recvfrom(struct svc_rqst *rqstp) ...@@ -531,6 +527,20 @@ static int svc_udp_recvfrom(struct svc_rqst *rqstp)
serv->sv_stats->netudpcnt++; serv->sv_stats->netudpcnt++;
return len; return len;
out_recv_err:
if (err != -EAGAIN) {
/* possibly an icmp error */
set_bit(XPT_DATA, &svsk->sk_xprt.xpt_flags);
}
trace_svcsock_udp_recv_err(&svsk->sk_xprt, err);
return 0;
out_cmsg_err:
net_warn_ratelimited("svc: received unknown control message %d/%d; dropping RPC reply datagram\n",
cmh->cmsg_level, cmh->cmsg_type);
goto out_free;
out_bh_enable:
local_bh_enable();
out_free: out_free:
kfree_skb(skb); kfree_skb(skb);
return 0; return 0;
......
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