mirror of
https://github.com/linux-apfs/apfstests.git
synced 2026-05-01 15:01:44 -07:00
cf89aed924
Fully scripted conversion, see script in initial SPDX license commit message. Signed-off-by: Dave Chinner <dchinner@redhat.com>
132 lines
3.5 KiB
Bash
Executable File
132 lines
3.5 KiB
Bash
Executable File
#! /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.
|
|
#
|
|
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
|