From: Jeff Layton <jlayton@kernel.org>
To: Chuck Lever <cel@kernel.org>, NeilBrown <neil@brown.name>,
Olga Kornievskaia <okorniev@redhat.com>,
Dai Ngo <Dai.Ngo@oracle.com>, Tom Talpey <tom@talpey.com>,
Trond Myklebust <trondmy@kernel.org>,
Anna Schumaker <anna@kernel.org>,
Jonathan Corbet <corbet@lwn.net>,
Shuah Khan <skhan@linuxfoundation.org>,
Randy Dunlap <rdunlap@infradead.org>,
Mike Snitzer <snitzer@kernel.org>,
Donald Hunter <donald.hunter@gmail.com>,
Jakub Kicinski <kuba@kernel.org>,
"David S. Miller" <davem@davemloft.net>,
Eric Dumazet <edumazet@kernel.org>,
Paolo Abeni <pabeni@redhat.com>, Simon Horman <horms@kernel.org>
Cc: Steve Dickson <steved@redhat.com>,
netdev@vger.kernel.org, linux-kernel@vger.kernel.org,
linux-nfs@vger.kernel.org, linux-doc@vger.kernel.org,
Jeff Layton <jlayton@kernel.org>
Subject: [PATCH 2/6] NFSD: Apply per-export I/O modes to READ and WRITE
Date: Tue, 27 Oct 2026 12:45:25 -0400 [thread overview]
Message-ID: <20261027-export-iomode-v1-2-262ed932a036@kernel.org> (raw)
In-Reply-To: <20261027-export-iomode-v1-0-262ed932a036@kernel.org>
Resolve each export's effective I/O mode (explicit setting, else the
global io_cache_read/write knob) in nfsd_iter_read and nfsd_vfs_write,
and skip splice for reads on exports whose effective read mode is not
buffered. Update the debugfs knob comments to match.
Signed-off-by: Jeff Layton <jlayton@kernel.org>
---
fs/nfsd/debugfs.c | 6 ++++--
fs/nfsd/nfs4xdr.c | 6 ++++--
fs/nfsd/vfs.c | 39 ++++++++++++++++++++++++++++++++++++---
fs/nfsd/vfs.h | 2 ++
4 files changed, 46 insertions(+), 7 deletions(-)
diff --git a/fs/nfsd/debugfs.c b/fs/nfsd/debugfs.c
index 4af1e6b8b212..a10159db3b60 100644
--- a/fs/nfsd/debugfs.c
+++ b/fs/nfsd/debugfs.c
@@ -47,7 +47,8 @@ DEFINE_DEBUGFS_ATTRIBUTE(nfsd_dsr_fops, nfsd_dsr_get, nfsd_dsr_set, "%llu\n");
* %2: NFS READ will use direct IO
*
* This setting takes immediate effect for all NFS versions,
- * all exports, and in all NFSD net namespaces.
+ * all exports without an explicit riomode= setting, and in all
+ * NFSD net namespaces.
*/
static int nfsd_io_cache_read_get(void *data, u64 *val)
@@ -92,7 +93,8 @@ DEFINE_DEBUGFS_ATTRIBUTE(nfsd_io_cache_read_fops, nfsd_io_cache_read_get,
* %1: NFS WRITE will use dontcache (buffered IO w/ dropbehind)
*
* This setting takes immediate effect for all NFS versions,
- * all exports, and in all NFSD net namespaces.
+ * all exports without an explicit wiomode= setting, and in all
+ * NFSD net namespaces.
*/
static int nfsd_io_cache_write_get(void *data, u64 *val)
diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c
index 4d983444604a..9215feeeb0ba 100644
--- a/fs/nfsd/nfs4xdr.c
+++ b/fs/nfsd/nfs4xdr.c
@@ -5366,7 +5366,8 @@ nfsd4_encode_read(struct nfsd4_compoundres *resp, __be32 nfserr,
maxcount = min_t(unsigned long, read->rd_length,
(xdr->buf->buflen - xdr->buf->len));
- if (file->f_op->splice_read && splice_ok)
+ if (file->f_op->splice_read && splice_ok &&
+ nfsd_read_iomode(read->rd_fhp->fh_export) == NFSD_IO_BUFFERED)
nfserr = nfsd4_encode_splice_read(resp, read, file, maxcount);
else
nfserr = nfsd4_encode_readv(resp, read, maxcount);
@@ -6264,7 +6265,8 @@ nfsd4_encode_read_plus_data(struct nfsd4_compoundres *resp,
maxcount = min_t(unsigned long, read->rd_length,
(xdr->buf->buflen - xdr->buf->len));
- if (file->f_op->splice_read && splice_ok)
+ if (file->f_op->splice_read && splice_ok &&
+ nfsd_read_iomode(read->rd_fhp->fh_export) == NFSD_IO_BUFFERED)
nfserr = nfsd4_encode_splice_read(resp, read, file, maxcount);
else
nfserr = nfsd4_encode_readv(resp, read, maxcount);
diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c
index 7f9ec6c4af6d..15613b6df290 100644
--- a/fs/nfsd/vfs.c
+++ b/fs/nfsd/vfs.c
@@ -1266,6 +1266,38 @@ static bool nfsd_direct_read_ok(struct svc_rqst *rqstp, struct svc_fh *fhp,
return true;
}
+/**
+ * nfsd_read_iomode - effective NFS READ I/O mode for an export
+ * @exp: export being accessed
+ *
+ * An export without an explicit riomode= setting follows the global
+ * nfsd_io_cache_read knob.
+ *
+ * Returns one of NFSD_IO_BUFFERED, NFSD_IO_DONTCACHE, or NFSD_IO_DIRECT.
+ */
+int nfsd_read_iomode(struct svc_export *exp)
+{
+ if (exp->ex_riomode == NFSD_IO_DEFAULT)
+ return nfsd_io_cache_read;
+ return exp->ex_riomode;
+}
+
+/**
+ * nfsd_write_iomode - effective NFS WRITE I/O mode for an export
+ * @exp: export being accessed
+ *
+ * An export without an explicit wiomode= setting follows the global
+ * nfsd_io_cache_write knob.
+ *
+ * Returns one of NFSD_IO_BUFFERED, NFSD_IO_DONTCACHE, or NFSD_IO_DIRECT.
+ */
+int nfsd_write_iomode(struct svc_export *exp)
+{
+ if (exp->ex_wiomode == NFSD_IO_DEFAULT)
+ return nfsd_io_cache_write;
+ return exp->ex_wiomode;
+}
+
/**
* nfsd_iter_read - Perform a VFS read using an iterator
* @rqstp: RPC transaction context
@@ -1300,7 +1332,7 @@ __be32 nfsd_iter_read(struct svc_rqst *rqstp, struct svc_fh *fhp,
init_sync_kiocb(&kiocb, file);
- switch (nfsd_io_cache_read) {
+ switch (nfsd_read_iomode(fhp->fh_export)) {
case NFSD_IO_BUFFERED:
break;
case NFSD_IO_DIRECT:
@@ -1746,7 +1778,7 @@ nfsd_vfs_write(struct svc_rqst *rqstp, struct svc_fh *fhp,
if (verf)
nfsd_copy_write_verifier(verf, nn);
- switch (nfsd_io_cache_write) {
+ switch (nfsd_write_iomode(exp)) {
case NFSD_IO_DIRECT:
host_err = nfsd_direct_write(rqstp, fhp, nf, nvecs,
cnt, &kiocb);
@@ -1853,7 +1885,8 @@ __be32 nfsd_read(struct svc_rqst *rqstp, struct svc_fh *fhp,
return err;
file = nf->nf_file;
- if (file->f_op->splice_read && nfsd_read_splice_ok(rqstp))
+ if (file->f_op->splice_read && nfsd_read_splice_ok(rqstp) &&
+ nfsd_read_iomode(fhp->fh_export) == NFSD_IO_BUFFERED)
err = nfsd_splice_read(rqstp, fhp, file, offset, count, eof);
else
err = nfsd_iter_read(rqstp, fhp, nf, offset, count, eof);
diff --git a/fs/nfsd/vfs.h b/fs/nfsd/vfs.h
index 1f05c83a3ea6..e95611b79397 100644
--- a/fs/nfsd/vfs.h
+++ b/fs/nfsd/vfs.h
@@ -184,6 +184,8 @@ __be32 nfsd_iter_read(struct svc_rqst *rqstp, struct svc_fh *fhp,
struct nfsd_file *nf, loff_t offset,
unsigned long *count, u32 *eof);
bool nfsd_read_splice_ok(struct svc_rqst *rqstp);
+int nfsd_read_iomode(struct svc_export *exp);
+int nfsd_write_iomode(struct svc_export *exp);
__be32 nfsd_read(struct svc_rqst *rqstp, struct svc_fh *fhp,
loff_t offset, unsigned long *count,
u32 *eof);
--
2.56.0
next prev parent reply other threads:[~2026-10-27 16:45 UTC|newest]
Thread overview: 10+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-10-27 16:45 [PATCH 0/6] nfsd: add new export options for controlling read/write iomode Jeff Layton
2026-10-27 16:45 ` [PATCH 1/6] NFSD: Add per-export read/write I/O mode settings Jeff Layton
2026-10-27 16:45 ` Jeff Layton [this message]
2026-10-27 17:54 ` [PATCH 2/6] NFSD: Apply per-export I/O modes to READ and WRITE Chuck Lever
2026-10-27 17:59 ` Jeff Layton
2026-10-27 19:42 ` Chuck Lever
2026-10-27 16:45 ` [PATCH 3/6] NFSD: Document per-export riomode= and wiomode= options Jeff Layton
2026-10-27 16:45 ` [PATCH 4/6] NFSD: Keep per-export statistics across export cache updates Jeff Layton
2026-10-27 16:45 ` [PATCH 5/6] NFSD: Count the storage reads of each export's READs Jeff Layton
2026-10-27 16:45 ` [PATCH 6/6] NFSD: Document how to choose an IO mode Jeff Layton
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=20261027-export-iomode-v1-2-262ed932a036@kernel.org \
--to=jlayton@kernel.org \
--cc=Dai.Ngo@oracle.com \
--cc=anna@kernel.org \
--cc=cel@kernel.org \
--cc=corbet@lwn.net \
--cc=davem@davemloft.net \
--cc=donald.hunter@gmail.com \
--cc=edumazet@kernel.org \
--cc=horms@kernel.org \
--cc=kuba@kernel.org \
--cc=linux-doc@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-nfs@vger.kernel.org \
--cc=neil@brown.name \
--cc=netdev@vger.kernel.org \
--cc=okorniev@redhat.com \
--cc=pabeni@redhat.com \
--cc=rdunlap@infradead.org \
--cc=skhan@linuxfoundation.org \
--cc=snitzer@kernel.org \
--cc=steved@redhat.com \
--cc=tom@talpey.com \
--cc=trondmy@kernel.org \
/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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.