From: Chuck Lever <cel@kernel.org>
To: NeilBrown <neil@brown.name>, Jeff Layton <jlayton@kernel.org>,
Olga Kornievskaia <okorniev@redhat.com>,
Dai Ngo <dai.ngo@oracle.com>, Tom Talpey <tom@talpey.com>
Cc: <linux-nfs@vger.kernel.org>, Christoph Hellwig <hch@lst.de>,
Chuck Lever <chuck.lever@oracle.com>
Subject: [PATCH v8 10/12] NFSD: Combine direct I/O feasibility check with iterator setup
Date: Mon, 27 Oct 2025 11:46:28 -0400 [thread overview]
Message-ID: <20251027154630.1774-11-cel@kernel.org> (raw)
In-Reply-To: <20251027154630.1774-1-cel@kernel.org>
From: Chuck Lever <chuck.lever@oracle.com>
When direct I/O is not feasible (due to missing alignment info,
too-small writes, or no alignment possible), pack the entire
write payload into a single non-DIO segment and follow the usual
direct write I/O path.
This simplifies nfsd_direct_write() by eliminating the fallback path
and the separate nfsd_buffered_write() call - all writes now go
through nfsd_issue_write_dio() which handles both DIO and buffered
segments.
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
---
fs/nfsd/vfs.c | 69 +++++++++++++++++++++------------------------------
1 file changed, 28 insertions(+), 41 deletions(-)
diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c
index a872be300c9f..be0688f2ab3d 100644
--- a/fs/nfsd/vfs.c
+++ b/fs/nfsd/vfs.c
@@ -1304,30 +1304,6 @@ nfsd_find_dio_aligned_offset(struct nfsd_file *nf, loff_t file_offset,
return SIZE_MAX; /* No alignment found */
}
-/*
- * Check if the underlying file system implements direct I/O.
- */
-static bool
-nfsd_is_write_dio_possible(loff_t offset, unsigned long len,
- struct nfsd_write_dio_args *args)
-{
- u32 offset_align = args->nf->nf_dio_offset_align;
- u32 mem_align = args->nf->nf_dio_mem_align;
-
- if (unlikely(!mem_align || !offset_align))
- return false;
-
- /*
- * Need enough data to potentially find an aligned segment.
- * In the worst case, we might need up to
- * lcm(offset_align, mem_align) bytes for the prefix.
- */
- if (unlikely(len < max(offset_align, mem_align)))
- return false;
-
- return true;
-}
-
static void
nfsd_write_dio_seg_init(struct nfsd_write_dio_seg *segment,
struct bio_vec *bvec, unsigned int nvecs,
@@ -1340,22 +1316,31 @@ nfsd_write_dio_seg_init(struct nfsd_write_dio_seg *segment,
segment->use_dio = false;
}
-static bool
-nfsd_setup_write_dio_iters(struct bio_vec *bvec, unsigned int nvecs,
- loff_t offset, unsigned long total,
- struct nfsd_write_dio_args *args)
+static void
+nfsd_write_dio_iters_init(struct bio_vec *bvec, unsigned int nvecs,
+ loff_t offset, unsigned long total,
+ struct nfsd_write_dio_args *args)
{
u32 offset_align = args->nf->nf_dio_offset_align;
+ u32 mem_align = args->nf->nf_dio_mem_align;
unsigned long mem_offset = bvec->bv_offset;
loff_t prefix_end, orig_end, middle_end;
size_t prefix, middle, suffix;
args->nsegs = 0;
+ /*
+ * Check if direct I/O is feasible for this write request.
+ * If alignments are not available, the write is too small,
+ * or no alignment can be found, fall back to buffered I/O.
+ */
+ if (unlikely(!mem_align || !offset_align) ||
+ unlikely(total < max(offset_align, mem_align)))
+ goto no_dio;
prefix = nfsd_find_dio_aligned_offset(args->nf, offset, mem_offset,
total);
if (prefix == SIZE_MAX)
- return false; /* No alignment possible */
+ goto no_dio;
prefix_end = offset + prefix;
orig_end = offset + total;
@@ -1371,7 +1356,7 @@ nfsd_setup_write_dio_iters(struct bio_vec *bvec, unsigned int nvecs,
}
if (!middle)
- return false; /* No aligned region for DIO */
+ goto no_dio;
nfsd_write_dio_seg_init(&args->segment[args->nsegs], bvec, nvecs,
total, prefix, middle);
@@ -1384,7 +1369,13 @@ nfsd_setup_write_dio_iters(struct bio_vec *bvec, unsigned int nvecs,
++args->nsegs;
}
- return true;
+ return;
+
+no_dio:
+ /* No alignment possible - pack into single non-DIO segment */
+ nfsd_write_dio_seg_init(&args->segment[0], bvec, nvecs, total,
+ 0, total);
+ args->nsegs = 1;
}
static int
@@ -1405,7 +1396,7 @@ nfsd_buffered_write(struct svc_rqst *rqstp, struct file *file,
}
static int
-nfsd_issue_write_dio(struct svc_rqst *rqstp, struct svc_fh *fhp, u32 *stable_how,
+nfsd_issue_dio_write(struct svc_rqst *rqstp, struct svc_fh *fhp, u32 *stable_how,
struct kiocb *kiocb, unsigned int nvecs, unsigned long *cnt,
struct nfsd_write_dio_args *args)
{
@@ -1413,10 +1404,6 @@ nfsd_issue_write_dio(struct svc_rqst *rqstp, struct svc_fh *fhp, u32 *stable_how
ssize_t host_err;
unsigned int i;
- if (!nfsd_setup_write_dio_iters(rqstp->rq_bvec, nvecs, kiocb->ki_pos,
- *cnt, args))
- return nfsd_buffered_write(rqstp, file, nvecs, cnt, kiocb);
-
/*
* Any buffered IO issued here will be misaligned, use
* sync IO to ensure it has completed before returning.
@@ -1425,6 +1412,9 @@ nfsd_issue_write_dio(struct svc_rqst *rqstp, struct svc_fh *fhp, u32 *stable_how
kiocb->ki_flags |= (IOCB_DSYNC|IOCB_SYNC);
*stable_how = NFS_FILE_SYNC;
+ nfsd_write_dio_iters_init(rqstp->rq_bvec, nvecs, kiocb->ki_pos,
+ *cnt, args);
+
*cnt = 0;
for (i = 0; i < args->nsegs; i++) {
if (args->segment[i].use_dio) {
@@ -1463,11 +1453,8 @@ nfsd_direct_write(struct svc_rqst *rqstp, struct svc_fh *fhp,
if (args.nf->nf_file->f_op->fop_flags & FOP_DONTCACHE)
kiocb->ki_flags |= IOCB_DONTCACHE;
- if (nfsd_is_write_dio_possible(kiocb->ki_pos, *cnt, &args))
- return nfsd_issue_write_dio(rqstp, fhp, stable_how, kiocb,
- nvecs, cnt, &args);
-
- return nfsd_buffered_write(rqstp, args.nf->nf_file, nvecs, cnt, kiocb);
+ return nfsd_issue_dio_write(rqstp, fhp, stable_how, kiocb, nvecs,
+ cnt, &args);
}
/**
--
2.51.0
next prev parent reply other threads:[~2025-10-27 15:46 UTC|newest]
Thread overview: 27+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-10-27 15:46 [PATCH v8 00/12] NFSD: Implement NFSD_IO_DIRECT for NFS WRITE Chuck Lever
2025-10-27 15:46 ` [PATCH v8 01/12] NFSD: Make FILE_SYNC WRITEs comply with spec Chuck Lever
2025-10-27 15:46 ` [PATCH v8 02/12] NFSD: Enable return of an updated stable_how to NFS clients Chuck Lever
2025-10-27 15:46 ` [PATCH v8 03/12] NFSD: Implement NFSD_IO_DIRECT for NFS WRITE Chuck Lever
2025-10-27 15:46 ` [PATCH v8 04/12] NFSD: Remove specific error handling Chuck Lever
2025-10-27 15:46 ` [PATCH v8 05/12] NFSD: Remove alignment size checking Chuck Lever
2025-10-27 15:46 ` [PATCH v8 06/12] NFSD: Clean up struct nfsd_write_dio Chuck Lever
2025-10-27 15:46 ` [PATCH v8 07/12] NFSD: Introduce struct nfsd_write_dio_seg Chuck Lever
2025-10-27 15:46 ` [PATCH v8 08/12] NFSD: Simplify nfsd_iov_iter_aligned_bvec() Chuck Lever
2025-10-30 15:00 ` Jeff Layton
2025-10-31 13:16 ` Christoph Hellwig
2025-10-27 15:46 ` [PATCH v8 09/12] NFSD: Handle both offset and memory alignment for direct I/O Chuck Lever
2025-10-30 19:52 ` Jeff Layton
2025-10-30 19:55 ` Chuck Lever
2025-10-31 9:13 ` Christoph Hellwig
2025-10-31 13:19 ` Christoph Hellwig
2025-10-31 13:21 ` Chuck Lever
2025-10-31 13:23 ` Christoph Hellwig
2025-10-31 16:07 ` Mike Snitzer
2025-10-27 15:46 ` Chuck Lever [this message]
2025-10-30 19:59 ` [PATCH v8 10/12] NFSD: Combine direct I/O feasibility check with iterator setup Jeff Layton
2025-10-31 13:20 ` Christoph Hellwig
2025-10-27 15:46 ` [PATCH v8 11/12] NFSD: Handle kiocb->ki_flags correctly Chuck Lever
2025-10-30 20:01 ` Jeff Layton
2025-10-31 13:21 ` Christoph Hellwig
2025-10-27 15:46 ` [PATCH v8 12/12] NFSD: Refactor nfsd_vfs_write Chuck Lever
2025-10-30 20:02 ` 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=20251027154630.1774-11-cel@kernel.org \
--to=cel@kernel.org \
--cc=chuck.lever@oracle.com \
--cc=dai.ngo@oracle.com \
--cc=hch@lst.de \
--cc=jlayton@kernel.org \
--cc=linux-nfs@vger.kernel.org \
--cc=neil@brown.name \
--cc=okorniev@redhat.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