summaryrefslogtreecommitdiff
path: root/net
diff options
context:
space:
mode:
authorParthasarathy Bhuvaragan <parthasarathy.bhuvaragan@gmail.com>2019-05-09 08:13:42 +0300
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2019-05-16 20:35:37 +0300
commit5338e8ff22f3180cfafa74b3f9aa92c03c39cc1e (patch)
treea859b4a5fea2c39c5c4c482ad8e9f03c96b06b98 /net
parent17617cd5557ac5b82b3d7da71772e02f2258805b (diff)
downloadlinux-5338e8ff22f3180cfafa74b3f9aa92c03c39cc1e.tar.xz
tipc: fix hanging clients using poll with EPOLLOUT flag
[ Upstream commit ff946833b70e0c7f93de9a3f5b329b5ae2287b38 ] commit 517d7c79bdb398 ("tipc: fix hanging poll() for stream sockets") introduced a regression for clients using non-blocking sockets. After the commit, we send EPOLLOUT event to the client even in TIPC_CONNECTING state. This causes the subsequent send() to fail with ENOTCONN, as the socket is still not in TIPC_ESTABLISHED state. In this commit, we: - improve the fix for hanging poll() by replacing sk_data_ready() with sk_state_change() to wake up all clients. - revert the faulty updates introduced by commit 517d7c79bdb398 ("tipc: fix hanging poll() for stream sockets"). Fixes: 517d7c79bdb398 ("tipc: fix hanging poll() for stream sockets") Signed-off-by: Parthasarathy Bhuvaragan <parthasarathy.bhuvaragan@gmail.com> Acked-by: Jon Maloy <jon.maloy@ericsson.se> Signed-off-by: David S. Miller <davem@davemloft.net> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'net')
-rw-r--r--net/tipc/socket.c4
1 files changed, 2 insertions, 2 deletions
diff --git a/net/tipc/socket.c b/net/tipc/socket.c
index b542f14ed444..2851937f6e32 100644
--- a/net/tipc/socket.c
+++ b/net/tipc/socket.c
@@ -734,11 +734,11 @@ static __poll_t tipc_poll(struct file *file, struct socket *sock,
switch (sk->sk_state) {
case TIPC_ESTABLISHED:
- case TIPC_CONNECTING:
if (!tsk->cong_link_cnt && !tsk_conn_cong(tsk))
revents |= EPOLLOUT;
/* fall through */
case TIPC_LISTEN:
+ case TIPC_CONNECTING:
if (!skb_queue_empty(&sk->sk_receive_queue))
revents |= EPOLLIN | EPOLLRDNORM;
break;
@@ -2041,7 +2041,7 @@ static bool tipc_sk_filter_connect(struct tipc_sock *tsk, struct sk_buff *skb)
if (msg_data_sz(hdr))
return true;
/* Empty ACK-, - wake up sleeping connect() and drop */
- sk->sk_data_ready(sk);
+ sk->sk_state_change(sk);
msg_set_dest_droppable(hdr, 1);
return false;
}