ksmbd: keep TCP timers alive for kernel sockets
authorNamjae Jeon <linkinjeon@kernel.org>
Wed, 19 Aug 2026 23:26:03 +0000 (08:26 +0900)
committerNamjae Jeon <linkinjeon@kernel.org>
Thu, 20 Aug 2026 13:56:12 +0000 (22:56 +0900)
ksmbd creates its listening socket with sock_create_kern(). Kernel
sockets do not hold a network namespace reference by default. Accepted
sockets inherit this state.

When an accepted socket is released, tcp_close() clears its pending TCP
timers for a kernel socket after the socket enters an orphaned state. If
the peer is unreachable while ksmbd sends a FIN, this can leave a
FIN-WAIT-1 orphan without a retransmission timer.

Upgrade the listening socket's network namespace reference before
kernel_listen(). Accepted sockets inherit the reference, so the TCP
stack can keep the retransmission timer active and apply its normal
orphan retry policy.

Preserve the existing graceful shutdown behavior.

Link: https://github.com/openwrt/openwrt/issues/24744
Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
fs/smb/server/transport_tcp.c

index 921e4e8..832e930 100644 (file)
@@ -523,6 +523,12 @@ static int create_socket(struct interface *iface)
                goto out_error;
        }
 
+       /*
+        * Accepted sockets inherit the listener's net reference. Keep TCP
+        * timers alive after a kernel socket is released.
+        */
+       sk_net_refcnt_upgrade(ksmbd_socket->sk);
+
        ret = kernel_listen(ksmbd_socket, KSMBD_SOCKET_BACKLOG);
        if (ret) {
                pr_err("Port listen() error: %d\n", ret);