diff options
| author | ChenXiaoSong <chenxiaosong@kylinos.cn> | 2026-07-23 04:11:30 +0000 |
|---|---|---|
| committer | Namjae Jeon <linkinjeon@kernel.org> | 2026-08-17 15:00:52 +0900 |
| commit | 4fd5bad647bfa45eb86bfd2f03ba1bef3fcd5851 (patch) | |
| tree | b136ccbaecc66654ed86f2ccbd79cc4390637027 | |
| parent | df3e2150f3ea44256688ad1be9cbd7453fcf0ca2 (diff) | |
| download | linux-4fd5bad647bfa45eb86bfd2f03ba1bef3fcd5851.tar.gz linux-4fd5bad647bfa45eb86bfd2f03ba1bef3fcd5851.zip | |
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>
| -rw-r--r-- | fs/smb/server/connection.c | 21 |
1 files changed, 21 insertions, 0 deletions
diff --git a/fs/smb/server/connection.c b/fs/smb/server/connection.c index b08ef8e49a24..99ffb00e87bf 100644 --- a/fs/smb/server/connection.c +++ b/fs/smb/server/connection.c @@ -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 @@ recheck: } 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); |
