mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: "wang zhaolong" <wangzhaolong@fnnas.com>
To: <linux-cifs@vger.kernel.org>
Cc: <linkinjeon@kernel.org>, <smfrench@gmail.com>,
	 <senozhatsky@chromium.org>, <tom@talpey.com>,
	 <linux-kernel@vger.kernel.org>,
	"Wang Zhaolong" <wangzhaolong@fnnas.com>
Subject: [RFC 3/3] ksmbd: use splice payloads for simple SMB2 READ
Date: Mon, 13 Jul 2026 15:11:40 +0800	[thread overview]
Message-ID: <20260713071141.3909087-4-wangzhaolong@fnnas.com> (raw)
In-Reply-To: <20260713071141.3909087-1-wangzhaolong@fnnas.com>

From: Wang Zhaolong <wangzhaolong@fnnas.com>

Use the page-backed payload path for plain TCP SMB2 READ requests of at
least 64 KiB. Unsupported collection results fall back before response
ownership is committed; permission, locking and allocation failures retain
the existing error handling.

Keep signed, encrypted, compressed, compound and RDMA requests on the
buffered path because they require signing, response transforms, compound
response layout, or alternate transport handling. Streams, non-regular
files, O_DIRECT and DAX reads also remain on the buffered path.

Signed-off-by: Wang Zhaolong <wangzhaolong@fnnas.com>
---
 fs/smb/server/smb2pdu.c | 67 +++++++++++++++++++++++++++++++++++++++++
 1 file changed, 67 insertions(+)

diff --git a/fs/smb/server/smb2pdu.c b/fs/smb/server/smb2pdu.c
index b73167785e87..a4a80ecc6d2f 100644
--- a/fs/smb/server/smb2pdu.c
+++ b/fs/smb/server/smb2pdu.c
@@ -7304,10 +7304,38 @@ static ssize_t smb2_read_rdma_channel(struct ksmbd_work *work,
 		return err;
 
 	return length;
 }
 
+#define KSMBD_READ_PAYLOAD_MIN_IO_SIZE	SZ_64K
+
+static bool smb2_read_payload_allowed(struct ksmbd_work *work,
+				      struct smb2_read_req *req,
+				      struct ksmbd_file *fp,
+				      size_t length, bool is_rdma_channel)
+{
+	struct ksmbd_conn *conn = work->conn;
+	struct file *filp = fp->filp;
+
+	if (is_rdma_channel || length < KSMBD_READ_PAYLOAD_MIN_IO_SIZE ||
+	    !conn->transport->ops->write_read_payload)
+		return false;
+	if (req->Flags & SMB2_READFLAG_REQUEST_COMPRESSED)
+		return false;
+	if (work->next_smb2_rcv_hdr_off || le32_to_cpu(req->hdr.NextCommand))
+		return false;
+	if (work->encrypted)
+		return false;
+	if (work->sess &&
+	    (work->sess->sign || conn->ops->is_sign_req(work, SMB2_READ_HE)))
+		return false;
+	if (ksmbd_stream_fd(fp) || !S_ISREG(file_inode(filp)->i_mode) ||
+	    (filp->f_flags & O_DIRECT) || IS_DAX(file_inode(filp)))
+		return false;
+	return true;
+}
+
 /**
  * smb2_read() - handler for smb2 read from file
  * @work:	smb work containing read command buffer
  *
  * Return:	0 on success, otherwise error
@@ -7316,10 +7344,11 @@ int smb2_read(struct ksmbd_work *work)
 {
 	struct ksmbd_conn *conn = work->conn;
 	struct smb2_read_req *req;
 	struct smb2_read_rsp *rsp;
 	struct ksmbd_file *fp = NULL;
+	struct ksmbd_read_payload *payload = NULL;
 	loff_t offset;
 	size_t length, mincount;
 	ssize_t nbytes = 0, remain_bytes = 0;
 	int err = 0;
 	bool is_rdma_channel = false, async_interim = false;
@@ -7418,10 +7447,48 @@ int smb2_read(struct ksmbd_work *work)
 	}
 
 	ksmbd_debug(SMB, "filename %pD, offset %lld, len %zu\n",
 		    fp->filp, offset, length);
 
+	if (smb2_read_payload_allowed(work, req, fp, length,
+				      is_rdma_channel)) {
+		nbytes = ksmbd_vfs_read_payload(work, fp, length, &offset,
+						&payload);
+		if (nbytes == -EOPNOTSUPP)
+			goto read_fallback;
+		if (nbytes < 0) {
+			err = nbytes;
+			goto out;
+		}
+		if ((nbytes == 0 && length != 0) || nbytes < mincount) {
+			ksmbd_read_payload_release(payload);
+			rsp->hdr.Status = STATUS_END_OF_FILE;
+			smb2_set_err_rsp(work);
+			ksmbd_fd_put(work, fp);
+			return -ENODATA;
+		}
+
+		rsp->StructureSize = cpu_to_le16(17);
+		rsp->DataOffset = 80;
+		rsp->Reserved = 0;
+		rsp->DataLength = cpu_to_le32(nbytes);
+		rsp->DataRemaining = 0;
+		rsp->Flags = 0;
+		err = ksmbd_iov_pin_rsp_read_payload(work, rsp,
+						     offsetof(struct smb2_read_rsp, Buffer),
+						     payload);
+		if (err) {
+			ksmbd_read_payload_release(payload);
+			goto out;
+		}
+		ksmbd_fd_put(work, fp);
+		return 0;
+	}
+
+read_fallback:
+	payload = NULL;
+
 	aux_payload_buf = kvmalloc(ALIGN(length, 8), KSMBD_DEFAULT_GFP);
 	if (!aux_payload_buf) {
 		err = -ENOMEM;
 		goto out;
 	}
-- 
2.47.3

  parent reply	other threads:[~2026-07-13  7:12 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-07-13  7:11 [RFC 0/3] ksmbd: use splice for SMB2 READ responses wang zhaolong
2026-07-13  7:11 ` [RFC 1/3] ksmbd: add read payload infrastructure wang zhaolong
2026-07-13  7:11 ` [RFC 2/3] ksmbd: add splice-based read payload helper wang zhaolong
2026-07-13  7:11 ` wang zhaolong [this message]
2026-07-13  8:58   ` [RFC 3/3] ksmbd: use splice payloads for simple SMB2 READ Namjae Jeon
2026-07-13  9:36     ` Wang Zhaolong
2026-07-17 12:49     ` Wang Zhaolong

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=20260713071141.3909087-4-wangzhaolong@fnnas.com \
    --to=wangzhaolong@fnnas.com \
    --cc=linkinjeon@kernel.org \
    --cc=linux-cifs@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=senozhatsky@chromium.org \
    --cc=smfrench@gmail.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