[PATCH RFC 21/29] xfs: add writeback and iomap reading of Merkel tree pages

Andrey Albershteyn
2025-07-28T20:31:47Z

In the writeback path use unbound write interface, meaning that inode
size is not updated and none of the file size checks are applied.

In read path let iomap know that data is stored beyond EOF via flag.
This leads to skipping of post EOF zeroing.

Signed-off-by: Andrey Albershteyn <aalbersh@kernel.org>
---
fs/xfs/xfs_aops.c | 21 ++++++++++++++-------
fs/xfs/xfs_iomap.c | 9 +++++++--
2 files changed, 21 insertions(+), 9 deletions(-)

diff --git a/fs/xfs/xfs_aops.c b/fs/xfs/xfs_aops.c
index 63151feb9c3f..02e2c04b36c1 100644
--- a/fs/xfs/xfs_aops.c
+++ b/fs/xfs/xfs_aops.c
@@ -22,6 +22,7 @@
#include "xfs_icache.h"
#include "xfs_zone_alloc.h"
#include "xfs_rtgroup.h"
+#include "xfs_fsverity.h"

struct xfs_writepage_ctx {
struct iomap_writepage_ctx ctx;
@@ -628,10 +629,12 @@ static const struct iomap_writeback_ops xfs_zoned_writeback_ops = {

STATIC int
xfs_vm_writepages(
- struct address_space *mapping,
- struct writeback_control *wbc)
+ struct address_space *mapping,
+ struct writeback_control *wbc)
{
- struct xfs_inode *ip = XFS_I(mapping->host);
+ struct xfs_inode *ip = XFS_I(mapping->host);
+ struct xfs_writepage_ctx wpc = { };
+

xfs_iflags_clear(ip, XFS_ITRUNCATED);

@@ -644,12 +647,16 @@ xfs_vm_writepages(
if (xc.open_zone)
xfs_open_zone_put(xc.open_zone);
return error;
- } else {
- struct xfs_writepage_ctx wpc = { };
+ }

- return iomap_writepages(mapping, wbc, &wpc.ctx,
- &xfs_writeback_ops);
+ if (xfs_iflags_test(ip, XFS_VERITY_CONSTRUCTION)) {
+ wbc->range_start = XFS_FSVERITY_MTREE_OFFSET;
+ wbc->range_end = LLONG_MAX;
+ return iomap_writepages_unbound(mapping, wbc, &wpc.ctx,
+ &xfs_writeback_ops);
}
+
+ return iomap_writepages(mapping, wbc, &wpc.ctx, &xfs_writeback_ops);
}

STATIC int
diff --git a/fs/xfs/xfs_iomap.c b/fs/xfs/xfs_iomap.c
index 00ec1a738b39..c8725508165c 100644
--- a/fs/xfs/xfs_iomap.c
+++ b/fs/xfs/xfs_iomap.c
@@ -2031,6 +2031,7 @@ xfs_read_iomap_begin(
bool shared = false;
unsigned int lockmode = XFS_ILOCK_SHARED;
u64 seq;
+ int iomap_flags;

ASSERT(!(flags & (IOMAP_WRITE | IOMAP_ZERO)));

@@ -2050,8 +2051,12 @@ xfs_read_iomap_begin(
if (error)
return error;
trace_xfs_iomap_found(ip, offset, length, XFS_DATA_FORK, &imap);
- return xfs_bmbt_to_iomap(ip, iomap, &imap, flags,
- shared ? IOMAP_F_SHARED : 0, seq);
+ iomap_flags = shared ? IOMAP_F_SHARED : 0;
+
+ if (fsverity_active(inode) && offset >= XFS_FSVERITY_MTREE_OFFSET)
+ iomap_flags |= IOMAP_F_BEYOND_EOF;
+
+ return xfs_bmbt_to_iomap(ip, iomap, &imap, flags, iomap_flags, seq);
}

const struct iomap_ops xfs_read_iomap_ops = {

--
2.50.0