From 25c2e34931c5f2a02baefd111a4eb7fa31158059 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 7 Apr 2026 16:46:29 +0200 Subject: [PATCH] smb: smbdirect: fix the logic in smbdirect_socket_destroy_sync() without an error If smbdirect_socket_destroy_sync() and sc->first_error was not set we should set -ESHUTDOWN, that's a better condition doing it only implicitly with the sc->status < SMBDIRECT_SOCKET_DISCONNECTING check. Cc: Steve French Cc: Tom Talpey Cc: Long Li Cc: Namjae Jeon Cc: David Howells Cc: Henrique Carvalho Cc: linux-cifs@vger.kernel.org Cc: samba-technical@lists.samba.org Signed-off-by: Stefan Metzmacher Signed-off-by: Steve French --- fs/smb/common/smbdirect/smbdirect_socket.c | 28 ++++++++++++++++------ 1 file changed, 21 insertions(+), 7 deletions(-) diff --git a/fs/smb/common/smbdirect/smbdirect_socket.c b/fs/smb/common/smbdirect/smbdirect_socket.c index 4003753bea261..9153e1dbf53d5 100644 --- a/fs/smb/common/smbdirect/smbdirect_socket.c +++ b/fs/smb/common/smbdirect/smbdirect_socket.c @@ -600,13 +600,20 @@ void smbdirect_socket_destroy_sync(struct smbdirect_socket *sc) */ WARN_ON_ONCE(in_interrupt()); - smbdirect_log_rdma_event(sc, SMBDIRECT_LOG_INFO, - "cancelling and disable disconnect_work\n"); - disable_work_sync(&sc->disconnect_work); + /* + * First we try to disable the work + * without disable_work_sync() in a + * non blocking way, if it's already + * running it will be handles by + * disable_work_sync() below. + * + * Here we just want to make sure queue_work() in + * smbdirect_socket_schedule_cleanup_lvl() + * is a no-op. + */ + disable_work(&sc->disconnect_work); - smbdirect_log_rdma_event(sc, SMBDIRECT_LOG_INFO, - "destroying rdma session\n"); - if (sc->status < SMBDIRECT_SOCKET_DISCONNECTING) { + if (!sc->first_error) /* * SMBDIRECT_LOG_INFO is enough here * as this is the typical case where @@ -615,8 +622,15 @@ void smbdirect_socket_destroy_sync(struct smbdirect_socket *sc) smbdirect_socket_schedule_cleanup_lvl(sc, SMBDIRECT_LOG_INFO, -ESHUTDOWN); + + smbdirect_log_rdma_event(sc, SMBDIRECT_LOG_INFO, + "cancelling and disable disconnect_work\n"); + disable_work_sync(&sc->disconnect_work); + + smbdirect_log_rdma_event(sc, SMBDIRECT_LOG_INFO, + "destroying rdma session\n"); + if (sc->status < SMBDIRECT_SOCKET_DISCONNECTING) smbdirect_socket_cleanup_work(&sc->disconnect_work); - } if (sc->status < SMBDIRECT_SOCKET_DISCONNECTED) { smbdirect_log_rdma_event(sc, SMBDIRECT_LOG_INFO, "wait for transport being disconnected\n"); -- 2.47.3