From: ChenXiaoSong <chenxiaosong@chenxiaosong.com>
To: smfrench@gmail.com, linkinjeon@kernel.org, pc@manguebit.org,
ronniesahlberg@gmail.com, sprasad@microsoft.com, tom@talpey.com,
bharathsm@microsoft.com, senozhatsky@chromium.org,
dhowells@redhat.com, metze@samba.org
Cc: linux-cifs@vger.kernel.org, samba-technical@lists.samba.org,
ChenXiaoSong <chenxiaosong@kylinos.cn>
Subject: [PATCH v2 1/3] smb/server: send compound prefix before async pending response
Date: Wed, 8 Jul 2026 02:56:13 +0000 [thread overview]
Message-ID: <20260708025615.145390-2-chenxiaosong@chenxiaosong.com> (raw)
In-Reply-To: <20260708025615.145390-1-chenxiaosong@chenxiaosong.com>
From: ChenXiaoSong <chenxiaosong@kylinos.cn>
When the last request in a compound request becomes async, ksmbd sends a
STATUS_PENDING response for it. But the responses for previous requests in
the same compound request are still kept in the same response buffer.
Send these previous responses first. Clear NextCommand for the last
response in this part, sign it again if needed, and reset the iov state.
After that, the async request sends STATUS_PENDING first, and sends the
real response later. Both are separate responses.
Example:
smbtorture //${server_ip}/export -U${username}%${password} smb2.compound_async.write_write
Client request:
Write Request Len:64 Off:0, File: compound_async_write_write; Write Request Len:64 Off:64
Before this patch, STATUS_PENDING Write Response is the first of
several responses:
Write Response, Error: STATUS_PENDING
Write Response, File: compound_async_write_write; Write Response
But STATUS_PENDING Write Response should be in the middle of several
responses, after this patch:
Write Response, File: compound_async_write_write
Write Response
SMB2, STATUS_PENDING, Write Response, MessageId 7
SMB2, Write Response, MessageId 7
Signed-off-by: ChenXiaoSong <chenxiaosong@kylinos.cn>
---
fs/smb/server/smb2pdu.c | 45 +++++++++++++++++++++++++++++++++++++++++
1 file changed, 45 insertions(+)
diff --git a/fs/smb/server/smb2pdu.c b/fs/smb/server/smb2pdu.c
index 0ab05a8e575e..35f8476bbb6d 100644
--- a/fs/smb/server/smb2pdu.c
+++ b/fs/smb/server/smb2pdu.c
@@ -839,6 +839,48 @@ void release_async_work(struct ksmbd_work *work)
}
}
+static void smb2_send_interim_compound_prefix(struct ksmbd_work *work)
+{
+ struct smb2_hdr *req_hdr;
+ struct smb2_hdr *rsp_hdr;
+ int err;
+
+ if (!work->next_smb2_rcv_hdr_off ||
+ !work->next_smb2_rsp_hdr_off ||
+ work->curr_smb2_rsp_hdr_off == work->next_smb2_rsp_hdr_off ||
+ !work->iov_idx)
+ return;
+
+ req_hdr = ksmbd_req_buf_next(work);
+ /* Detach only the final async command from the completed prefix. */
+ if (req_hdr->NextCommand)
+ return;
+
+ /*
+ * The responses before the async command are sent as a standalone
+ * compound response. The last response in this prefix must terminate
+ * the chain.
+ */
+ rsp_hdr = ksmbd_resp_buf_curr(work);
+ rsp_hdr->NextCommand = 0;
+ if ((rsp_hdr->Flags & SMB2_FLAGS_SIGNED) && work->sess &&
+ work->conn->ops->set_sign_rsp)
+ work->conn->ops->set_sign_rsp(work);
+
+ err = ksmbd_conn_write(work);
+ if (err)
+ ksmbd_debug(SMB, "failed to send compound interim prefix: %d\n",
+ err);
+
+ work->iov_idx = 0;
+ work->iov_cnt = 0;
+ work->curr_smb2_rsp_hdr_off = work->next_smb2_rsp_hdr_off;
+ *(__be32 *)work->response_buf = 0;
+
+ rsp_hdr = ksmbd_resp_buf_next(work);
+ rsp_hdr->Flags &= ~SMB2_FLAGS_RELATED_OPERATIONS;
+}
+
void smb2_send_interim_resp(struct ksmbd_work *work, __le32 status)
{
struct smb2_hdr *rsp_hdr;
@@ -853,6 +895,9 @@ void smb2_send_interim_resp(struct ksmbd_work *work, __le32 status)
return;
}
+ if (status == STATUS_PENDING)
+ smb2_send_interim_compound_prefix(work);
+
in_work->conn = work->conn;
memcpy(smb_get_msg(in_work->response_buf), ksmbd_resp_buf_next(work),
__SMB2_HEADER_STRUCTURE_SIZE);
--
2.54.0
next prev parent reply other threads:[~2026-07-08 2:56 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-07-08 2:56 [PATCH v2 0/3] smb/server: improve async interim response handling for compound requests ChenXiaoSong
2026-07-08 2:56 ` ChenXiaoSong [this message]
2026-07-08 2:56 ` [PATCH v2 2/3] smb/server: introduce struct ksmbd_transport_write ChenXiaoSong
2026-07-08 2:56 ` [PATCH v2 3/3] smb/server: use MSG_EOR for async interim response ChenXiaoSong
2026-07-08 10:33 ` [PATCH v2 0/3] smb/server: improve async interim response handling for compound requests Namjae Jeon
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260708025615.145390-2-chenxiaosong@chenxiaosong.com \
--to=chenxiaosong@chenxiaosong.com \
--cc=bharathsm@microsoft.com \
--cc=chenxiaosong@kylinos.cn \
--cc=dhowells@redhat.com \
--cc=linkinjeon@kernel.org \
--cc=linux-cifs@vger.kernel.org \
--cc=metze@samba.org \
--cc=pc@manguebit.org \
--cc=ronniesahlberg@gmail.com \
--cc=samba-technical@lists.samba.org \
--cc=senozhatsky@chromium.org \
--cc=smfrench@gmail.com \
--cc=sprasad@microsoft.com \
--cc=tom@talpey.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox