smb: client: let smbd_destroy() wait for SMBDIRECT_SOCKET_DISCONNECTED

We should wait for the rdma_cm to become SMBDIRECT_SOCKET_DISCONNECTED,
it turns out that (at least running some xfstests e.g. cifs/001)
often triggers the case where wait_event_interruptible() returns
with -ERESTARTSYS instead of waiting for SMBDIRECT_SOCKET_DISCONNECTED
to be reached.

Or we are already in SMBDIRECT_SOCKET_DISCONNECTING and never wait
for SMBDIRECT_SOCKET_DISCONNECTED.

Fixes: 050b8c3740 ("smbd: Make upper layer decide when to destroy the transport")
Fixes: e8b3bfe9bc ("cifs: smbd: Don't destroy transport on RDMA disconnect")
Fixes: b0aa92a229 ("smb: client: make sure smbd_disconnect_rdma_work() doesn't run after smbd_destroy() took over")
Cc: Steve French <smfrench@gmail.com>
Cc: Tom Talpey <tom@talpey.com>
Cc: Long Li <longli@microsoft.com>
Cc: Namjae Jeon <linkinjeon@kernel.org>
Cc: linux-cifs@vger.kernel.org
Cc: samba-technical@lists.samba.org
Signed-off-by: Stefan Metzmacher <metze@samba.org>
Signed-off-by: Steve French <stfrench@microsoft.com>
This commit is contained in:
Stefan Metzmacher
2025-10-15 17:05:04 +02:00
committed by Steve French
parent d877470b59
commit d451a0e88e

View File

@@ -1575,12 +1575,12 @@ void smbd_destroy(struct TCP_Server_Info *server)
disable_work_sync(&sc->disconnect_work);
log_rdma_event(INFO, "destroying rdma session\n");
if (sc->status < SMBDIRECT_SOCKET_DISCONNECTING) {
if (sc->status < SMBDIRECT_SOCKET_DISCONNECTING)
smbd_disconnect_rdma_work(&sc->disconnect_work);
if (sc->status < SMBDIRECT_SOCKET_DISCONNECTED) {
log_rdma_event(INFO, "wait for transport being disconnected\n");
wait_event_interruptible(
sc->status_wait,
sc->status == SMBDIRECT_SOCKET_DISCONNECTED);
wait_event(sc->status_wait, sc->status == SMBDIRECT_SOCKET_DISCONNECTED);
log_rdma_event(INFO, "waited for transport being disconnected\n");
}
/*