[PATCH 03/21] NFSv4/flexfiles: Bound page coalescing on the absolute stripe offset
Benjamin Coddington <[email protected]>
| Newsgroups | org.kernel.vger.linux-nfs |
|---|---|
| Message-ID | <3d211bb3dcbb29c63936db084848afed5eaa1f4f.1786653063.git.bcodding@hammerspace.com> |
ff_layout_pg_test() was copied from the files layout, which partitions
data servers relative to pattern_offset and bounds coalescing with a
segment-relative offset. Flexfiles has no pattern_offset:
nfs4_ff_layout_calc_dss_id() partitions on the absolute file offset
(RFC 8435 Section 6). So when a layout segment's offset is not
stripe-unit-aligned, the segment-relative coalescing window is shifted
off the absolute stripe grid and a coalesced I/O can straddle a stripe
boundary, sending the bytes past it to the wrong data server.
Bound coalescing on the absolute offset to match calc_dss_id(). Aligned
segments, including all whole-file layouts, are unchanged.
Fixes: 4934ccbeaed3 ("NFSv4/flexfiles: Read path updates for striped layouts")
Cc: [email protected]
Assisted-by: Claude:claude-opus-4-8
Signed-off-by: Benjamin Coddington <[email protected]>
---
fs/nfs/flexfilelayout/flexfilelayout.c | 7 +++----
1 file changed, 3 insertions(+), 4 deletions(-)
diff --git a/fs/nfs/flexfilelayout/flexfilelayout.c b/fs/nfs/flexfilelayout/flexfilelayout.c
index cce56faa8b70..692ad84047d4 100644
--- a/fs/nfs/flexfilelayout/flexfilelayout.c
+++ b/fs/nfs/flexfilelayout/flexfilelayout.c
@@ -996,7 +996,6 @@ ff_layout_pg_test(struct nfs_pageio_descriptor *pgio, struct nfs_page *prev,
unsigned int size;
u64 p_stripe, r_stripe;
u32 stripe_offset;
- u64 segment_offset = pgio->pg_lseg->pls_range.offset;
u32 stripe_unit = FF_LAYOUT_LSEG(pgio->pg_lseg)->stripe_unit;
/* calls nfs_generic_pg_test */
@@ -1008,8 +1007,8 @@ ff_layout_pg_test(struct nfs_pageio_descriptor *pgio, struct nfs_page *prev,
/* see if req and prev are in the same stripe */
if (prev) {
- p_stripe = (u64)req_offset(prev) - segment_offset;
- r_stripe = (u64)req_offset(req) - segment_offset;
+ p_stripe = (u64)req_offset(prev);
+ r_stripe = (u64)req_offset(req);
do_div(p_stripe, stripe_unit);
do_div(r_stripe, stripe_unit);
@@ -1018,7 +1017,7 @@ ff_layout_pg_test(struct nfs_pageio_descriptor *pgio, struct nfs_page *prev,
}
/* calculate remaining bytes in the current stripe */
- div_u64_rem((u64)req_offset(req) - segment_offset,
+ div_u64_rem((u64)req_offset(req),
stripe_unit,
&stripe_offset);
WARN_ON_ONCE(stripe_offset > stripe_unit);
--
2.53.0