[PATCH RFC 20/29] xfs: disable preallocations for fsverity Merkle tree writes

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

While writing Merkle tree, file is read-only and there's no further
writes except Merkle tree building. The file is truncated beforehand to
remove any preallocated extents.

The Merkle tree is the only data XFS will write. As we don't want XFS to
truncate file after we done writing, let's also skip truncation on
fsverity files. Therefore, we also need to disable preallocations while
writing merkle tree as we don't want any unused extents past the tree.

Signed-off-by: Andrey Albershteyn <aalbersh@kernel.org>
---
fs/xfs/xfs_iomap.c | 13 ++++++++++++-
1 file changed, 12 insertions(+), 1 deletion(-)

diff --git a/fs/xfs/xfs_iomap.c b/fs/xfs/xfs_iomap.c
index ff05e6b1b0bb..00ec1a738b39 100644
--- a/fs/xfs/xfs_iomap.c
+++ b/fs/xfs/xfs_iomap.c
@@ -32,6 +32,8 @@
#include "xfs_rtbitmap.h"
#include "xfs_icache.h"
#include "xfs_zone_alloc.h"
+#include "xfs_fsverity.h"
+#include <linux/fsverity.h>

#define XFS_ALLOC_ALIGN(mp, off) \
(((off) >> mp->m_allocsize_log) << mp->m_allocsize_log)
@@ -1849,7 +1851,9 @@ xfs_buffered_write_iomap_begin(
* Determine the initial size of the preallocation.
* We clean up any extra preallocation when the file is closed.
*/
- if (xfs_has_allocsize(mp))
+ if (xfs_iflags_test(ip, XFS_VERITY_CONSTRUCTION))
+ prealloc_blocks = 0;
+ else if (xfs_has_allocsize(mp))
prealloc_blocks = mp->m_allocsize_blocks;
else if (allocfork == XFS_DATA_FORK)
prealloc_blocks = xfs_iomap_prealloc_size(ip, allocfork,
@@ -1976,6 +1980,13 @@ xfs_buffered_write_iomap_end(
if (flags & IOMAP_FAULT)
return 0;

+ /*
+ * While writing Merkle tree to disk we would not have any other
+ * delayed allocations
+ */
+ if (xfs_iflags_test(XFS_I(inode), XFS_VERITY_CONSTRUCTION))
+ return 0;
+
/* Nothing to do if we've written the entire delalloc extent */
start_byte = iomap_last_written_block(inode, offset, written);
end_byte = round_up(offset + length, i_blocksize(inode));

--
2.50.0