Files
apfstests/tests/generic/404
T
Roman Pen 2504b26a3a generic: reproduce ext4 bugs in a shift extents logic
Regression test which targets two nasty ext4 bugs in a logic which
shifts extents:

1) 14d981f468a1 ("ext4: Include forgotten start block on fallocate insert range")

Test tries to insert many blocks at the same offset to reproduce
the following layout on ext4:

   block #0  block #1
   |ext0 ext1|ext2 ext3 ...|
        ^
     insert of a new block

Because of an incorrect range first block is never reached,
thus ext1 is untouched, resulting to a hole at a wrong offset:

What we got:

   block #0   block #1
   |ext0 ext1|   ext2 ext3 ...|
              ^
              hole at a wrong offset

What we expect:

   block #0    block #1
   |ext0   ext1|ext2 ext3 ...|
        ^
        hole at a correct offset

2) 2b3864b32403 ("ext4: do not polute the extents cache while shifting extents")

Extents status tree is filled in with outdated offsets while doing
extent shift, that leads to wrong data blocks.   That's why md5sum
of a result file is being checked after each block insert.

Signed-off-by: Roman Pen <roman.penyaev@profitbricks.com>
Cc: "Theodore Ts'o <tytso@mit.edu>"
Cc: Eryu Guan <eguan@redhat.com>
Cc: linux-ext4@vger.kernel.org
Cc: fstests@vger.kernel.org
Reviewed-by: Eryu Guan <eguan@redhat.com>
Signed-off-by: Eryu Guan <eguan@redhat.com>
2017-01-15 13:56:45 +08:00

147 lines
4.2 KiB
Bash
Executable File

#! /bin/bash
# FS QA Test 404
#
# Regression test which targets two nasty ext4 bugs in a logic which
# shifts extents:
#
# 1) 14d981f468a1 ("ext4: Include forgotten start block on fallocate insert range")
#
# An incorrect right shift (insert range) for the first extent in
# a range.
#
# Test tries to insert many blocks at the same offset to reproduce
# the following layout:
#
# block #0 block #1
# |ext0 ext1|ext2 ext3 ...|
# ^
# insert of a new block
#
# Because of an incorrect range first block is never reached,
# thus ext1 is untouched, resulting to a hole at a wrong offset:
#
# What we got:
#
# block #0 block #1
# |ext0 ext1| ext2 ext3 ...|
# ^
# hole at a wrong offset
#
# What we expect:
#
# block #0 block #1
# |ext0 ext1|ext2 ext3 ...|
# ^
# hole at a correct offset
#
# 2) 2b3864b32403 ("ext4: do not polute the extents cache while shifting extents")
#
# Extents status tree is filled in with outdated offsets while doing
# extents shift, that leads to wrong data blocks. That is why test
# writes unique block content and checks md5sum of a result file after
# each block insert.
#
#-----------------------------------------------------------------------
# Copyright (c) 2017 Roman Penyaev. All Rights Reserved.
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License as
# published by the Free Software Foundation.
#
# This program is distributed in the hope that it would be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write the Free Software Foundation,
# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#-----------------------------------------------------------------------
#
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
testfile=$TEST_DIR/$seq.file
pattern=$tmp.pattern
_cleanup()
{
cd /
rm -f $tmp.*
rm -f $testfile
}
# 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
_supported_os Linux
_require_test
_require_xfs_io_command "finsert"
blksize=`_get_block_size $TEST_DIR`
# Generate a block with a repeating number represented as 4 bytes decimal.
# The test generates unique pattern for each block in order to observe a
# wrong order if any.
function generate_pattern() {
blkind=$1
printf "%04d" $blkind | awk '{ while (c++ < '$(($blksize/4))') \
printf "%s", $0 }' > $pattern
}
$XFS_IO_PROG -f -c "falloc 0 $(($blksize * 2))" $testfile \
>> $seqres.full 2>&1
# First block, has 0001 as a pattern
generate_pattern 1
$XFS_IO_PROG -c "pwrite -i $pattern 0 $blksize" $testfile \
>> $seqres.full 2>&1
# Second block, has 0002 as a pattern
generate_pattern 2
$XFS_IO_PROG -c "pwrite -i $pattern $blksize $blksize" $testfile \
>> $seqres.full 2>&1
# Insert 498 blocks after the first block. We use this quite big
# number to increase the reproduction probability.
for (( block=3; block<=500; block++ )); do
$XFS_IO_PROG -c "finsert $blksize $blksize" $testfile \
>> $seqres.full 2>&1
generate_pattern $block
$XFS_IO_PROG -c "pwrite -i $pattern $blksize $blksize" $testfile \
>> $seqres.full 2>&1
# Avoid offsets in hexdump output, because block size can vary.
# Here we check md5 after each insert to be sure that zero blocks
# do not appear, targets this commit:
# 14d981f468a1 ("ext4: Include forgotten start block on fallocate insert range")
# or blocks are in correct order, this commit:
# 2b3864b32403 ("ext4: do not polute the extents cache while shifting extents")
#
md5=`hexdump -e '16/1 "%_p" "\n"' $testfile | md5sum`
printf "#%d %s\n" "$block" "$md5"
done
# Eventually output file has 500 blocks in the following order:
# 0001 0500 0499 0498 ... 0002
# success, all done
status=0
exit