@@ -28,6 +28,16 @@ _scratch_mkfs >/dev/null 2>&1
_require_metadata_journaling $SCRATCH_DEV
_scratch_mount
+# This test requires that i_blocks remains unchanged from the start of the
+# check_inode_metadata call until after recovery is complete. fpunch calls
+# turn into pagecache writes if the arguments are not aligned to the fs
+# blocksize. If the range being punched is already mapped to a written extent
+# and alwayscow is enabled, i_blocks will increase by the size of the COW
+# staging extent. This causes stat to report different numbers for %b, which
+# results in a test failure. Hence do not run this test if XFS is in alwayscow
+# mode.
+test "$FSTYP" = "xfs" && _require_no_xfs_always_cow
+
testfile=$SCRATCH_MNT/testfile
# check inode metadata after shutdown
@@ -43,6 +43,18 @@ _scratch_mount >> $seqres.full
_require_congruent_file_oplen $SCRATCH_MNT $blksz
$XFS_IO_PROG -c "cowextsize $sz" $SCRATCH_MNT
+# This test uses a very large cowextszhint to manipulate the COW fork to
+# contain a large unwritten extent before injecting the error. The goal is
+# that the write() will succeed, writeback will flush the dirty data to disk,
+# and writeback completion will shut down the filesystem when it tries to
+# remove the staging extent record from the refcount btree. In other words,
+# this test ensures that XFS always finishes a COW completion it has started.
+#
+# This test isn't compatible with always_cow mode because the hole in the COW
+# fork left by the first write means that writeback tries to allocate a COW
+# staging extent for an unshared extent and trips over the injected error.
+_require_no_xfs_always_cow
+
echo "Create files"
_pwrite_byte 0x66 0 $sz $SCRATCH_MNT/file1 >> $seqres.full
_cp_reflink $SCRATCH_MNT/file1 $SCRATCH_MNT/file2
@@ -114,6 +114,12 @@ _require_xfs_io_error_injection "wb_delay_ms"
_require_scratch_reflink
_require_cp_reflink
+# This test races writeback of a pure overwrite of a data fork extent against
+# the creation of a speculative COW preallocation. In alwayscow mode, there
+# are no pure overwrites, which means that a precondition of the test is not
+# satisfied, and this test should be skipped.
+_require_no_xfs_always_cow
+
_scratch_mkfs >> $seqres.full
_scratch_mount >> $seqres.full