[PATCH v2 3/3] smb/server: stop new async work when closing connection

ChenXiaoSong <[email protected]>
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 966e61788422..b80f0bcf5fc1 100644
--- a/fs/smb/server/smb2pdu.c
+++ b/fs/smb/server/smb2pdu.c
@@ -802,21 +802,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
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.