diff options
Diffstat (limited to 'net')
-rw-r--r-- | net/sunrpc/svcsock.c | 21 |
1 files changed, 13 insertions, 8 deletions
diff --git a/net/sunrpc/svcsock.c b/net/sunrpc/svcsock.c index fdb1386f5dcd..5baf48de2558 100644 --- a/net/sunrpc/svcsock.c +++ b/net/sunrpc/svcsock.c | |||
@@ -788,15 +788,20 @@ svc_udp_recvfrom(struct svc_rqst *rqstp) | |||
788 | } | 788 | } |
789 | 789 | ||
790 | clear_bit(SK_DATA, &svsk->sk_flags); | 790 | clear_bit(SK_DATA, &svsk->sk_flags); |
791 | while ((err = kernel_recvmsg(svsk->sk_sock, &msg, NULL, | 791 | skb = NULL; |
792 | 0, 0, MSG_PEEK | MSG_DONTWAIT)) < 0 || | 792 | err = kernel_recvmsg(svsk->sk_sock, &msg, NULL, |
793 | (skb = skb_recv_datagram(svsk->sk_sk, 0, 1, &err)) == NULL) { | 793 | 0, 0, MSG_PEEK | MSG_DONTWAIT); |
794 | if (err == -EAGAIN) { | 794 | if (err >= 0) |
795 | svc_sock_received(svsk); | 795 | skb = skb_recv_datagram(svsk->sk_sk, 0, 1, &err); |
796 | return err; | 796 | |
797 | if (skb == NULL) { | ||
798 | if (err != -EAGAIN) { | ||
799 | /* possibly an icmp error */ | ||
800 | dprintk("svc: recvfrom returned error %d\n", -err); | ||
801 | set_bit(SK_DATA, &svsk->sk_flags); | ||
797 | } | 802 | } |
798 | /* possibly an icmp error */ | 803 | svc_sock_received(svsk); |
799 | dprintk("svc: recvfrom returned error %d\n", -err); | 804 | return -EAGAIN; |
800 | } | 805 | } |
801 | rqstp->rq_addrlen = sizeof(rqstp->rq_addr); | 806 | rqstp->rq_addrlen = sizeof(rqstp->rq_addr); |
802 | if (skb->tstamp.tv64 == 0) { | 807 | if (skb->tstamp.tv64 == 0) { |