aboutsummaryrefslogtreecommitdiffstats
path: root/net/unix/af_unix.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/unix/af_unix.c')
-rw-r--r--net/unix/af_unix.c55
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)