blob: 939692eb38b7459945f9a3ff3d87191879f47215 [file] [log] [blame]
#! /bin/bash
# SPDX-License-Identifier: GPL-2.0
# Copyright (c) 2017 Roman Penyaev. All Rights Reserved.
#
# 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.
#
. ./common/preamble
_begin_fstest auto quick insert
testfile=$TEST_DIR/$seq.file
pattern=$tmp.pattern
# Override the default cleanup function.
_cleanup()
{
cd /
rm -f $tmp.*
rm -f $testfile
}
# Import common functions.
. ./common/filter
# real QA test starts here
# Modify as appropriate.
_supported_fs generic
_require_test
_require_xfs_io_command "falloc"
_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=`od -An -c $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