From 9fe2be655a793d2f9425b96e53a7e1e7feec067e Mon Sep 17 00:00:00 2001 From: Joel Colledge Date: Wed, 18 Sep 2024 15:08:55 +0200 Subject: [PATCH 30/32] drbd: kref_put() path when kernel_accept() fails We need to put the reference that dtt_wait_connect_cond() gets. This is an unusual situation. The function dtt_wait_connect_cond() only returns a path when pending_accepts is positive or there is a socket in the path->sockets list. So if the code reaches the kernel_accept() call, we expect it to succeed. However, it has been observed to fail, so we need to handle that case cleanly. Without the kref_put(), it is impossible to rmmod drbd. For any error other than -EAGAIN, the error is be passed up and is logged by conn_connect(). However, when -EAGAIN is returned, dtt_connect() continues trying to connect and the error from kernel_accept() leaves no traces in the logs. --- drbd/drbd_transport_tcp.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drbd/drbd_transport_tcp.c b/drbd/drbd_transport_tcp.c index df144fcb4522..d59f68d83c58 100644 --- a/drbd/drbd_transport_tcp.c +++ b/drbd/drbd_transport_tcp.c @@ -625,8 +625,10 @@ retry: s_estab = NULL; err = kernel_accept(listener->s_listen, &s_estab, O_NONBLOCK); - if (err < 0) + if (err < 0) { + kref_put(&path->path.kref, drbd_destroy_path); return err; + } /* The established socket inherits the sk_state_change callback from the listening socket. */ -- 2.35.3