diff options
Diffstat (limited to 'net/unix/af_unix.c')
| -rw-r--r-- | net/unix/af_unix.c | 43 |
1 files changed, 25 insertions, 18 deletions
diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c index e3f85bc8b135..c5bf5ef2bf89 100644 --- a/net/unix/af_unix.c +++ b/net/unix/af_unix.c | |||
| @@ -451,7 +451,7 @@ static void unix_write_space(struct sock *sk) | |||
| 451 | rcu_read_lock(); | 451 | rcu_read_lock(); |
| 452 | if (unix_writable(sk)) { | 452 | if (unix_writable(sk)) { |
| 453 | wq = rcu_dereference(sk->sk_wq); | 453 | wq = rcu_dereference(sk->sk_wq); |
| 454 | if (wq_has_sleeper(wq)) | 454 | if (skwq_has_sleeper(wq)) |
| 455 | wake_up_interruptible_sync_poll(&wq->wait, | 455 | wake_up_interruptible_sync_poll(&wq->wait, |
| 456 | POLLOUT | POLLWRNORM | POLLWRBAND); | 456 | POLLOUT | POLLWRNORM | POLLWRBAND); |
| 457 | sk_wake_async(sk, SOCK_WAKE_SPACE, POLL_OUT); | 457 | sk_wake_async(sk, SOCK_WAKE_SPACE, POLL_OUT); |
| @@ -2108,8 +2108,8 @@ static int unix_dgram_recvmsg(struct socket *sock, struct msghdr *msg, | |||
| 2108 | struct scm_cookie scm; | 2108 | struct scm_cookie scm; |
| 2109 | struct sock *sk = sock->sk; | 2109 | struct sock *sk = sock->sk; |
| 2110 | struct unix_sock *u = unix_sk(sk); | 2110 | struct unix_sock *u = unix_sk(sk); |
| 2111 | int noblock = flags & MSG_DONTWAIT; | 2111 | struct sk_buff *skb, *last; |
| 2112 | struct sk_buff *skb; | 2112 | long timeo; |
| 2113 | int err; | 2113 | int err; |
| 2114 | int peeked, skip; | 2114 | int peeked, skip; |
| 2115 | 2115 | ||
| @@ -2117,30 +2117,38 @@ static int unix_dgram_recvmsg(struct socket *sock, struct msghdr *msg, | |||
| 2117 | if (flags&MSG_OOB) | 2117 | if (flags&MSG_OOB) |
| 2118 | goto out; | 2118 | goto out; |
| 2119 | 2119 | ||
| 2120 | err = mutex_lock_interruptible(&u->readlock); | 2120 | timeo = sock_rcvtimeo(sk, flags & MSG_DONTWAIT); |
| 2121 | if (unlikely(err)) { | ||
| 2122 | /* recvmsg() in non blocking mode is supposed to return -EAGAIN | ||
| 2123 | * sk_rcvtimeo is not honored by mutex_lock_interruptible() | ||
| 2124 | */ | ||
| 2125 | err = noblock ? -EAGAIN : -ERESTARTSYS; | ||
| 2126 | goto out; | ||
| 2127 | } | ||
| 2128 | 2121 | ||
| 2129 | skip = sk_peek_offset(sk, flags); | 2122 | do { |
| 2123 | mutex_lock(&u->readlock); | ||
| 2130 | 2124 | ||
| 2131 | skb = __skb_recv_datagram(sk, flags, &peeked, &skip, &err); | 2125 | skip = sk_peek_offset(sk, flags); |
| 2132 | if (!skb) { | 2126 | skb = __skb_try_recv_datagram(sk, flags, &peeked, &skip, &err, |
| 2127 | &last); | ||
| 2128 | if (skb) | ||
| 2129 | break; | ||
| 2130 | |||
| 2131 | mutex_unlock(&u->readlock); | ||
| 2132 | |||
| 2133 | if (err != -EAGAIN) | ||
| 2134 | break; | ||
| 2135 | } while (timeo && | ||
| 2136 | !__skb_wait_for_more_packets(sk, &err, &timeo, last)); | ||
| 2137 | |||
| 2138 | if (!skb) { /* implies readlock unlocked */ | ||
| 2133 | unix_state_lock(sk); | 2139 | unix_state_lock(sk); |
| 2134 | /* Signal EOF on disconnected non-blocking SEQPACKET socket. */ | 2140 | /* Signal EOF on disconnected non-blocking SEQPACKET socket. */ |
| 2135 | if (sk->sk_type == SOCK_SEQPACKET && err == -EAGAIN && | 2141 | if (sk->sk_type == SOCK_SEQPACKET && err == -EAGAIN && |
| 2136 | (sk->sk_shutdown & RCV_SHUTDOWN)) | 2142 | (sk->sk_shutdown & RCV_SHUTDOWN)) |
| 2137 | err = 0; | 2143 | err = 0; |
| 2138 | unix_state_unlock(sk); | 2144 | unix_state_unlock(sk); |
| 2139 | goto out_unlock; | 2145 | goto out; |
| 2140 | } | 2146 | } |
| 2141 | 2147 | ||
| 2142 | wake_up_interruptible_sync_poll(&u->peer_wait, | 2148 | if (wq_has_sleeper(&u->peer_wait)) |
| 2143 | POLLOUT | POLLWRNORM | POLLWRBAND); | 2149 | wake_up_interruptible_sync_poll(&u->peer_wait, |
| 2150 | POLLOUT | POLLWRNORM | | ||
| 2151 | POLLWRBAND); | ||
| 2144 | 2152 | ||
| 2145 | if (msg->msg_name) | 2153 | if (msg->msg_name) |
| 2146 | unix_copy_addr(msg, skb->sk); | 2154 | unix_copy_addr(msg, skb->sk); |
| @@ -2192,7 +2200,6 @@ static int unix_dgram_recvmsg(struct socket *sock, struct msghdr *msg, | |||
| 2192 | 2200 | ||
| 2193 | out_free: | 2201 | out_free: |
| 2194 | skb_free_datagram(sk, skb); | 2202 | skb_free_datagram(sk, skb); |
| 2195 | out_unlock: | ||
| 2196 | mutex_unlock(&u->readlock); | 2203 | mutex_unlock(&u->readlock); |
| 2197 | out: | 2204 | out: |
| 2198 | return err; | 2205 | return err; |
