diff options
author | Parthasarathy Bhuvaragan <parthasarathy.bhuvaragan@gmail.com> | 2019-05-09 01:13:42 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2019-05-09 12:26:09 -0400 |
commit | ff946833b70e0c7f93de9a3f5b329b5ae2287b38 (patch) | |
tree | 3e765dd8dbd1455ace9773bf0a561b466fd413e8 /net/tipc/socket.c | |
parent | 9871a9e47a2646fe30ae7fd2e67668a8d30912f6 (diff) |
tipc: fix hanging clients using poll with EPOLLOUT flag
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>
Diffstat (limited to 'net/tipc/socket.c')
-rw-r--r-- | net/tipc/socket.c | 4 |
1 files changed, 2 insertions, 2 deletions
diff --git a/net/tipc/socket.c b/net/tipc/socket.c index 145e4decb0c9..dd8537f988c4 100644 --- a/net/tipc/socket.c +++ b/net/tipc/socket.c | |||
@@ -736,11 +736,11 @@ static __poll_t tipc_poll(struct file *file, struct socket *sock, | |||
736 | 736 | ||
737 | switch (sk->sk_state) { | 737 | switch (sk->sk_state) { |
738 | case TIPC_ESTABLISHED: | 738 | case TIPC_ESTABLISHED: |
739 | case TIPC_CONNECTING: | ||
740 | if (!tsk->cong_link_cnt && !tsk_conn_cong(tsk)) | 739 | if (!tsk->cong_link_cnt && !tsk_conn_cong(tsk)) |
741 | revents |= EPOLLOUT; | 740 | revents |= EPOLLOUT; |
742 | /* fall through */ | 741 | /* fall through */ |
743 | case TIPC_LISTEN: | 742 | case TIPC_LISTEN: |
743 | case TIPC_CONNECTING: | ||
744 | if (!skb_queue_empty(&sk->sk_receive_queue)) | 744 | if (!skb_queue_empty(&sk->sk_receive_queue)) |
745 | revents |= EPOLLIN | EPOLLRDNORM; | 745 | revents |= EPOLLIN | EPOLLRDNORM; |
746 | break; | 746 | break; |
@@ -2043,7 +2043,7 @@ static bool tipc_sk_filter_connect(struct tipc_sock *tsk, struct sk_buff *skb) | |||
2043 | if (msg_data_sz(hdr)) | 2043 | if (msg_data_sz(hdr)) |
2044 | return true; | 2044 | return true; |
2045 | /* Empty ACK-, - wake up sleeping connect() and drop */ | 2045 | /* Empty ACK-, - wake up sleeping connect() and drop */ |
2046 | sk->sk_data_ready(sk); | 2046 | sk->sk_state_change(sk); |
2047 | msg_set_dest_droppable(hdr, 1); | 2047 | msg_set_dest_droppable(hdr, 1); |
2048 | return false; | 2048 | return false; |
2049 | } | 2049 | } |