diff options
author | Stefan Hajnoczi <stefanha@redhat.com> | 2016-07-28 10:36:31 -0400 |
---|---|---|
committer | Michael S. Tsirkin <mst@redhat.com> | 2016-08-01 19:57:28 -0400 |
commit | 6773b7dc39f165bd9d824b50ac52cbb3f87d53c8 (patch) | |
tree | eec9a1d84ed6d1c3113cd35c47887d6dd42d4448 | |
parent | 0b01aeb3d2fbf16787f0c9629f4ca52ae792f732 (diff) |
VSOCK: defer sock removal to transports
The virtio transport will implement graceful shutdown and the related
SO_LINGER socket option. This requires orphaning the sock but keeping
it in the table of connections after .release().
This patch adds the vsock_remove_sock() function and leaves it up to the
transport when to remove the sock.
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
-rw-r--r-- | include/net/af_vsock.h | 1 | ||||
-rw-r--r-- | net/vmw_vsock/af_vsock.c | 16 | ||||
-rw-r--r-- | net/vmw_vsock/vmci_transport.c | 2 |
3 files changed, 13 insertions, 6 deletions
diff --git a/include/net/af_vsock.h b/include/net/af_vsock.h index 23f55259b60d..3af0b224f754 100644 --- a/include/net/af_vsock.h +++ b/include/net/af_vsock.h | |||
@@ -180,6 +180,7 @@ void vsock_remove_connected(struct vsock_sock *vsk); | |||
180 | struct sock *vsock_find_bound_socket(struct sockaddr_vm *addr); | 180 | struct sock *vsock_find_bound_socket(struct sockaddr_vm *addr); |
181 | struct sock *vsock_find_connected_socket(struct sockaddr_vm *src, | 181 | struct sock *vsock_find_connected_socket(struct sockaddr_vm *src, |
182 | struct sockaddr_vm *dst); | 182 | struct sockaddr_vm *dst); |
183 | void vsock_remove_sock(struct vsock_sock *vsk); | ||
183 | void vsock_for_each_connected_socket(void (*fn)(struct sock *sk)); | 184 | void vsock_for_each_connected_socket(void (*fn)(struct sock *sk)); |
184 | 185 | ||
185 | #endif /* __AF_VSOCK_H__ */ | 186 | #endif /* __AF_VSOCK_H__ */ |
diff --git a/net/vmw_vsock/af_vsock.c b/net/vmw_vsock/af_vsock.c index e34d96f8bde2..17dbbe64cd73 100644 --- a/net/vmw_vsock/af_vsock.c +++ b/net/vmw_vsock/af_vsock.c | |||
@@ -344,6 +344,16 @@ static bool vsock_in_connected_table(struct vsock_sock *vsk) | |||
344 | return ret; | 344 | return ret; |
345 | } | 345 | } |
346 | 346 | ||
347 | void vsock_remove_sock(struct vsock_sock *vsk) | ||
348 | { | ||
349 | if (vsock_in_bound_table(vsk)) | ||
350 | vsock_remove_bound(vsk); | ||
351 | |||
352 | if (vsock_in_connected_table(vsk)) | ||
353 | vsock_remove_connected(vsk); | ||
354 | } | ||
355 | EXPORT_SYMBOL_GPL(vsock_remove_sock); | ||
356 | |||
347 | void vsock_for_each_connected_socket(void (*fn)(struct sock *sk)) | 357 | void vsock_for_each_connected_socket(void (*fn)(struct sock *sk)) |
348 | { | 358 | { |
349 | int i; | 359 | int i; |
@@ -660,12 +670,6 @@ static void __vsock_release(struct sock *sk) | |||
660 | vsk = vsock_sk(sk); | 670 | vsk = vsock_sk(sk); |
661 | pending = NULL; /* Compiler warning. */ | 671 | pending = NULL; /* Compiler warning. */ |
662 | 672 | ||
663 | if (vsock_in_bound_table(vsk)) | ||
664 | vsock_remove_bound(vsk); | ||
665 | |||
666 | if (vsock_in_connected_table(vsk)) | ||
667 | vsock_remove_connected(vsk); | ||
668 | |||
669 | transport->release(vsk); | 673 | transport->release(vsk); |
670 | 674 | ||
671 | lock_sock(sk); | 675 | lock_sock(sk); |
diff --git a/net/vmw_vsock/vmci_transport.c b/net/vmw_vsock/vmci_transport.c index 4120b7a538be..4be4fbbc0b50 100644 --- a/net/vmw_vsock/vmci_transport.c +++ b/net/vmw_vsock/vmci_transport.c | |||
@@ -1644,6 +1644,8 @@ static void vmci_transport_destruct(struct vsock_sock *vsk) | |||
1644 | 1644 | ||
1645 | static void vmci_transport_release(struct vsock_sock *vsk) | 1645 | static void vmci_transport_release(struct vsock_sock *vsk) |
1646 | { | 1646 | { |
1647 | vsock_remove_sock(vsk); | ||
1648 | |||
1647 | if (!vmci_handle_is_invalid(vmci_trans(vsk)->dg_handle)) { | 1649 | if (!vmci_handle_is_invalid(vmci_trans(vsk)->dg_handle)) { |
1648 | vmci_datagram_destroy_handle(vmci_trans(vsk)->dg_handle); | 1650 | vmci_datagram_destroy_handle(vmci_trans(vsk)->dg_handle); |
1649 | vmci_trans(vsk)->dg_handle = VMCI_INVALID_HANDLE; | 1651 | vmci_trans(vsk)->dg_handle = VMCI_INVALID_HANDLE; |