[prev in list] [next in list] [prev in thread] [next in thread] 

List:       fstests
Subject:    Re: [PATCH v3 1/3] btrfs: test defrag with regular and preallocated extents
From:       Filipe Manana <fdmanana () kernel ! org>
Date:       2022-01-28 11:49:07
Message-ID: YfPYM2ACKBEs5b9i () debian9 ! Home
[Download RAW message or body]

On Fri, Jan 28, 2022 at 08:26:59AM +0800, Qu Wenruo wrote:
> Recent v5.16 has some regression around btrfs autodefrag mount option,
> and the extra scrutiny around defrag code exposes some questionable
> behavior from the old code.
> 
> One behavior is to defrag extents along with the next preallocated
> extent.
> 
> This behavior will cause extra IO and convert all the preallocated
> extent to regular zero filled extents, rendering the preallocated extent
> useless.
> 
> The kernel fix is titled:
> 
>   btrfs: defrag: don't try to merge regular extents with preallocated extents
> 
> Signed-off-by: Qu Wenruo <wqu@suse.com>
> ---
> Changelog:
> v2:
> - Add _require_btrfs_support_sectorsize() helper
>   And use it to make sure the platform supports 4k sectorsize
> 
> - Use $AWK_PROG to replace awk
> 
> v3:
> - Move _get_file_extent_sector() into common/rc
> ---
>  common/btrfs        | 16 ++++++++++
>  common/rc           | 18 +++++++++++
>  tests/btrfs/255     | 75 +++++++++++++++++++++++++++++++++++++++++++++
>  tests/btrfs/255.out |  2 ++
>  4 files changed, 111 insertions(+)
>  create mode 100755 tests/btrfs/255
>  create mode 100644 tests/btrfs/255.out
> 
> diff --git a/common/btrfs b/common/btrfs
> index 4afe81eb..5de926dd 100644
> --- a/common/btrfs
> +++ b/common/btrfs
> @@ -480,3 +480,19 @@ _btrfs_no_v1_cache_opt()
>  	fi
>  	echo -n "-onospace_cache"
>  }
> +
> +# Require certain sectorsize support
> +_require_btrfs_support_sectorsize()
> +{
> +	local sectorsize=$1
> +
> +	# PAGE_SIZE as sectorsize is always supported
> +	if [ $sectorsize -eq $(get_page_size) ]; then
> +		return
> +	fi
> +
> +	test -f /sys/fs/btrfs/features/supported_sectorsizes || \
> +		_notrun "no subpage support found"
> +	grep -wq $sectorsize /sys/fs/btrfs/features/supported_sectorsizes || \
> +		_notrun "sectorsize $sectorsize is not supported"
> +}
> diff --git a/common/rc b/common/rc
> index b3289de9..8fbb32f8 100644
> --- a/common/rc
> +++ b/common/rc
> @@ -3767,6 +3767,24 @@ _count_attr_extents()
>  	$XFS_IO_PROG -c "fiemap -a" $1 | tail -n +2 | grep -v hole | wc -l
>  }
>  
> +# Get the sector number of the extent at @offset of @file
> +_get_file_extent_sector()
> +{
> +	local file=$1
> +	local offset=$2
> +	local result
> +
> +	result=$($XFS_IO_PROG -c "fiemap $offset" "$file" | \
> +		 _filter_xfs_io_fiemap | head -n1 | $AWK_PROG '{print $3}')
> +
> +	# xfs_io fiemap will output nothing if there is only hole, so here
> +	# to replace the empty string with "hole" instead
> +	if [ -z "$result" ]; then
> +		result="hole"
> +	fi
> +	echo "$result"
> +}
> +
>  # arg 1 is dev to remove and is output of the below eg.
>  # ls -l /sys/class/block/sdd | rev | cut -d "/" -f 3 | rev
>  _devmgt_remove()
> diff --git a/tests/btrfs/255 b/tests/btrfs/255
> new file mode 100755
> index 00000000..fb80359c
> --- /dev/null
> +++ b/tests/btrfs/255
> @@ -0,0 +1,75 @@
> +#! /bin/bash
> +# SPDX-License-Identifier: GPL-2.0
> +# Copyright (C) 2022 SUSE Linux Products GmbH. All Rights Reserved.
> +#
> +# FS QA Test 255
> +#
> +# Make sure btrfs doesn't defrag preallocated extents, nor lone extents
> +# before preallocated extents.
> +#
> +
> +. ./common/preamble
> +_begin_fstest auto quick defrag

Missing the 'prealloc' group.

> +
> +# Override the default cleanup function.
> +# _cleanup()
> +# {
> +# 	cd /
> +# 	rm -r -f $tmp.*
> +# }
> +
> +# Import common functions.
> +. ./common/filter
> +
> +# real QA test starts here
> +
> +# Modify as appropriate.
> +_supported_fs btrfs
> +_require_scratch
> +
> +# Needs 4K sectorsize
> +_require_btrfs_support_sectorsize 4096

We use the falloc command of xfs_io, so missing:

_require_xfs_io_command "falloc"

> +
> +_scratch_mkfs -s 4k >> $seqres.full 2>&1
> +
> +# Need datacow to make the defragged extents to have different bytenr
> +_scratch_mount -o datacow
> +
> +# Create a file with the following layout:
> +# 0       4K        8K        16K
> +# |<- R ->|<-- Preallocated ->|
> +# R is regular extents.
> +#
> +# In this case it makes no sense to defrag any extent.
> +$XFS_IO_PROG -f -c "pwrite 0 4k" -c sync -c "falloc 4k 12k" \
> +	"$SCRATCH_MNT/foobar" >> $seqres.full
> +
> +echo "=== Initial file extent layout ===" >> $seqres.full
> +$XFS_IO_PROG -c "fiemap -v" "$SCRATCH_MNT/foobar" >> $seqres.full
> +
> +# Save the bytenr of both extents
> +old_regular=$(_get_file_extent_sector "$SCRATCH_MNT/foobar" 0)
> +old_prealloc=$(_get_file_extent_sector "$SCRATCH_MNT/foobar" 4096)
> +
> +# Now defrag and write the defragged range back to disk
> +$BTRFS_UTIL_PROG filesystem defrag "$SCRATCH_MNT/foobar" >> $seqres.full
> +sync
> +
> +echo "=== File extent layout after defrag ===" >> $seqres.full
> +$XFS_IO_PROG -c "fiemap -v" "$SCRATCH_MNT/foobar" >> $seqres.full
> +
> +new_regular=$(_get_file_extent_sector "$SCRATCH_MNT/foobar" 0)
> +new_prealloc=$(_get_file_extent_sector "$SCRATCH_MNT/foobar" 4096)
> +
> +if [ "$old_regular" -ne "$new_regular" ]; then
> +	echo "the single lone sector get defragged"

get -> got

> +fi
> +if [ "$old_prealloc" -ne "$new_prealloc" ]; then
> +	echo "the preallocated extent get defragged"

get -> got

I don't want to make you send yet another patch version, and those
are minor things that Eryu can probably change when picks the patch,
so:

Reviewed-by: Filipe Manana <fdmanana@suse.com>

The test fails as expected without the btrfs fix, and passes with
it with.

Thanks.

> +fi
> +
> +echo "Silence is golden"
> +
> +# success, all done
> +status=0
> +exit
> diff --git a/tests/btrfs/255.out b/tests/btrfs/255.out
> new file mode 100644
> index 00000000..7eefb828
> --- /dev/null
> +++ b/tests/btrfs/255.out
> @@ -0,0 +1,2 @@
> +QA output created by 255
> +Silence is golden
> -- 
> 2.34.1
> 
[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic