• Qu Wenruo's avatar
    btrfs: defrag: don't defrag extents which are already at max capacity · 979b25c3
    Qu Wenruo authored
    [BUG]
    For compressed extents, defrag ioctl will always try to defrag any
    compressed extents, wasting not only IO but also CPU time to
    compress/decompress:
    
       mkfs.btrfs -f $DEV
       mount -o compress $DEV $MNT
       xfs_io -f -c "pwrite -S 0xab 0 128K" $MNT/foobar
       sync
       xfs_io -f -c "pwrite -S 0xcd 128K 128K" $MNT/foobar
       sync
       echo "=== before ==="
       xfs_io -c "fiemap -v" $MNT/foobar
       btrfs filesystem defrag $MNT/foobar
       sync
       echo "=== after ==="
       xfs_io -c "fiemap -v" $MNT/foobar
    
    Then it shows the 2 128K extents just get COW for no extra benefit, with
    extra IO/CPU spent:
    
        === before ===
        /mnt/btrfs/file1:
         EXT: FILE-OFFSET      BLOCK-RANGE      TOTAL FLAGS
           0: [0..255]:        26624..26879       256   0x8
           1: [256..511]:      26632..26887       256   0x9
        === after ===
        /mnt/btrfs/file1:
         EXT: FILE-OFFSET      BLOCK-RANGE      TOTAL FLAGS
           0: [0..255]:        26640..26895       256   0x8
           1: [256..511]:      26648..26903       256   0x9
    
    This affects not only v5.16 (after the defrag rework), but also v5.15
    (before the defrag rework).
    
    [CAUSE]
    From the very beginning, btrfs defrag never checks if one extent is
    already at its max capacity (128K for compressed extents, 128M
    otherwise).
    
    And the default extent size threshold is 256K, which is already beyond
    the compressed extent max size.
    
    This means, by default btrfs defrag ioctl will mark all compressed
    extent which is not adjacent to a hole/preallocated range for defrag.
    
    [FIX]
    Introduce a helper to grab the maximum extent size, and then in
    defrag_collect_targets() and defrag_check_next_extent(), reject extents
    which are already at their max capacity.
    Reported-by: default avatarFilipe Manana <fdmanana@suse.com>
    CC: stable@vger.kernel.org # 5.16
    Reviewed-by: default avatarFilipe Manana <fdmanana@suse.com>
    Signed-off-by: default avatarQu Wenruo <wqu@suse.com>
    Signed-off-by: default avatarDavid Sterba <dsterba@suse.com>
    979b25c3
ioctl.c 129 KB