diff options
Diffstat (limited to 'net/sunrpc/svcsock.c')
| -rw-r--r-- | net/sunrpc/svcsock.c | 34 |
1 files changed, 20 insertions, 14 deletions
diff --git a/net/sunrpc/svcsock.c b/net/sunrpc/svcsock.c index 22f61aee4824..5baf48de2558 100644 --- a/net/sunrpc/svcsock.c +++ b/net/sunrpc/svcsock.c | |||
| @@ -53,7 +53,8 @@ | |||
| 53 | * svc_serv->sv_lock protects sv_tempsocks, sv_permsocks, sv_tmpcnt. | 53 | * svc_serv->sv_lock protects sv_tempsocks, sv_permsocks, sv_tmpcnt. |
| 54 | * when both need to be taken (rare), svc_serv->sv_lock is first. | 54 | * when both need to be taken (rare), svc_serv->sv_lock is first. |
| 55 | * BKL protects svc_serv->sv_nrthread. | 55 | * BKL protects svc_serv->sv_nrthread. |
| 56 | * svc_sock->sk_defer_lock protects the svc_sock->sk_deferred list | 56 | * svc_sock->sk_lock protects the svc_sock->sk_deferred list |
| 57 | * and the ->sk_info_authunix cache. | ||
| 57 | * svc_sock->sk_flags.SK_BUSY prevents a svc_sock being enqueued multiply. | 58 | * svc_sock->sk_flags.SK_BUSY prevents a svc_sock being enqueued multiply. |
| 58 | * | 59 | * |
| 59 | * Some flags can be set to certain values at any time | 60 | * Some flags can be set to certain values at any time |
| @@ -787,15 +788,20 @@ svc_udp_recvfrom(struct svc_rqst *rqstp) | |||
| 787 | } | 788 | } |
| 788 | 789 | ||
| 789 | clear_bit(SK_DATA, &svsk->sk_flags); | 790 | clear_bit(SK_DATA, &svsk->sk_flags); |
| 790 | while ((err = kernel_recvmsg(svsk->sk_sock, &msg, NULL, | 791 | skb = NULL; |
| 791 | 0, 0, MSG_PEEK | MSG_DONTWAIT)) < 0 || | 792 | err = kernel_recvmsg(svsk->sk_sock, &msg, NULL, |
| 792 | (skb = skb_recv_datagram(svsk->sk_sk, 0, 1, &err)) == NULL) { | 793 | 0, 0, MSG_PEEK | MSG_DONTWAIT); |
| 793 | if (err == -EAGAIN) { | 794 | if (err >= 0) |
| 794 | svc_sock_received(svsk); | 795 | skb = skb_recv_datagram(svsk->sk_sk, 0, 1, &err); |
| 795 | 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); | ||
| 796 | } | 802 | } |
| 797 | /* possibly an icmp error */ | 803 | svc_sock_received(svsk); |
| 798 | dprintk("svc: recvfrom returned error %d\n", -err); | 804 | return -EAGAIN; |
| 799 | } | 805 | } |
| 800 | rqstp->rq_addrlen = sizeof(rqstp->rq_addr); | 806 | rqstp->rq_addrlen = sizeof(rqstp->rq_addr); |
| 801 | if (skb->tstamp.tv64 == 0) { | 807 | if (skb->tstamp.tv64 == 0) { |
| @@ -1633,7 +1639,7 @@ static struct svc_sock *svc_setup_socket(struct svc_serv *serv, | |||
| 1633 | svsk->sk_server = serv; | 1639 | svsk->sk_server = serv; |
| 1634 | atomic_set(&svsk->sk_inuse, 1); | 1640 | atomic_set(&svsk->sk_inuse, 1); |
| 1635 | svsk->sk_lastrecv = get_seconds(); | 1641 | svsk->sk_lastrecv = get_seconds(); |
| 1636 | spin_lock_init(&svsk->sk_defer_lock); | 1642 | spin_lock_init(&svsk->sk_lock); |
| 1637 | INIT_LIST_HEAD(&svsk->sk_deferred); | 1643 | INIT_LIST_HEAD(&svsk->sk_deferred); |
| 1638 | INIT_LIST_HEAD(&svsk->sk_ready); | 1644 | INIT_LIST_HEAD(&svsk->sk_ready); |
| 1639 | mutex_init(&svsk->sk_mutex); | 1645 | mutex_init(&svsk->sk_mutex); |
| @@ -1857,9 +1863,9 @@ static void svc_revisit(struct cache_deferred_req *dreq, int too_many) | |||
| 1857 | dprintk("revisit queued\n"); | 1863 | dprintk("revisit queued\n"); |
| 1858 | svsk = dr->svsk; | 1864 | svsk = dr->svsk; |
| 1859 | dr->svsk = NULL; | 1865 | dr->svsk = NULL; |
| 1860 | spin_lock_bh(&svsk->sk_defer_lock); | 1866 | spin_lock(&svsk->sk_lock); |
| 1861 | list_add(&dr->handle.recent, &svsk->sk_deferred); | 1867 | list_add(&dr->handle.recent, &svsk->sk_deferred); |
| 1862 | spin_unlock_bh(&svsk->sk_defer_lock); | 1868 | spin_unlock(&svsk->sk_lock); |
| 1863 | set_bit(SK_DEFERRED, &svsk->sk_flags); | 1869 | set_bit(SK_DEFERRED, &svsk->sk_flags); |
| 1864 | svc_sock_enqueue(svsk); | 1870 | svc_sock_enqueue(svsk); |
| 1865 | svc_sock_put(svsk); | 1871 | svc_sock_put(svsk); |
| @@ -1925,7 +1931,7 @@ static struct svc_deferred_req *svc_deferred_dequeue(struct svc_sock *svsk) | |||
| 1925 | 1931 | ||
| 1926 | if (!test_bit(SK_DEFERRED, &svsk->sk_flags)) | 1932 | if (!test_bit(SK_DEFERRED, &svsk->sk_flags)) |
| 1927 | return NULL; | 1933 | return NULL; |
| 1928 | spin_lock_bh(&svsk->sk_defer_lock); | 1934 | spin_lock(&svsk->sk_lock); |
| 1929 | clear_bit(SK_DEFERRED, &svsk->sk_flags); | 1935 | clear_bit(SK_DEFERRED, &svsk->sk_flags); |
| 1930 | if (!list_empty(&svsk->sk_deferred)) { | 1936 | if (!list_empty(&svsk->sk_deferred)) { |
| 1931 | dr = list_entry(svsk->sk_deferred.next, | 1937 | dr = list_entry(svsk->sk_deferred.next, |
| @@ -1934,6 +1940,6 @@ static struct svc_deferred_req *svc_deferred_dequeue(struct svc_sock *svsk) | |||
| 1934 | list_del_init(&dr->handle.recent); | 1940 | list_del_init(&dr->handle.recent); |
| 1935 | set_bit(SK_DEFERRED, &svsk->sk_flags); | 1941 | set_bit(SK_DEFERRED, &svsk->sk_flags); |
| 1936 | } | 1942 | } |
| 1937 | spin_unlock_bh(&svsk->sk_defer_lock); | 1943 | spin_unlock(&svsk->sk_lock); |
| 1938 | return dr; | 1944 | return dr; |
| 1939 | } | 1945 | } |
