* [PATCH] pnfs/blocklayout: don't let a READ layout hide written extents
@ 2026-10-30 7:40 ` Daejun Park via B4 Relay
0 siblings, 0 replies; 3+ messages in thread
From: Daejun Park @ 2026-10-30 7:40 UTC (permalink / raw)
To: Trond Myklebust, Anna Schumaker
Cc: Christoph Hellwig, Benjamin Coddington, linux-nfs, Daejun Park
Once a client writes to an INVALID_DATA extent, reads must use it
(RFC 5663, section 2.3.4). A READ layout fetched before LAYOUTCOMMIT
can map the range as NONE_DATA. Lookups check read-only extents first.
The client then reads zeroes until the layout is returned.
Do not add read-only extents over written or READ_WRITE_DATA extents.
Fixes: 8067253c8cc5 ("pnfs/blocklayout: rewrite extent tracking")
Signed-off-by: Daejun Park <daejun7.park@samsung.com>
---
Against next-20261006. extent_tree.c is the same in next-20261029
and in mainline 65ba8f34ec88.
Tested against Linux nfsd on XFS: an O_DIRECT write into a range with
no data, then a read across it, returned zeroes in 12 of 12 runs before
and the written data after. generic/013, 091 and 263 pass.
---
fs/nfs/blocklayout/extent_tree.c | 27 ++++++++++++++++++++++++++-
1 file changed, 26 insertions(+), 1 deletion(-)
diff --git a/fs/nfs/blocklayout/extent_tree.c b/fs/nfs/blocklayout/extent_tree.c
index 7393118c42..40a6ab6329 100644
--- a/fs/nfs/blocklayout/extent_tree.c
+++ b/fs/nfs/blocklayout/extent_tree.c
@@ -252,6 +252,28 @@ __ext_tree_remove(struct rb_root *root,
return 0;
}
+/*
+ * Return the first extent at or after @start that a new read-only
+ * extent must not cover: an ro extent, or an rw extent before @end
+ * that reads use. An INVALID_DATA extent not yet written to does
+ * not count: reads of it use the ro extent below it (copy-on-write).
+ */
+static struct pnfs_block_extent *
+ext_tree_search_ro(struct pnfs_block_layout *bl, sector_t start, sector_t end)
+{
+ struct pnfs_block_extent *be = __ext_tree_search(&bl->bl_ext_ro, start);
+ struct pnfs_block_extent *rw;
+
+ if (be && be->be_f_offset < end)
+ end = be->be_f_offset;
+ for (rw = __ext_tree_search(&bl->bl_ext_rw, start);
+ rw && rw->be_f_offset < end; rw = ext_tree_next(rw)) {
+ if (rw->be_state != PNFS_BLOCK_INVALID_DATA || rw->be_tag)
+ return rw;
+ }
+ return be;
+}
+
int
ext_tree_insert(struct pnfs_block_layout *bl, struct pnfs_block_extent *new)
{
@@ -275,7 +297,10 @@ ext_tree_insert(struct pnfs_block_layout *bl, struct pnfs_block_extent *new)
spin_lock(&bl->bl_ext_lock);
retry:
- be = __ext_tree_search(root, new->be_f_offset);
+ if (root == &bl->bl_ext_ro)
+ be = ext_tree_search_ro(bl, new->be_f_offset, ext_f_end(new));
+ else
+ be = __ext_tree_search(root, new->be_f_offset);
if (!be || be->be_f_offset >= ext_f_end(new)) {
__ext_tree_insert(root, new, true);
} else if (new->be_f_offset >= be->be_f_offset) {
---
base-commit: eea3fef32a9cf36abcb5975a5a594e4135a6b026
change-id: 20261030-nfs-bl-ro-cdbf608f4f0d
Best regards,
--
Daejun Park <daejun7.park@samsung.com>
^ permalink raw reply related [flat|nested] 3+ messages in thread
* [PATCH] pnfs/blocklayout: don't let a READ layout hide written extents
@ 2026-10-30 7:40 ` Daejun Park via B4 Relay
0 siblings, 0 replies; 3+ messages in thread
From: Daejun Park via B4 Relay @ 2026-10-30 7:40 UTC (permalink / raw)
To: Trond Myklebust, Anna Schumaker
Cc: Christoph Hellwig, Benjamin Coddington, linux-nfs, Daejun Park
From: Daejun Park <daejun7.park@samsung.com>
Once a client writes to an INVALID_DATA extent, reads must use it
(RFC 5663, section 2.3.4). A READ layout fetched before LAYOUTCOMMIT
can map the range as NONE_DATA. Lookups check read-only extents first.
The client then reads zeroes until the layout is returned.
Do not add read-only extents over written or READ_WRITE_DATA extents.
Fixes: 8067253c8cc5 ("pnfs/blocklayout: rewrite extent tracking")
Signed-off-by: Daejun Park <daejun7.park@samsung.com>
---
Against next-20261006. extent_tree.c is the same in next-20261029
and in mainline 65ba8f34ec88.
Tested against Linux nfsd on XFS: an O_DIRECT write into a range with
no data, then a read across it, returned zeroes in 12 of 12 runs before
and the written data after. generic/013, 091 and 263 pass.
---
fs/nfs/blocklayout/extent_tree.c | 27 ++++++++++++++++++++++++++-
1 file changed, 26 insertions(+), 1 deletion(-)
diff --git a/fs/nfs/blocklayout/extent_tree.c b/fs/nfs/blocklayout/extent_tree.c
index 7393118c42..40a6ab6329 100644
--- a/fs/nfs/blocklayout/extent_tree.c
+++ b/fs/nfs/blocklayout/extent_tree.c
@@ -252,6 +252,28 @@ __ext_tree_remove(struct rb_root *root,
return 0;
}
+/*
+ * Return the first extent at or after @start that a new read-only
+ * extent must not cover: an ro extent, or an rw extent before @end
+ * that reads use. An INVALID_DATA extent not yet written to does
+ * not count: reads of it use the ro extent below it (copy-on-write).
+ */
+static struct pnfs_block_extent *
+ext_tree_search_ro(struct pnfs_block_layout *bl, sector_t start, sector_t end)
+{
+ struct pnfs_block_extent *be = __ext_tree_search(&bl->bl_ext_ro, start);
+ struct pnfs_block_extent *rw;
+
+ if (be && be->be_f_offset < end)
+ end = be->be_f_offset;
+ for (rw = __ext_tree_search(&bl->bl_ext_rw, start);
+ rw && rw->be_f_offset < end; rw = ext_tree_next(rw)) {
+ if (rw->be_state != PNFS_BLOCK_INVALID_DATA || rw->be_tag)
+ return rw;
+ }
+ return be;
+}
+
int
ext_tree_insert(struct pnfs_block_layout *bl, struct pnfs_block_extent *new)
{
@@ -275,7 +297,10 @@ ext_tree_insert(struct pnfs_block_layout *bl, struct pnfs_block_extent *new)
spin_lock(&bl->bl_ext_lock);
retry:
- be = __ext_tree_search(root, new->be_f_offset);
+ if (root == &bl->bl_ext_ro)
+ be = ext_tree_search_ro(bl, new->be_f_offset, ext_f_end(new));
+ else
+ be = __ext_tree_search(root, new->be_f_offset);
if (!be || be->be_f_offset >= ext_f_end(new)) {
__ext_tree_insert(root, new, true);
} else if (new->be_f_offset >= be->be_f_offset) {
---
base-commit: eea3fef32a9cf36abcb5975a5a594e4135a6b026
change-id: 20261030-nfs-bl-ro-cdbf608f4f0d
Best regards,
--
Daejun Park <daejun7.park@samsung.com>
^ permalink raw reply related [flat|nested] 3+ messages in thread
* Re: [PATCH] pnfs/blocklayout: don't let a READ layout hide written extents
2026-10-30 7:40 ` Daejun Park via B4 Relay
(?)
@ 2026-11-03 7:50 ` Christoph Hellwig
-1 siblings, 0 replies; 3+ messages in thread
From: Christoph Hellwig @ 2026-11-03 7:50 UTC (permalink / raw)
To: daejun7.park
Cc: Trond Myklebust, Anna Schumaker, Christoph Hellwig,
Benjamin Coddington, linux-nfs
Looks good:
Reviewed-by: Christoph Hellwig <hch@lst.de>
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2026-11-03 7:50 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-10-30 7:40 [PATCH] pnfs/blocklayout: don't let a READ layout hide written extents Daejun Park
2026-10-30 7:40 ` Daejun Park via B4 Relay
2026-11-03 7:50 ` Christoph Hellwig
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.