提交 afa485dc 编写于 作者: P Parthasarathy Bhuvaragan 提交者: Greg Kroah-Hartman

tipc: fix hanging clients using poll with EPOLLOUT flag

[ Upstream commit ff946833b70e0c7f93de9a3f5b329b5ae2287b38 ]

commit 517d7c79 ("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 517d7c79
  ("tipc: fix hanging poll() for stream sockets").

Fixes: 517d7c79 ("tipc: fix hanging poll() for stream sockets")
Signed-off-by: NParthasarathy Bhuvaragan <parthasarathy.bhuvaragan@gmail.com>
Acked-by: NJon Maloy <jon.maloy@ericsson.se>
Signed-off-by: NDavid S. Miller <davem@davemloft.net>
Signed-off-by: NGreg Kroah-Hartman <gregkh@linuxfoundation.org>
上级 98652e0b
...@@ -726,11 +726,11 @@ static __poll_t tipc_poll(struct file *file, struct socket *sock, ...@@ -726,11 +726,11 @@ static __poll_t tipc_poll(struct file *file, struct socket *sock,
switch (sk->sk_state) { switch (sk->sk_state) {
case TIPC_ESTABLISHED: case TIPC_ESTABLISHED:
case TIPC_CONNECTING:
if (!tsk->cong_link_cnt && !tsk_conn_cong(tsk)) if (!tsk->cong_link_cnt && !tsk_conn_cong(tsk))
revents |= EPOLLOUT; revents |= EPOLLOUT;
/* fall thru' */ /* fall thru' */
case TIPC_LISTEN: case TIPC_LISTEN:
case TIPC_CONNECTING:
if (!skb_queue_empty(&sk->sk_receive_queue)) if (!skb_queue_empty(&sk->sk_receive_queue))
revents |= EPOLLIN | EPOLLRDNORM; revents |= EPOLLIN | EPOLLRDNORM;
break; break;
...@@ -2039,7 +2039,7 @@ static bool tipc_sk_filter_connect(struct tipc_sock *tsk, struct sk_buff *skb) ...@@ -2039,7 +2039,7 @@ static bool tipc_sk_filter_connect(struct tipc_sock *tsk, struct sk_buff *skb)
return true; return true;
/* If empty 'ACK-' message, wake up sleeping connect() */ /* If empty 'ACK-' message, wake up sleeping connect() */
sk->sk_data_ready(sk); sk->sk_state_change(sk);
/* 'ACK-' message is neither accepted nor rejected: */ /* 'ACK-' message is neither accepted nor rejected: */
msg_set_dest_droppable(hdr, 1); msg_set_dest_droppable(hdr, 1);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册