| From foo@baz Thu Dec 21 09:02:40 CET 2017 |
| From: Peng Tao <bergwolf@gmail.com> |
| Date: Wed, 15 Mar 2017 09:32:17 +0800 |
| Subject: vsock: cancel packets when failing to connect |
| |
| From: Peng Tao <bergwolf@gmail.com> |
| |
| |
| [ Upstream commit 380feae0def7e6a115124a3219c3ec9b654dca32 ] |
| |
| Otherwise we'll leave the packets queued until releasing vsock device. |
| E.g., if guest is slow to start up, resulting ETIMEDOUT on connect, guest |
| will get the connect requests from failed host sockets. |
| |
| Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com> |
| Reviewed-by: Jorgen Hansen <jhansen@vmware.com> |
| Signed-off-by: Peng Tao <bergwolf@gmail.com> |
| Signed-off-by: David S. Miller <davem@davemloft.net> |
| Signed-off-by: Sasha Levin <alexander.levin@verizon.com> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| --- |
| net/vmw_vsock/af_vsock.c | 14 ++++++++++++++ |
| 1 file changed, 14 insertions(+) |
| |
| --- a/net/vmw_vsock/af_vsock.c |
| +++ b/net/vmw_vsock/af_vsock.c |
| @@ -1101,10 +1101,19 @@ static const struct proto_ops vsock_dgra |
| .sendpage = sock_no_sendpage, |
| }; |
| |
| +static int vsock_transport_cancel_pkt(struct vsock_sock *vsk) |
| +{ |
| + if (!transport->cancel_pkt) |
| + return -EOPNOTSUPP; |
| + |
| + return transport->cancel_pkt(vsk); |
| +} |
| + |
| static void vsock_connect_timeout(struct work_struct *work) |
| { |
| struct sock *sk; |
| struct vsock_sock *vsk; |
| + int cancel = 0; |
| |
| vsk = container_of(work, struct vsock_sock, dwork.work); |
| sk = sk_vsock(vsk); |
| @@ -1115,8 +1124,11 @@ static void vsock_connect_timeout(struct |
| sk->sk_state = SS_UNCONNECTED; |
| sk->sk_err = ETIMEDOUT; |
| sk->sk_error_report(sk); |
| + cancel = 1; |
| } |
| release_sock(sk); |
| + if (cancel) |
| + vsock_transport_cancel_pkt(vsk); |
| |
| sock_put(sk); |
| } |
| @@ -1223,11 +1235,13 @@ static int vsock_stream_connect(struct s |
| err = sock_intr_errno(timeout); |
| sk->sk_state = SS_UNCONNECTED; |
| sock->state = SS_UNCONNECTED; |
| + vsock_transport_cancel_pkt(vsk); |
| goto out_wait; |
| } else if (timeout == 0) { |
| err = -ETIMEDOUT; |
| sk->sk_state = SS_UNCONNECTED; |
| sock->state = SS_UNCONNECTED; |
| + vsock_transport_cancel_pkt(vsk); |
| goto out_wait; |
| } |
| |