]> git-server-git.apps.pok.os.sepia.ceph.com Git - xfstests-dev.git/commitdiff
generic: add a test case for fallocate i_size extension
authorFilipe Manana <fdmanana@suse.com>
Tue, 19 May 2026 17:14:10 +0000 (18:14 +0100)
committerZorro Lang <zlang@kernel.org>
Wed, 20 May 2026 09:42:06 +0000 (17:42 +0800)
Test an i_size expanding fallocate into a range beyond current i_size that
already has a preallocated extent, with an unmount and mount after each
fallocate to verify that no metadata (i_size) and extents were lost.

This used to fail on btrfs when not using the no-holes feature (which is
a default since btrfs-progs 5.15) before this recent kernel fix:

  c562ba61fc5e ("btrfs: fix incorrect i_size after remount caused by KEEP_SIZE prealloc gap")

So in order to reproduce the failure when using an unpatched kernel and
a btrfs-progs >= 5.15, one must run the test with:

  MKFS_OPTIONS="-O ^no-holes"

Signed-off-by: Filipe Manana <fdmanana@suse.com>
Reviewed-by: Zorro Lang <zlang@kernel.org>
Reviewed-by: Qu Wenruo <wqu@suse.com>
Signed-off-by: Zorro Lang <zlang@kernel.org>
tests/generic/796 [new file with mode: 0755]
tests/generic/796.out [new file with mode: 0644]

diff --git a/tests/generic/796 b/tests/generic/796
new file mode 100755 (executable)
index 0000000..ee87348
--- /dev/null
@@ -0,0 +1,52 @@
+#! /bin/bash
+# SPDX-License-Identifier: GPL-2.0
+# Copyright (c) 2026 SUSE S.A.  All Rights Reserved.
+#
+# FS QA Test 796
+#
+# Test an i_size expanding fallocate into a range beyond current i_size that
+# already has a preallocated extent, with an unmount and mount after each
+# fallocate to verify that no metadata (i_size) and extents were lost.
+#
+. ./common/preamble
+_begin_fstest auto quick prealloc fiemap
+
+. ./common/punch # for _filter_fiemap
+
+_require_scratch
+_require_xfs_io_command "falloc" "-k"
+_require_xfs_io_command "fiemap"
+
+_fixed_by_fs_commit btrfs c562ba61fc5e \
+       "btrfs: fix incorrect i_size after remount caused by KEEP_SIZE prealloc gap"
+
+_scratch_mkfs >>$seqres.full 2>&1
+_scratch_mount
+
+# The fiemap results in the golden output requires file allocations to align to
+# 1M boundaries.
+_require_congruent_file_oplen $SCRATCH_MNT 1048576
+
+# Create our file with a size of 0 and a prealloc extent in the range [4M, 8M].
+$XFS_IO_PROG -f -c "falloc -k 4M 4M" $SCRATCH_MNT/foo
+
+# Unmount and mount again to remove any in memory state of the inode. We will
+# verify later that neither metadata nor extents were lost during unmount.
+_scratch_cycle_mount
+
+# Do an i_size expanding fallocate that overlaps the previous prealloc range
+# and extents past it. This increases the file size to 9M and allocates an
+# extent in the range [8M, 9M].
+$XFS_IO_PROG -c "falloc 7M 2M" $SCRATCH_MNT/foo
+
+# Unmount and mount again to remove any in memory state of the inode. We will
+# verify later that neither metadata nor extents were lost during unmount.
+_scratch_cycle_mount
+
+# File size should be 9M and we should have unwritten extents in range [4M, 9M].
+echo "File size after cycle mounts: $(stat -c %s $SCRATCH_MNT/foo)"
+echo "Fiemap output:"
+$XFS_IO_PROG -c "fiemap -v" $SCRATCH_MNT/foo | _filter_fiemap
+
+# Success, all done.
+_exit 0
diff --git a/tests/generic/796.out b/tests/generic/796.out
new file mode 100644 (file)
index 0000000..836a3ca
--- /dev/null
@@ -0,0 +1,5 @@
+QA output created by 796
+File size after cycle mounts: 9437184
+Fiemap output:
+0: [0..8191]: hole
+1: [8192..18431]: unwritten