Skip to content

Commit 5ec4086

Browse files
mmhalPaolo Abeni
authored andcommitted
vsock: Move lingering logic to af_vsock core
Lingering should be transport-independent in the long run. In preparation for supporting other transports, as well as the linger on shutdown(), move code to core. Generalize by querying vsock_transport::unsent_bytes(), guard against the callback being unimplemented. Do not pass sk_lingertime explicitly. Pull SOCK_LINGER check into vsock_linger(). Flatten the function. Remove the nested block by inverting the condition: return early on !timeout. Suggested-by: Stefano Garzarella <[email protected]> Reviewed-by: Stefano Garzarella <[email protected]> Signed-off-by: Michal Luczaj <[email protected]> Link: https://patch.msgid.link/[email protected] Signed-off-by: Paolo Abeni <[email protected]>
1 parent 1c39f5d commit 5ec4086

File tree

3 files changed

+36
-21
lines changed

3 files changed

+36
-21
lines changed

include/net/af_vsock.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -221,6 +221,7 @@ void vsock_for_each_connected_socket(struct vsock_transport *transport,
221221
void (*fn)(struct sock *sk));
222222
int vsock_assign_transport(struct vsock_sock *vsk, struct vsock_sock *psk);
223223
bool vsock_find_cid(unsigned int cid);
224+
void vsock_linger(struct sock *sk);
224225

225226
/**** TAP ****/
226227

net/vmw_vsock/af_vsock.c

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1013,6 +1013,39 @@ static int vsock_getname(struct socket *sock,
10131013
return err;
10141014
}
10151015

1016+
void vsock_linger(struct sock *sk)
1017+
{
1018+
DEFINE_WAIT_FUNC(wait, woken_wake_function);
1019+
ssize_t (*unsent)(struct vsock_sock *vsk);
1020+
struct vsock_sock *vsk = vsock_sk(sk);
1021+
long timeout;
1022+
1023+
if (!sock_flag(sk, SOCK_LINGER))
1024+
return;
1025+
1026+
timeout = sk->sk_lingertime;
1027+
if (!timeout)
1028+
return;
1029+
1030+
/* Transports must implement `unsent_bytes` if they want to support
1031+
* SOCK_LINGER through `vsock_linger()` since we use it to check when
1032+
* the socket can be closed.
1033+
*/
1034+
unsent = vsk->transport->unsent_bytes;
1035+
if (!unsent)
1036+
return;
1037+
1038+
add_wait_queue(sk_sleep(sk), &wait);
1039+
1040+
do {
1041+
if (sk_wait_event(sk, &timeout, unsent(vsk) == 0, &wait))
1042+
break;
1043+
} while (!signal_pending(current) && timeout);
1044+
1045+
remove_wait_queue(sk_sleep(sk), &wait);
1046+
}
1047+
EXPORT_SYMBOL_GPL(vsock_linger);
1048+
10161049
static int vsock_shutdown(struct socket *sock, int mode)
10171050
{
10181051
int err;

net/vmw_vsock/virtio_transport_common.c

Lines changed: 2 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1191,25 +1191,6 @@ static void virtio_transport_remove_sock(struct vsock_sock *vsk)
11911191
vsock_remove_sock(vsk);
11921192
}
11931193

1194-
static void virtio_transport_wait_close(struct sock *sk, long timeout)
1195-
{
1196-
if (timeout) {
1197-
DEFINE_WAIT_FUNC(wait, woken_wake_function);
1198-
struct vsock_sock *vsk = vsock_sk(sk);
1199-
1200-
add_wait_queue(sk_sleep(sk), &wait);
1201-
1202-
do {
1203-
if (sk_wait_event(sk, &timeout,
1204-
virtio_transport_unsent_bytes(vsk) == 0,
1205-
&wait))
1206-
break;
1207-
} while (!signal_pending(current) && timeout);
1208-
1209-
remove_wait_queue(sk_sleep(sk), &wait);
1210-
}
1211-
}
1212-
12131194
static void virtio_transport_cancel_close_work(struct vsock_sock *vsk,
12141195
bool cancel_timeout)
12151196
{
@@ -1279,8 +1260,8 @@ static bool virtio_transport_close(struct vsock_sock *vsk)
12791260
if ((sk->sk_shutdown & SHUTDOWN_MASK) != SHUTDOWN_MASK)
12801261
(void)virtio_transport_shutdown(vsk, SHUTDOWN_MASK);
12811262

1282-
if (sock_flag(sk, SOCK_LINGER) && !(current->flags & PF_EXITING))
1283-
virtio_transport_wait_close(sk, sk->sk_lingertime);
1263+
if (!(current->flags & PF_EXITING))
1264+
vsock_linger(sk);
12841265

12851266
if (sock_flag(sk, SOCK_DONE)) {
12861267
return true;

0 commit comments

Comments
 (0)