Re: [PATCH v2 2/3] btrfs: test autodefrag with regular and hole extents

[Date Prev] [Date Next] [Thread Prev] [Thread Next] [Date Index] [Thread Index]



On Fri, Jan 28, 2022 at 12:13 PM Qu Wenruo <quwenruo.btrfs@xxxxxxx> wrote:
>
>
>
> On 2022/1/28 19:57, Filipe Manana wrote:
> > On Fri, Jan 28, 2022 at 08:27:00AM +0800, Qu Wenruo wrote:
> >> 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@xxxxxxxx>
> >
> > Tried the test, and it succeeds here without the kernel fix applied.
> > I've ran it 10 times, and it always passed without the kernel fix.
>
> Have you tried v5.15 kernels? As v5.16 has the reworked code and will
> always pass.
>
> Or you can try to revert those 3 commits:
>
> c22a3572cbaf ("btrfs: defrag: enable defrag for subpage case")
> c635757365c3 ("btrfs: defrag: remove the old infrastructure")
> 7b508037d4ca ("btrfs: defrag: use defrag_one_cluster() to implement
> btrfs_defrag_file()")

With all those reverted, plus all the recent fixes that went to Linus'
tree, it fails as expected.
I got lost somewhere while navigating the sea of so many recent defrag
patches and versions.

So:

Reviewed-by: Filipe Manana <fdmanana@xxxxxxxx>

Thanks.

>
> That's how I tested the case with the same kernel base without going
> back to v5.15.
>
> And with those 3 commits reverted (aka, my baseline to emulate v5.15),
> it fails like this:
>
> btrfs/256 4s ... - output mismatch (see
> /home/adam/xfstests-dev/results//btrfs/256.out.bad)
>      --- tests/btrfs/256.out    2022-01-28 08:19:11.123333302 +0800
>      +++ /home/adam/xfstests-dev/results//btrfs/256.out.bad     2022-01-28
> 20:10:18.416666746 +0800
>      @@ -1,2 +1,3 @@
>       QA output created by 256
>      +regular extents didn't get defragged
>       Silence is golden
>      ...
>      (Run 'diff -u /home/adam/xfstests-dev/tests/btrfs/256.out
> /home/adam/xfstests-dev/results//btrfs/256.out.bad'  to see the entire diff)
> Ran: btrfs/256
>
> With the fiemap result in the full log:
> === File extent layout before autodefrag ===
> /mnt/scratch/foobar:
>   EXT: FILE-OFFSET      BLOCK-RANGE      TOTAL FLAGS
>     0: [0..31]:         26720..26751        32   0x0
>     1: [32..63]:        26688..26719        32   0x0
>     2: [64..95]:        26656..26687        32   0x0
>     3: [96..127]:       26624..26655        32   0x1
>     4: [128..255]:      hole               128
> old md5=9ef8ace32f3b9890cff4fd43699bbd81
> === File extent layout after autodefrag ===
> /mnt/scratch/foobar:
>   EXT: FILE-OFFSET      BLOCK-RANGE      TOTAL FLAGS
>     0: [0..31]:         26720..26751        32   0x0
>     1: [32..63]:        26688..26719        32   0x0
>     2: [64..95]:        26656..26687        32   0x0
>     3: [96..127]:       26624..26655        32   0x1
>     4: [128..255]:      hole               128
> new md5=9ef8ace32f3b9890cff4fd43699bbd81
>
> With my POC patch for v5.15 or v5.16 kernel it passes as expected.
>
> Thus that's why there is no fix mentioned in the commit message.
>
> Thanks,
> Qu
>
>
>
> >
> > Thanks.
> >
> >> ---
> >> Changelog:
> >> v2:
> >> - Use the previously define _get_file_extent_sector() helper
> >>    This also removed some out-of-sync error messages
> >>
> >> - Trigger autodefrag using commit=1 mount option
> >>    No need for special purpose patch any more.
> >>
> >> - Use xfs_io -s to skip several sync calls
> >>
> >> - Shorten the subject of the commit
> >> ---
> >>   tests/btrfs/256     | 80 +++++++++++++++++++++++++++++++++++++++++++++
> >>   tests/btrfs/256.out |  2 ++
> >>   2 files changed, 82 insertions(+)
> >>   create mode 100755 tests/btrfs/256
> >>   create mode 100644 tests/btrfs/256.out
> >>
> >> diff --git a/tests/btrfs/256 b/tests/btrfs/256
> >> new file mode 100755
> >> index 00000000..def83a15
> >> --- /dev/null
> >> +++ b/tests/btrfs/256
> >> @@ -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 256
> >> +#
> >> +# 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/256.out b/tests/btrfs/256.out
> >> new file mode 100644
> >> index 00000000..7ee8e2e5
> >> --- /dev/null
> >> +++ b/tests/btrfs/256.out
> >> @@ -0,0 +1,2 @@
> >> +QA output created by 256
> >> +Silence is golden
> >> --
> >> 2.34.1
> >>



[Index of Archives]     [Linux Filesystems Development]     [Linux NFS]     [Linux NILFS]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux