VSOCK: defer sock removal to transports
authorStefan Hajnoczi <stefanha@redhat.com>
Thu, 28 Jul 2016 14:36:31 +0000 (15:36 +0100)
committerMichael S. Tsirkin <mst@redhat.com>
Mon, 1 Aug 2016 23:57:28 +0000 (02:57 +0300)
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>
include/net/af_vsock.h
net/vmw_vsock/af_vsock.c
net/vmw_vsock/vmci_transport.c

index 23f55259b60d9454d40dc625f60220819e6c82e9..3af0b224f7544d48ca6bc6ea4f2fd424ef0411ec 100644 (file)
@@ -180,6 +180,7 @@ void vsock_remove_connected(struct vsock_sock *vsk);
 struct sock *vsock_find_bound_socket(struct sockaddr_vm *addr);
 struct sock *vsock_find_connected_socket(struct sockaddr_vm *src,
                                         struct sockaddr_vm *dst);
+void vsock_remove_sock(struct vsock_sock *vsk);
 void vsock_for_each_connected_socket(void (*fn)(struct sock *sk));
 
 #endif /* __AF_VSOCK_H__ */
index e34d96f8bde2794aff14b0c4ce5f23155c31a5a2..17dbbe64cd7321b440ea2ce68cb336e2be3e9fde 100644 (file)
@@ -344,6 +344,16 @@ static bool vsock_in_connected_table(struct vsock_sock *vsk)
        return ret;
 }
 
+void vsock_remove_sock(struct vsock_sock *vsk)
+{
+       if (vsock_in_bound_table(vsk))
+               vsock_remove_bound(vsk);
+
+       if (vsock_in_connected_table(vsk))
+               vsock_remove_connected(vsk);
+}
+EXPORT_SYMBOL_GPL(vsock_remove_sock);
+
 void vsock_for_each_connected_socket(void (*fn)(struct sock *sk))
 {
        int i;
@@ -660,12 +670,6 @@ static void __vsock_release(struct sock *sk)
                vsk = vsock_sk(sk);
                pending = NULL; /* Compiler warning. */
 
-               if (vsock_in_bound_table(vsk))
-                       vsock_remove_bound(vsk);
-
-               if (vsock_in_connected_table(vsk))
-                       vsock_remove_connected(vsk);
-
                transport->release(vsk);
 
                lock_sock(sk);
index 4120b7a538be933dae935a6785e6d20ecf1afa32..4be4fbbc0b5035662b1cd756bd4e99dd3351309e 100644 (file)
@@ -1644,6 +1644,8 @@ static void vmci_transport_destruct(struct vsock_sock *vsk)
 
 static void vmci_transport_release(struct vsock_sock *vsk)
 {
+       vsock_remove_sock(vsk);
+
        if (!vmci_handle_is_invalid(vmci_trans(vsk)->dg_handle)) {
                vmci_datagram_destroy_handle(vmci_trans(vsk)->dg_handle);
                vmci_trans(vsk)->dg_handle = VMCI_INVALID_HANDLE;