From: Mike Snitzer <snitzer@kernel.org>
To: Chuck Lever <cel@kernel.org>, Jeff Layton <jlayton@kernel.org>
Cc: linux-nfs@vger.kernel.org, NeilBrown <neil@brown.name>,
Olga Kornievskaia <okorniev@redhat.com>,
Dai Ngo <Dai.Ngo@oracle.com>, Tom Talpey <tom@talpey.com>,
Christoph Hellwig <hch@lst.de>, Jens Axboe <axboe@kernel.dk>,
Matthew Wilcox <willy@infradead.org>,
linux-mm@kvack.org
Subject: [PATCH v4 05/10] NFSD: do not use direct I/O for a READ smaller than its alignment
Date: Thu, 15 Oct 2026 19:33:04 -0400 [thread overview]
Message-ID: <20261015233309.42999-6-snitzer@kernel.org> (raw)
In-Reply-To: <20261015233309.42999-1-snitzer@kernel.org>
nfsd_direct_read() expands a misaligned READ out to DIO-aligned
boundaries: it reads from round_down(offset, dio_read_offset_align) to
round_up(offset + count, dio_read_offset_align) and returns only the
requested bytes from within that window. When the READ is smaller than
the alignment, that window is always at least one full alignment unit,
and two when the READ straddles a boundary, so a few hundred bytes of
payload can cost a 4K or 64K device read.
Decline direct I/O for those. A READ smaller than
dio_read_offset_align now falls through to the DONTCACHE path, which
issues DONTCACHE buffered I/O when the file system supports
FOP_DONTCACHE and normal buffered I/O otherwise. This mirrors the
WRITE side, which already declines direct I/O for a WRITE smaller than
the larger of its offset and memory alignments.
Only dio_read_offset_align is consulted: nfsd_direct_read() lands the
data in whole rq_pages pages at offset zero, so dio_mem_align is always
satisfied and only the file offset and length can be misaligned. The
threshold only bites when the file system advertises a large alignment;
where it reports 512 almost no READ is excluded.
Document it in the "Misaligned READ" section of nfsd-io-modes.rst.
Assisted-by: LLM
Signed-off-by: Mike Snitzer <snitzer@kernel.org>
---
Documentation/filesystems/nfs/nfsd-io-modes.rst | 5 +++++
fs/nfsd/vfs.c | 11 +++++++++--
2 files changed, 14 insertions(+), 2 deletions(-)
diff --git a/Documentation/filesystems/nfs/nfsd-io-modes.rst b/Documentation/filesystems/nfs/nfsd-io-modes.rst
index 2679d85152dfc..90bf1038453cc 100644
--- a/Documentation/filesystems/nfs/nfsd-io-modes.rst
+++ b/Documentation/filesystems/nfs/nfsd-io-modes.rst
@@ -121,6 +121,11 @@ Misaligned READ:
verified to have proper offset/len (logical_block_size) and
dma_alignment checking.
+ A READ smaller than dio_read_offset_align is not expanded: it would
+ read one or two whole alignment units to return less than one unit
+ of data. It is issued as DONTCACHE buffered IO instead (normal
+ buffered IO if the filesystem lacks FOP_DONTCACHE).
+
Misaligned WRITE:
If NFSD_IO_DIRECT is used, split any misaligned WRITE into a start,
middle and end as needed. The large middle segment is DIO-aligned
diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c
index b596bd61f8cb7..7e65328de7c86 100644
--- a/fs/nfsd/vfs.c
+++ b/fs/nfsd/vfs.c
@@ -1166,11 +1166,18 @@ nfsd_direct_read(struct svc_rqst *rqstp, struct svc_fh *fhp,
eof, host_err);
}
-static bool nfsd_direct_read_ok(struct svc_rqst *rqstp, struct nfsd_file *nf)
+static bool nfsd_direct_read_ok(struct svc_rqst *rqstp, struct nfsd_file *nf,
+ unsigned long count)
{
/* When dio_read_offset_align is zero, dio is not supported */
if (!nf->nf_dio_read_offset_align)
return false;
+ /*
+ * A READ smaller than that alignment is not worth expanding to one
+ * or two whole alignment units.
+ */
+ if (count < nf->nf_dio_read_offset_align)
+ return false;
if (rqstp->rq_res.page_len)
return false;
#ifdef CONFIG_NFSD_V4
@@ -1222,7 +1229,7 @@ __be32 nfsd_iter_read(struct svc_rqst *rqstp, struct svc_fh *fhp,
case NFSD_IO_BUFFERED:
break;
case NFSD_IO_DIRECT:
- if (nfsd_direct_read_ok(rqstp, nf))
+ if (nfsd_direct_read_ok(rqstp, nf, *count))
return nfsd_direct_read(rqstp, fhp, nf, offset,
count, page, eof);
fallthrough;
--
2.52.0
next prev parent reply other threads:[~2026-10-15 23:33 UTC|newest]
Thread overview: 11+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-10-15 23:32 [PATCH v4 00/10] NFSD: keep direct-mode I/O out of the page cache Mike Snitzer
2026-10-15 23:33 ` [PATCH v4 01/10] NFSD: cut a misaligned direct-mode WRITE at page boundaries Mike Snitzer
2026-10-15 23:33 ` [PATCH v4 02/10] NFSD: mark the direct middle of a split WRITE IOCB_DONTCACHE as well Mike Snitzer
2026-10-15 23:33 ` [PATCH v4 03/10] NFSD: only split a direct-mode WRITE for a worthwhile direct middle Mike Snitzer
2026-10-15 23:33 ` [PATCH v4 04/10] NFSD: add direct_misaligned_dontcache debugfs knob Mike Snitzer
2026-10-15 23:33 ` Mike Snitzer [this message]
2026-10-15 23:33 ` [PATCH v4 06/10] NFSD: persist a synchronous direct-mode WRITE once, after all of its segments Mike Snitzer
2026-10-15 23:33 ` [PATCH v4 07/10] mm: add folio_mark_dropbehind() to mark a folio dropbehind and account it Mike Snitzer
2026-10-15 23:33 ` [PATCH v4 08/10] mm: expose WB_DONTCACHE_DIRTY in bdi debugfs stats Mike Snitzer
2026-10-15 23:33 ` [PATCH v4 09/10] NFSD: keep boundary page of a split direct-mode WRITE until both writers complete Mike Snitzer
2026-10-15 23:33 ` [PATCH v4 10/10] NFSD: add tracing for how direct-mode READ and WRITE are serviced Mike Snitzer
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=20261015233309.42999-6-snitzer@kernel.org \
--to=snitzer@kernel.org \
--cc=Dai.Ngo@oracle.com \
--cc=axboe@kernel.dk \
--cc=cel@kernel.org \
--cc=hch@lst.de \
--cc=jlayton@kernel.org \
--cc=linux-mm@kvack.org \
--cc=linux-nfs@vger.kernel.org \
--cc=neil@brown.name \
--cc=okorniev@redhat.com \
--cc=tom@talpey.com \
--cc=willy@infradead.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.