diff options
author | Qu Wenruo <wqu@suse.com> | 2022-01-28 08:27:00 +0800 |
---|---|---|
committer | Eryu Guan <guaneryu@gmail.com> | 2022-02-14 01:17:46 +0800 |
commit | 8925b0290ffe0744d28f99a0a38e92e46cb85d75 (patch) | |
tree | 878f142875ce86528bfef114d6b75d19877d617d | |
parent | d8639e1632ab3fe1d8044702699350ddf2499b12 (diff) | |
download | xfstests-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-x | tests/btrfs/258 | 80 | ||||
-rw-r--r-- | tests/btrfs/258.out | 2 |
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 |