smb/server: cancel async requests when closing connection

An async request may still be waiting when a connection is closed.
This can stop the connection from closing.

Cancel active async requests before waiting for them to finish.

Suggested-by: Namjae Jeon <linkinjeon@kernel.org>
Signed-off-by: ChenXiaoSong <chenxiaosong@kylinos.cn>
Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
This commit is contained in:
ChenXiaoSong 2026-07-23 04:11:30 +00:00 committed by Namjae Jeon
parent df3e2150f3
commit 4fd5bad647

View File

@ -371,6 +371,26 @@ void ksmbd_conn_try_dequeue_request(struct ksmbd_work *work)
wake_up_all(&conn->req_running_q);
}
static void ksmbd_conn_cancel_async_requests(struct ksmbd_conn *conn)
{
struct ksmbd_work *work, *tmp;
ksmbd_debug(CONN, "Cancel pending async requests on releasing connection\n");
spin_lock(&conn->request_lock);
list_for_each_entry_safe(work, tmp, &conn->async_requests,
async_request_entry) {
if (work->state != KSMBD_WORK_ACTIVE)
continue;
ksmbd_debug(CONN, "Cancel async request id %d\n",
work->async_id);
work->state = KSMBD_WORK_CANCELLED;
if (work->cancel_fn)
work->cancel_fn(work->cancel_argv);
}
spin_unlock(&conn->request_lock);
}
void ksmbd_conn_lock(struct ksmbd_conn *conn)
{
mutex_lock(&conn->srv_mutex);
@ -665,6 +685,7 @@ int ksmbd_conn_handler_loop(void *p)
}
ksmbd_conn_set_releasing(conn);
ksmbd_conn_cancel_async_requests(conn);
/* Wait till all reference dropped to the Server object*/
ksmbd_debug(CONN, "Wait for all pending requests(%d)\n", atomic_read(&conn->r_count));
wait_event(conn->r_count_q, atomic_read(&conn->r_count) == 0);