[PATCH v3 3/3] smb/server: stop new async work when closing connection
ChenXiaoSong <[email protected]> Thu, 23 Jul 2026 04:11:31 +0000
| Newsgroups | org.kernel.vger.linux-cifs |
|---|---|
| Message-ID | <[email protected]> |
From: ChenXiaoSong <[email protected]> A new async request may be added while a connection is closing. The close code may miss this request and wait forever. Check the connection state before adding the request. Return an error and release the async ID if the connection is closing. Signed-off-by: ChenXiaoSong <[email protected]> --- fs/smb/server/smb2pdu.c | 24 +++++++++++++++--------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/fs/smb/server/smb2pdu.c b/fs/smb/server/smb2pdu.c index 54327f8362db..0680222a8da4 100644 --- a/fs/smb/server/smb2pdu.c +++ b/fs/smb/server/smb2pdu.c @@ -1001,21 +1001,27 @@ int setup_async_work(struct ksmbd_work *work, void (*fn)(void **), void **arg) pr_err("Failed to alloc async message id\n"); return id; } - work->asynchronous = true; - work->async_id = id; - ksmbd_debug(SMB, - "Send interim Response to inform async request id : %d\n", - work->async_id); + spin_lock(&conn->request_lock); + if (ksmbd_conn_exiting(conn) || ksmbd_conn_releasing(conn)) { + spin_unlock(&conn->request_lock); + pr_err_ratelimited("Failed to setup async work: connection is exiting\n"); + ksmbd_release_id(&conn->async_ida, id); + return -ESHUTDOWN; + } + work->asynchronous = true; + work->async_id = id; work->cancel_fn = fn; work->cancel_argv = arg; - if (list_empty(&work->async_request_entry)) { - spin_lock(&conn->request_lock); + if (list_empty(&work->async_request_entry)) list_add_tail(&work->async_request_entry, &conn->async_requests); - spin_unlock(&conn->request_lock); - } + spin_unlock(&conn->request_lock); + + ksmbd_debug(SMB, + "Send interim Response to inform async request id : %d\n", + work->async_id); return 0; } -- 2.54.0