From: Stefan Metzmacher Date: Tue, 7 Apr 2026 14:46:29 +0000 (+0200) Subject: smb: smbdirect: fix the logic in smbdirect_socket_destroy_sync() without an error X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=25c2e34931c5f2a02baefd111a4eb7fa31158059;p=thirdparty%2Fkernel%2Flinux.git 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 --- diff --git a/fs/smb/common/smbdirect/smbdirect_socket.c b/fs/smb/common/smbdirect/smbdirect_socket.c index 4003753bea26..9153e1dbf53d 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");