btrfs trims fiemap extents to the inputted offset, which leads to inconsistent results for most inputs, and downright bizarre outputs like [7..6] when the trimmed extent is at the end of an extent and shorter than 512 bytes. This test covers a bunch of cases like that and ensures that file systems always return the full extent without trimming it. I also ran it under ext2, ext3, ext4, f2fs, and xfs successfully, but I suppose it's no guarantee that every file system will store a 4k synced write in a single extent. For that reason, this might be a bit fragile. This test is fixed for btrfs by: btrfs: return whole extents in fiemap (https://lore.kernel.org/linux-btrfs/274e5bcebdb05a8969fc300b4802f33da2fbf218.1617746680.git.boris@xxxxxx/) Signed-off-by: Boris Burkov <boris@xxxxxx> -- v2: fill out copyright and test description --- tests/generic/623 | 94 +++++++++++++++++++++++++++++++++++++++++++ tests/generic/623.out | 2 + tests/generic/group | 1 + 3 files changed, 97 insertions(+) create mode 100755 tests/generic/623 create mode 100644 tests/generic/623.out diff --git a/tests/generic/623 b/tests/generic/623 new file mode 100755 index 00000000..85ef68f6 --- /dev/null +++ b/tests/generic/623 @@ -0,0 +1,94 @@ +#! /bin/bash +# SPDX-License-Identifier: GPL-2.0 +# Copyright (c) 2021 Facebook. All Rights Reserved. +# +# FS QA Test 623 +# +# Test fiemaps with offsets into small parts of extents. +# Expect to get the whole extent, anyway. +# +seq=`basename $0` +seqres=$RESULT_DIR/$seq +echo "QA output created by $seq" + +here=`pwd` +tmp=/tmp/$$ +status=1 # failure is the default! +trap "_cleanup; exit \$status" 0 1 2 3 15 + +_cleanup() +{ + cd / + rm -f $tmp.* +} + +# get standard environment, filters and checks +. ./common/rc +. ./common/filter + +# remove previous $seqres.full before test +rm -f $seqres.full + +# real QA test starts here + +# Modify as appropriate. +_supported_fs generic +_require_test +_require_scratch +_require_xfs_io_command "fiemap" + +rm -f $seqres.full + +_do_fiemap() { + off=$1 + len=$2 + $XFS_IO_PROG -c "fiemap $off $len" $SCRATCH_MNT/foo +} + +_check_fiemap() { + off=$1 + len=$2 + actual=$(_do_fiemap $off $len | tee -a $seqres.full) + [ "$actual" == "$expected" ] || _fail "unexpected fiemap on $off $len" +} + +_scratch_mkfs >>$seqres.full 2>&1 +_scratch_mount + +# write a file with one extent +$XFS_IO_PROG -f -s -c "pwrite -S 0xcf 0 4K" $SCRATCH_MNT/foo >/dev/null + +# since the exact extent location is unpredictable especially when +# varying file systems, just test that they are all equal, which is +# what we really expect. +expected=$(_do_fiemap) + +# start to mid-extent +_check_fiemap 0 2048 +# start to end +_check_fiemap 0 4096 +# start to past-end +_check_fiemap 0 4097 +# mid-extent to mid-extent +_check_fiemap 1024 2048 +# mid-extent to end +_check_fiemap 2048 4096 +# mid-extent to past-end +_check_fiemap 2048 4097 + +# to end; len < 512 +_check_fiemap 4091 5 +# to end; len == 512 +_check_fiemap 3584 512 +# past end; len < 512 +_check_fiemap 4091 500 +# past end; len == 512 +_check_fiemap 4091 512 + +_scratch_unmount + +echo "Silence is golden" + +# success, all done +status=0 +exit diff --git a/tests/generic/623.out b/tests/generic/623.out new file mode 100644 index 00000000..6f774f19 --- /dev/null +++ b/tests/generic/623.out @@ -0,0 +1,2 @@ +QA output created by 623 +Silence is golden diff --git a/tests/generic/group b/tests/generic/group index b10fdea4..39e02383 100644 --- a/tests/generic/group +++ b/tests/generic/group @@ -625,3 +625,4 @@ 620 auto mount quick 621 auto quick encrypt 622 auto shutdown metadata atime +623 auto quick -- 2.30.2