aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorQu Wenruo <wqu@suse.com>2022-01-28 08:27:00 +0800
committerEryu Guan <guaneryu@gmail.com>2022-02-14 01:17:46 +0800
commit8925b0290ffe0744d28f99a0a38e92e46cb85d75 (patch)
tree878f142875ce86528bfef114d6b75d19877d617d
parentd8639e1632ab3fe1d8044702699350ddf2499b12 (diff)
downloadxfstests-dev-8925b0290ffe0744d28f99a0a38e92e46cb85d75.tar.gz
btrfs: autodefrag with regular and hole extents
In v5.11~v5.15 kernels, there is a regression in autodefrag that if a cluster (up to 256K in size) has even a single hole, the whole cluster will be rejected. This will greatly reduce the efficiency of autodefrag. The behavior is fixed in v5.16 by a full rework, although the rework itself has other problems, it at least solves the problem. Here we add a test case to reproduce the case, where we have a 128K cluster, the first half is fragmented extents which can be defragged. The second half is hole. Make sure autodefrag can defrag the 64K part. Signed-off-by: Qu Wenruo <wqu@suse.com> Reviewed-by: Filipe Manana <fdmanana@suse.com> Signed-off-by: Eryu Guan <guaneryu@gmail.com>
-rwxr-xr-xtests/btrfs/25880
-rw-r--r--tests/btrfs/258.out2
2 files changed, 82 insertions, 0 deletions
diff --git a/tests/btrfs/258 b/tests/btrfs/258
new file mode 100755
index 0000000000..158eaf79a9
--- /dev/null
+++ b/tests/btrfs/258
@@ -0,0 +1,80 @@
+#! /bin/bash
+# SPDX-License-Identifier: GPL-2.0
+# Copyright (C) 2022 SUSE Linux Products GmbH. All Rights Reserved.
+#
+# FS QA Test 258
+#
+# Make sure btrfs auto defrag can properly defrag clusters which has hole
+# in the middle
+#
+. ./common/preamble
+_begin_fstest auto defrag quick
+
+. ./common/btrfs
+. ./common/filter
+
+# real QA test starts here
+
+# Modify as appropriate.
+_supported_fs generic
+_require_scratch
+
+# Needs 4K sectorsize, as larger sectorsize can change the file layout.
+_require_btrfs_support_sectorsize 4096
+
+_scratch_mkfs >> $seqres.full
+
+# Need datacow to show which range is defragged, and we're testing
+# autodefrag
+_scratch_mount -o datacow,autodefrag
+
+# Create a layout where we have fragmented extents at [0, 64k) (sync write in
+# reserve order), then a hole at [64k, 128k)
+$XFS_IO_PROG -f -s -c "pwrite 48k 16k" -c "pwrite 32k 16k" \
+ -c "pwrite 16k 16k" -c "pwrite 0 16k" \
+ $SCRATCH_MNT/foobar >> $seqres.full
+truncate -s 128k $SCRATCH_MNT/foobar
+
+old_csum=$(_md5_checksum $SCRATCH_MNT/foobar)
+echo "=== File extent layout before autodefrag ===" >> $seqres.full
+$XFS_IO_PROG -c "fiemap -v" "$SCRATCH_MNT/foobar" >> $seqres.full
+echo "old md5=$old_csum" >> $seqres.full
+
+old_regular=$(_get_file_extent_sector "$SCRATCH_MNT/foobar" 0)
+old_hole=$(_get_file_extent_sector "$SCRATCH_MNT/foobar" 64k)
+
+# Now trigger autodefrag, autodefrag is triggered in the cleaner thread,
+# which will be woken up by commit thread
+_scratch_remount commit=1
+sleep 3
+sync
+
+new_csum=$(_md5_checksum $SCRATCH_MNT/foobar)
+new_regular=$(_get_file_extent_sector "$SCRATCH_MNT/foobar" 0)
+new_hole=$(_get_file_extent_sector "$SCRATCH_MNT/foobar" 64k)
+
+echo "=== File extent layout after autodefrag ===" >> $seqres.full
+$XFS_IO_PROG -c "fiemap -v" "$SCRATCH_MNT/foobar" >> $seqres.full
+echo "new md5=$new_csum" >> $seqres.full
+
+# In v5.11~v5.15 kernels, regular extents won't get defragged, and would trigger
+# the following output
+if [ $new_regular == $old_regular ]; then
+ echo "regular extents didn't get defragged"
+fi
+
+# In v5.10 and earlier kernel, autodefrag may choose to defrag holes,
+# which should be avoided.
+if [ "$new_hole" != "$old_hole" ]; then
+ echo "hole extents got defragged"
+fi
+
+# Defrag should not change file content
+if [ "$new_csum" != "$old_csum" ]; then
+ echo "file content changed"
+fi
+
+echo "Silence is golden"
+# success, all done
+status=0
+exit
diff --git a/tests/btrfs/258.out b/tests/btrfs/258.out
new file mode 100644
index 0000000000..9d47016ce6
--- /dev/null
+++ b/tests/btrfs/258.out
@@ -0,0 +1,2 @@
+QA output created by 258
+Silence is golden