Linux CIFS filesystem development
 help / color / mirror / Atom feed
* [PATCH 0/3] smb/server: fix some bugs in preparation for change notify support
@ 2026-07-15 13:55 ChenXiaoSong
  2026-07-15 13:55 ` [PATCH 1/3] smb/server: fix signing when a response uses more than one iov ChenXiaoSong
                   ` (3 more replies)
  0 siblings, 4 replies; 9+ messages in thread
From: ChenXiaoSong @ 2026-07-15 13:55 UTC (permalink / raw)
  To: smfrench, linkinjeon, pc, ronniesahlberg, sprasad, tom, bharathsm,
	senozhatsky, dhowells, metze, andriy.shevchenko
  Cc: linux-cifs, ChenXiaoSong

From: ChenXiaoSong <chenxiaosong@kylinos.cn>

I have implemented the ksmbd change notify feature, please see the following GitHub link (some minor changes are also needed):
https://github.com/chenxiaosonggithub/linux/commits/ksmbd-change-notify/

However, to make this feature work properly, some pre-existing bugs need to be fixed first.

ChenXiaoSong (3):
  smb/server: fix signing when a response uses more than one iov
  smb/server: cancel async requests when closing connection
  smb/server: stop new async work when closing connection

 fs/smb/server/connection.c | 21 +++++++++++
 fs/smb/server/smb2pdu.c    | 76 ++++++++++++++++++++++++++------------
 2 files changed, 74 insertions(+), 23 deletions(-)

-- 
2.54.0


^ permalink raw reply	[flat|nested] 9+ messages in thread

* [PATCH 1/3] smb/server: fix signing when a response uses more than one iov
  2026-07-15 13:55 [PATCH 0/3] smb/server: fix some bugs in preparation for change notify support ChenXiaoSong
@ 2026-07-15 13:55 ` ChenXiaoSong
  2026-07-15 14:25   ` Andy Shevchenko
  2026-07-15 13:55 ` [PATCH 2/3] smb/server: cancel async requests when closing connection ChenXiaoSong
                   ` (2 subsequent siblings)
  3 siblings, 1 reply; 9+ messages in thread
From: ChenXiaoSong @ 2026-07-15 13:55 UTC (permalink / raw)
  To: smfrench, linkinjeon, pc, ronniesahlberg, sprasad, tom, bharathsm,
	senozhatsky, dhowells, metze, andriy.shevchenko
  Cc: linux-cifs, ChenXiaoSong

From: ChenXiaoSong <chenxiaosong@kylinos.cn>

Some SMB responses keep their data in another buffer. The SMB header
and the data are then in different iovs.

The old code only handled this for SMB2 READ. For other commands, it
signed only the last iov. QUERY_INFO and CHANGE_NOTIFY can also use
another iov for their data. Their SMB header was not signed, so Windows
will client rejected the response.

Find the iov that starts with the current SMB header. Sign this iov and
all iovs after it.

Signed-off-by: ChenXiaoSong <chenxiaosong@kylinos.cn>
---
 fs/smb/server/smb2pdu.c | 52 ++++++++++++++++++++++++++++++-----------
 1 file changed, 38 insertions(+), 14 deletions(-)

diff --git a/fs/smb/server/smb2pdu.c b/fs/smb/server/smb2pdu.c
index b73167785e87..72e1b2b0a6fe 100644
--- a/fs/smb/server/smb2pdu.c
+++ b/fs/smb/server/smb2pdu.c
@@ -9625,6 +9625,40 @@ int smb2_check_sign_req(struct ksmbd_work *work)
 	return 1;
 }
 
+/**
+ * smb2_get_sign_rsp_iov() - get the iovecs used to sign a response
+ * @work: work that has the response iovecs
+ * @hdr: SMB2 header of the response
+ * @n_vec: set to the number of iovecs to sign
+ *
+ * Response data may be in another buffer. In this case, the response uses
+ * more than one iovec. Find the iovec that starts with @hdr. Sign this
+ * iovec and all iovecs after it.
+ *
+ * Return: The first iovec to sign.
+ */
+static struct kvec *smb2_get_sign_rsp_iov(struct ksmbd_work *work,
+					   struct smb2_hdr *hdr, int *n_vec)
+{
+	int i;
+
+	/*
+	 * iov[0] has the RFC1002 message length. It is not part of the SMB2
+	 * message, so do not sign it.
+	 */
+	for (i = 1; i <= work->iov_idx; i++) {
+		if (work->iov[i].iov_base == hdr) {
+			*n_vec = work->iov_idx - i + 1;
+			return &work->iov[i];
+		}
+	}
+
+	WARN_ON_ONCE(work->iov_idx < 1 ||
+		     work->iov[work->iov_idx].iov_base != hdr);
+	*n_vec = 1;
+	return &work->iov[work->iov_idx];
+}
+
 /**
  * smb2_set_sign_rsp() - handler for rsp packet sign processing
  * @work:   smb work containing notify command buffer
@@ -9635,18 +9669,13 @@ void smb2_set_sign_rsp(struct ksmbd_work *work)
 	struct smb2_hdr *hdr;
 	char signature[SMB2_HMACSHA256_SIZE];
 	struct kvec *iov;
-	int n_vec = 1;
+	int n_vec;
 
 	hdr = ksmbd_resp_buf_curr(work);
 	hdr->Flags |= SMB2_FLAGS_SIGNED;
 	memset(hdr->Signature, 0, SMB2_SIGNATURE_SIZE);
 
-	if (hdr->Command == SMB2_READ) {
-		iov = &work->iov[work->iov_idx - 1];
-		n_vec++;
-	} else {
-		iov = &work->iov[work->iov_idx];
-	}
+	iov = smb2_get_sign_rsp_iov(work, hdr, &n_vec);
 
 	ksmbd_sign_smb2_pdu(work->conn, work->sess->sess_key, iov, n_vec,
 			    signature);
@@ -9729,7 +9758,7 @@ void smb3_set_sign_rsp(struct ksmbd_work *work)
 	char signature[SMB2_CMACAES_SIZE];
 	struct kvec *iov;
 	u16 command = conn->ops->get_cmd_val(work);
-	int n_vec = 1;
+	int n_vec;
 	char *signing_key;
 
 	hdr = ksmbd_resp_buf_curr(work);
@@ -9751,12 +9780,7 @@ void smb3_set_sign_rsp(struct ksmbd_work *work)
 	hdr->Flags |= SMB2_FLAGS_SIGNED;
 	memset(hdr->Signature, 0, SMB2_SIGNATURE_SIZE);
 
-	if (hdr->Command == SMB2_READ) {
-		iov = &work->iov[work->iov_idx - 1];
-		n_vec++;
-	} else {
-		iov = &work->iov[work->iov_idx];
-	}
+	iov = smb2_get_sign_rsp_iov(work, hdr, &n_vec);
 
 	ksmbd_sign_smb3_pdu(conn, signing_key, iov, n_vec, signature);
 	memcpy(hdr->Signature, signature, SMB2_SIGNATURE_SIZE);
-- 
2.54.0


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH 2/3] smb/server: cancel async requests when closing connection
  2026-07-15 13:55 [PATCH 0/3] smb/server: fix some bugs in preparation for change notify support ChenXiaoSong
  2026-07-15 13:55 ` [PATCH 1/3] smb/server: fix signing when a response uses more than one iov ChenXiaoSong
@ 2026-07-15 13:55 ` ChenXiaoSong
  2026-07-15 14:26   ` Andy Shevchenko
  2026-07-15 13:55 ` [PATCH 3/3] smb/server: stop new async work " ChenXiaoSong
  2026-07-15 15:22 ` [PATCH 0/3] smb/server: fix some bugs in preparation for change notify support ChenXiaoSong
  3 siblings, 1 reply; 9+ messages in thread
From: ChenXiaoSong @ 2026-07-15 13:55 UTC (permalink / raw)
  To: smfrench, linkinjeon, pc, ronniesahlberg, sprasad, tom, bharathsm,
	senozhatsky, dhowells, metze, andriy.shevchenko
  Cc: linux-cifs, ChenXiaoSong

From: ChenXiaoSong <chenxiaosong@kylinos.cn>

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 <chenxiaosong@kylinos.cn>
---
 fs/smb/server/connection.c | 21 +++++++++++++++++++++
 1 file changed, 21 insertions(+)

diff --git a/fs/smb/server/connection.c b/fs/smb/server/connection.c
index 9e8fdb39e5a2..54b9672d7c70 100644
--- a/fs/smb/server/connection.c
+++ b/fs/smb/server/connection.c
@@ -291,6 +291,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;
+
+	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);
@@ -564,6 +584,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


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH 3/3] smb/server: stop new async work when closing connection
  2026-07-15 13:55 [PATCH 0/3] smb/server: fix some bugs in preparation for change notify support ChenXiaoSong
  2026-07-15 13:55 ` [PATCH 1/3] smb/server: fix signing when a response uses more than one iov ChenXiaoSong
  2026-07-15 13:55 ` [PATCH 2/3] smb/server: cancel async requests when closing connection ChenXiaoSong
@ 2026-07-15 13:55 ` ChenXiaoSong
  2026-07-15 15:22 ` [PATCH 0/3] smb/server: fix some bugs in preparation for change notify support ChenXiaoSong
  3 siblings, 0 replies; 9+ messages in thread
From: ChenXiaoSong @ 2026-07-15 13:55 UTC (permalink / raw)
  To: smfrench, linkinjeon, pc, ronniesahlberg, sprasad, tom, bharathsm,
	senozhatsky, dhowells, metze, andriy.shevchenko
  Cc: linux-cifs, ChenXiaoSong

From: ChenXiaoSong <chenxiaosong@kylinos.cn>

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 <chenxiaosong@kylinos.cn>
---
 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 72e1b2b0a6fe..4203771891fd 100644
--- a/fs/smb/server/smb2pdu.c
+++ b/fs/smb/server/smb2pdu.c
@@ -799,21 +799,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("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


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* Re: [PATCH 1/3] smb/server: fix signing when a response uses more than one iov
  2026-07-15 13:55 ` [PATCH 1/3] smb/server: fix signing when a response uses more than one iov ChenXiaoSong
@ 2026-07-15 14:25   ` Andy Shevchenko
  2026-07-15 15:04     ` ChenXiaoSong
  0 siblings, 1 reply; 9+ messages in thread
From: Andy Shevchenko @ 2026-07-15 14:25 UTC (permalink / raw)
  To: ChenXiaoSong
  Cc: smfrench, linkinjeon, pc, ronniesahlberg, sprasad, tom, bharathsm,
	senozhatsky, dhowells, metze, linux-cifs, ChenXiaoSong

On Wed, Jul 15, 2026 at 01:55:11PM +0000, ChenXiaoSong wrote:

> Some SMB responses keep their data in another buffer. The SMB header
> and the data are then in different iovs.
> 
> The old code only handled this for SMB2 READ. For other commands, it
> signed only the last iov. QUERY_INFO and CHANGE_NOTIFY can also use
> another iov for their data. Their SMB header was not signed, so Windows
> will client rejected the response.
> 
> Find the iov that starts with the current SMB header. Sign this iov and
> all iovs after it.

...

> +static struct kvec *smb2_get_sign_rsp_iov(struct ksmbd_work *work,
> +					   struct smb2_hdr *hdr, int *n_vec)
> +{
> +	int i;
> +
> +	/*
> +	 * iov[0] has the RFC1002 message length. It is not part of the SMB2
> +	 * message, so do not sign it.
> +	 */

> +	for (i = 1; i <= work->iov_idx; i++) {

	for (int i = 1; i <= work->iov_idx; i++) {

(or even unsigned int). This style is preferred as long as iterator is local
to the loop.

> +		if (work->iov[i].iov_base == hdr) {
> +			*n_vec = work->iov_idx - i + 1;
> +			return &work->iov[i];
> +		}
> +	}
> +
> +	WARN_ON_ONCE(work->iov_idx < 1 ||
> +		     work->iov[work->iov_idx].iov_base != hdr);
> +	*n_vec = 1;
> +	return &work->iov[work->iov_idx];
> +}

-- 
With Best Regards,
Andy Shevchenko



^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH 2/3] smb/server: cancel async requests when closing connection
  2026-07-15 13:55 ` [PATCH 2/3] smb/server: cancel async requests when closing connection ChenXiaoSong
@ 2026-07-15 14:26   ` Andy Shevchenko
  0 siblings, 0 replies; 9+ messages in thread
From: Andy Shevchenko @ 2026-07-15 14:26 UTC (permalink / raw)
  To: ChenXiaoSong
  Cc: smfrench, linkinjeon, pc, ronniesahlberg, sprasad, tom, bharathsm,
	senozhatsky, dhowells, metze, linux-cifs, ChenXiaoSong

On Wed, Jul 15, 2026 at 01:55:12PM +0000, ChenXiaoSong wrote:

> 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.

...

> +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) {

It's perfectly a single line. Note, the strict mode is 80 characters
(inclusive), this line even one less, id est 79 characters.

> +		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);
> +}

-- 
With Best Regards,
Andy Shevchenko



^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH 1/3] smb/server: fix signing when a response uses more than one iov
  2026-07-15 14:25   ` Andy Shevchenko
@ 2026-07-15 15:04     ` ChenXiaoSong
  2026-07-15 15:18       ` ChenXiaoSong
  0 siblings, 1 reply; 9+ messages in thread
From: ChenXiaoSong @ 2026-07-15 15:04 UTC (permalink / raw)
  To: Andy Shevchenko, ChenXiaoSong
  Cc: smfrench, linkinjeon, pc, ronniesahlberg, sprasad, tom, bharathsm,
	senozhatsky, dhowells, metze, linux-cifs

Got it, thanks.

Andy, could you update your patch "ksmbd: defer CHANGE_NOTIFY completion 
instead of STATUS_NOT_IMPLEMENTED" so that my remaining notify feature 
patches can be rebased on top of it?

https://github.com/chenxiaosonggithub/linux/commits/ksmbd-change-notify/

在 2026/7/15 22:25, Andy Shevchenko 写道:
> 	for (int i = 1; i <= work->iov_idx; i++) {
> 
> (or even unsigned int). This style is preferred as long as iterator is local
> to the loop.

-- 
ChenXiaoSong <chenxiaosong@chenxiaosong.com>
Chinese Homepage: https://chenxiaosong.com
English Homepage: https://chenxiaosong.com/en


^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH 1/3] smb/server: fix signing when a response uses more than one iov
  2026-07-15 15:04     ` ChenXiaoSong
@ 2026-07-15 15:18       ` ChenXiaoSong
  0 siblings, 0 replies; 9+ messages in thread
From: ChenXiaoSong @ 2026-07-15 15:18 UTC (permalink / raw)
  To: Andy Shevchenko
  Cc: smfrench, linkinjeon, pc, ronniesahlberg, sprasad, tom, bharathsm,
	senozhatsky, dhowells, metze, linux-cifs

Hi Andy,

Please ignore this. Sorry, I sent it to the wrong person.

在 2026/7/15 23:04, ChenXiaoSong 写道:
> Andy, could you update your patch "ksmbd: defer CHANGE_NOTIFY completion 
> instead of STATUS_NOT_IMPLEMENTED" so that my remaining notify feature 
> patches can be rebased on top of it?

-- 
ChenXiaoSong <chenxiaosong@chenxiaosong.com>
Chinese Homepage: https://chenxiaosong.com
English Homepage: https://chenxiaosong.com/en


^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH 0/3] smb/server: fix some bugs in preparation for change notify support
  2026-07-15 13:55 [PATCH 0/3] smb/server: fix some bugs in preparation for change notify support ChenXiaoSong
                   ` (2 preceding siblings ...)
  2026-07-15 13:55 ` [PATCH 3/3] smb/server: stop new async work " ChenXiaoSong
@ 2026-07-15 15:22 ` ChenXiaoSong
  3 siblings, 0 replies; 9+ messages in thread
From: ChenXiaoSong @ 2026-07-15 15:22 UTC (permalink / raw)
  To: Gaël Blivet-Bailly
  Cc: linux-cifs, smfrench, linkinjeon, pc, ronniesahlberg, sprasad,
	tom, bharathsm, senozhatsky, dhowells, metze, andriy.shevchenko

Hi Gaël,

Could you update your patch "ksmbd: defer CHANGE_NOTIFY completion 
instead of STATUS_NOT_IMPLEMENTED" so that my remaining notify feature 
patches can be rebased on top of it?

https://github.com/chenxiaosonggithub/linux/commits/ksmbd-change-notify/

在 2026/7/15 21:55, ChenXiaoSong 写道:
> From: ChenXiaoSong <chenxiaosong@kylinos.cn>
> 
> I have implemented the ksmbd change notify feature, please see the following GitHub link (some minor changes are also needed):
> https://github.com/chenxiaosonggithub/linux/commits/ksmbd-change-notify/
> 
> However, to make this feature work properly, some pre-existing bugs need to be fixed first.
> 
> ChenXiaoSong (3):
>    smb/server: fix signing when a response uses more than one iov
>    smb/server: cancel async requests when closing connection
>    smb/server: stop new async work when closing connection
> 
>   fs/smb/server/connection.c | 21 +++++++++++
>   fs/smb/server/smb2pdu.c    | 76 ++++++++++++++++++++++++++------------
>   2 files changed, 74 insertions(+), 23 deletions(-)
> 

-- 
ChenXiaoSong <chenxiaosong@chenxiaosong.com>
Chinese Homepage: https://chenxiaosong.com
English Homepage: https://chenxiaosong.com/en


^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2026-07-15 15:22 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-07-15 13:55 [PATCH 0/3] smb/server: fix some bugs in preparation for change notify support ChenXiaoSong
2026-07-15 13:55 ` [PATCH 1/3] smb/server: fix signing when a response uses more than one iov ChenXiaoSong
2026-07-15 14:25   ` Andy Shevchenko
2026-07-15 15:04     ` ChenXiaoSong
2026-07-15 15:18       ` ChenXiaoSong
2026-07-15 13:55 ` [PATCH 2/3] smb/server: cancel async requests when closing connection ChenXiaoSong
2026-07-15 14:26   ` Andy Shevchenko
2026-07-15 13:55 ` [PATCH 3/3] smb/server: stop new async work " ChenXiaoSong
2026-07-15 15:22 ` [PATCH 0/3] smb/server: fix some bugs in preparation for change notify support ChenXiaoSong

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox