[PATCH v2 2/3] smb/server: cancel async requests when closing connection
ChenXiaoSong <[email protected]>
| Newsgroups | org.kernel.vger.linux-cifs |
|---|---|
| Message-ID | <[email protected]> |
From: ChenXiaoSong <[email protected]> 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. Signed-off-by: ChenXiaoSong <[email protected]> --- fs/smb/server/connection.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/fs/smb/server/connection.c b/fs/smb/server/connection.c index 2de1413ba64e..b31b72c07f83 100644 --- a/fs/smb/server/connection.c +++ b/fs/smb/server/connection.c @@ -291,6 +291,25 @@ 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; + + ksmbd_debug(CONN, "Cancel pending async requests on releasing connection\n"); + spin_lock(&conn->request_lock); + list_for_each_entry(work, &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); @@ -589,6 +608,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); -- 2.54.0