diff options
Diffstat (limited to 'net/unix/af_unix.c')
-rw-r--r-- | net/unix/af_unix.c | 55 |
1 files changed, 32 insertions, 23 deletions
diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c index 2268e679812..ba5b8c20849 100644 --- a/net/unix/af_unix.c +++ b/net/unix/af_unix.c | |||
@@ -316,7 +316,8 @@ static void unix_write_space(struct sock *sk) | |||
316 | if (unix_writable(sk)) { | 316 | if (unix_writable(sk)) { |
317 | wq = rcu_dereference(sk->sk_wq); | 317 | wq = rcu_dereference(sk->sk_wq); |
318 | if (wq_has_sleeper(wq)) | 318 | if (wq_has_sleeper(wq)) |
319 | wake_up_interruptible_sync(&wq->wait); | 319 | wake_up_interruptible_sync_poll(&wq->wait, |
320 | POLLOUT | POLLWRNORM | POLLWRBAND); | ||
320 | sk_wake_async(sk, SOCK_WAKE_SPACE, POLL_OUT); | 321 | sk_wake_async(sk, SOCK_WAKE_SPACE, POLL_OUT); |
321 | } | 322 | } |
322 | rcu_read_unlock(); | 323 | rcu_read_unlock(); |
@@ -849,7 +850,7 @@ static int unix_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len) | |||
849 | * Get the parent directory, calculate the hash for last | 850 | * Get the parent directory, calculate the hash for last |
850 | * component. | 851 | * component. |
851 | */ | 852 | */ |
852 | err = path_lookup(sunaddr->sun_path, LOOKUP_PARENT, &nd); | 853 | err = kern_path_parent(sunaddr->sun_path, &nd); |
853 | if (err) | 854 | if (err) |
854 | goto out_mknod_parent; | 855 | goto out_mknod_parent; |
855 | 856 | ||
@@ -1156,7 +1157,7 @@ restart: | |||
1156 | goto restart; | 1157 | goto restart; |
1157 | } | 1158 | } |
1158 | 1159 | ||
1159 | err = security_unix_stream_connect(sock, other->sk_socket, newsk); | 1160 | err = security_unix_stream_connect(sk, other, newsk); |
1160 | if (err) { | 1161 | if (err) { |
1161 | unix_state_unlock(sk); | 1162 | unix_state_unlock(sk); |
1162 | goto out_unlock; | 1163 | goto out_unlock; |
@@ -1723,7 +1724,11 @@ static int unix_dgram_recvmsg(struct kiocb *iocb, struct socket *sock, | |||
1723 | 1724 | ||
1724 | msg->msg_namelen = 0; | 1725 | msg->msg_namelen = 0; |
1725 | 1726 | ||
1726 | mutex_lock(&u->readlock); | 1727 | err = mutex_lock_interruptible(&u->readlock); |
1728 | if (err) { | ||
1729 | err = sock_intr_errno(sock_rcvtimeo(sk, noblock)); | ||
1730 | goto out; | ||
1731 | } | ||
1727 | 1732 | ||
1728 | skb = skb_recv_datagram(sk, flags, noblock, &err); | 1733 | skb = skb_recv_datagram(sk, flags, noblock, &err); |
1729 | if (!skb) { | 1734 | if (!skb) { |
@@ -1736,7 +1741,8 @@ static int unix_dgram_recvmsg(struct kiocb *iocb, struct socket *sock, | |||
1736 | goto out_unlock; | 1741 | goto out_unlock; |
1737 | } | 1742 | } |
1738 | 1743 | ||
1739 | wake_up_interruptible_sync(&u->peer_wait); | 1744 | wake_up_interruptible_sync_poll(&u->peer_wait, |
1745 | POLLOUT | POLLWRNORM | POLLWRBAND); | ||
1740 | 1746 | ||
1741 | if (msg->msg_name) | 1747 | if (msg->msg_name) |
1742 | unix_copy_addr(msg, skb->sk); | 1748 | unix_copy_addr(msg, skb->sk); |
@@ -1862,7 +1868,11 @@ static int unix_stream_recvmsg(struct kiocb *iocb, struct socket *sock, | |||
1862 | memset(&tmp_scm, 0, sizeof(tmp_scm)); | 1868 | memset(&tmp_scm, 0, sizeof(tmp_scm)); |
1863 | } | 1869 | } |
1864 | 1870 | ||
1865 | mutex_lock(&u->readlock); | 1871 | err = mutex_lock_interruptible(&u->readlock); |
1872 | if (err) { | ||
1873 | err = sock_intr_errno(timeo); | ||
1874 | goto out; | ||
1875 | } | ||
1866 | 1876 | ||
1867 | do { | 1877 | do { |
1868 | int chunk; | 1878 | int chunk; |
@@ -1893,11 +1903,12 @@ static int unix_stream_recvmsg(struct kiocb *iocb, struct socket *sock, | |||
1893 | 1903 | ||
1894 | timeo = unix_stream_data_wait(sk, timeo); | 1904 | timeo = unix_stream_data_wait(sk, timeo); |
1895 | 1905 | ||
1896 | if (signal_pending(current)) { | 1906 | if (signal_pending(current) |
1907 | || mutex_lock_interruptible(&u->readlock)) { | ||
1897 | err = sock_intr_errno(timeo); | 1908 | err = sock_intr_errno(timeo); |
1898 | goto out; | 1909 | goto out; |
1899 | } | 1910 | } |
1900 | mutex_lock(&u->readlock); | 1911 | |
1901 | continue; | 1912 | continue; |
1902 | unlock: | 1913 | unlock: |
1903 | unix_state_unlock(sk); | 1914 | unix_state_unlock(sk); |
@@ -2099,13 +2110,12 @@ static unsigned int unix_dgram_poll(struct file *file, struct socket *sock, | |||
2099 | if (sk->sk_err || !skb_queue_empty(&sk->sk_error_queue)) | 2110 | if (sk->sk_err || !skb_queue_empty(&sk->sk_error_queue)) |
2100 | mask |= POLLERR; | 2111 | mask |= POLLERR; |
2101 | if (sk->sk_shutdown & RCV_SHUTDOWN) | 2112 | if (sk->sk_shutdown & RCV_SHUTDOWN) |
2102 | mask |= POLLRDHUP; | 2113 | mask |= POLLRDHUP | POLLIN | POLLRDNORM; |
2103 | if (sk->sk_shutdown == SHUTDOWN_MASK) | 2114 | if (sk->sk_shutdown == SHUTDOWN_MASK) |
2104 | mask |= POLLHUP; | 2115 | mask |= POLLHUP; |
2105 | 2116 | ||
2106 | /* readable? */ | 2117 | /* readable? */ |
2107 | if (!skb_queue_empty(&sk->sk_receive_queue) || | 2118 | if (!skb_queue_empty(&sk->sk_receive_queue)) |
2108 | (sk->sk_shutdown & RCV_SHUTDOWN)) | ||
2109 | mask |= POLLIN | POLLRDNORM; | 2119 | mask |= POLLIN | POLLRDNORM; |
2110 | 2120 | ||
2111 | /* Connection-based need to check for termination and startup */ | 2121 | /* Connection-based need to check for termination and startup */ |
@@ -2117,20 +2127,19 @@ static unsigned int unix_dgram_poll(struct file *file, struct socket *sock, | |||
2117 | return mask; | 2127 | return mask; |
2118 | } | 2128 | } |
2119 | 2129 | ||
2120 | /* writable? */ | 2130 | /* No write status requested, avoid expensive OUT tests. */ |
2121 | writable = unix_writable(sk); | 2131 | if (wait && !(wait->key & (POLLWRBAND | POLLWRNORM | POLLOUT))) |
2122 | if (writable) { | 2132 | return mask; |
2123 | other = unix_peer_get(sk); | ||
2124 | if (other) { | ||
2125 | if (unix_peer(other) != sk) { | ||
2126 | sock_poll_wait(file, &unix_sk(other)->peer_wait, | ||
2127 | wait); | ||
2128 | if (unix_recvq_full(other)) | ||
2129 | writable = 0; | ||
2130 | } | ||
2131 | 2133 | ||
2132 | sock_put(other); | 2134 | writable = unix_writable(sk); |
2135 | other = unix_peer_get(sk); | ||
2136 | if (other) { | ||
2137 | if (unix_peer(other) != sk) { | ||
2138 | sock_poll_wait(file, &unix_sk(other)->peer_wait, wait); | ||
2139 | if (unix_recvq_full(other)) | ||
2140 | writable = 0; | ||
2133 | } | 2141 | } |
2142 | sock_put(other); | ||
2134 | } | 2143 | } |
2135 | 2144 | ||
2136 | if (writable) | 2145 | if (writable) |