@@ -37,18 +37,19 @@ fsv_file=$SCRATCH_MNT/file.fsv
setup_zeroed_file()
{
- local len=$1
- local sparse=$2
+ local block_size=$1
+ local file_len=$2
+ local sparse=$3
if $sparse; then
- dd if=/dev/zero of=$fsv_orig_file bs=1 count=0 seek=$len \
+ dd if=/dev/zero of=$fsv_orig_file bs=1 count=0 seek=$file_len \
status=none
else
- head -c $len /dev/zero > $fsv_orig_file
+ head -c $file_len /dev/zero > $fsv_orig_file
fi
cp $fsv_orig_file $fsv_file
- _fsv_enable $fsv_file
- md5sum $fsv_file |& _filter_scratch
+ _fsv_enable $fsv_file --block-size=$block_size
+ cmp $fsv_orig_file $fsv_file
}
filter_sigbus()
@@ -66,63 +67,84 @@ round_up_to_page_boundary()
corruption_test()
{
- local file_len=$1
- local zap_offset=$2
- local zap_len=$3
- local is_merkle_tree=${4:-false} # if true, zap tree instead of data
- local use_sparse_file=${5:-false}
+ local block_size=$1
+ local file_len=$2
+ local zap_offset=$3
+ local zap_len=$4
+ local is_merkle_tree=${5:-false} # if true, zap tree instead of data
+ local use_sparse_file=${6:-false}
local page_aligned_eof=$(round_up_to_page_boundary $file_len)
- local measurement
+
+ local paramstr="block_size=$block_size"
+ paramstr+=", file_len=$file_len"
+ paramstr+=", zap_offset=$zap_offset"
+ paramstr+=", zap_len=$zap_len"
+ paramstr+=", is_merkle_tree=$is_merkle_tree"
+ paramstr+=", use_sparse_file=$use_sparse_file"
if $is_merkle_tree; then
local corrupt_func=_fsv_scratch_corrupt_merkle_tree
else
local corrupt_func=_fsv_scratch_corrupt_bytes
fi
+ local fs_block_size=$(_get_block_size $SCRATCH_MNT)
- local msg="Corruption test:"
- msg+=" file_len=$file_len"
- if $use_sparse_file; then
- msg+=" (sparse)"
- fi
- msg+=" zap_offset=$zap_offset"
- if $is_merkle_tree; then
- msg+=" (in Merkle tree)"
- fi
- msg+=" zap_len=$zap_len"
+ rm -rf "${SCRATCH_MNT:?}"/*
+ setup_zeroed_file $block_size $file_len $use_sparse_file
- _fsv_scratch_begin_subtest "$msg"
- setup_zeroed_file $file_len $use_sparse_file
- cmp $fsv_file $fsv_orig_file
- echo "Corrupting bytes..."
+ # Corrupt part of the file (data or Merkle tree).
head -c $zap_len /dev/zero | tr '\0' X \
| $corrupt_func $fsv_file $zap_offset
- echo "Validating corruption (reading full file)..."
+ # Reading the full file with buffered I/O should fail.
_scratch_cycle_mount
- md5sum $fsv_file |& _filter_scratch
+ if cat $fsv_file >/dev/null 2>$tmp.out; then
+ echo "Unexpectedly was able to read full file ($paramstr)"
+ elif ! grep -q 'Input/output error' $tmp.out; then
+ echo "Wrong error reading full file ($paramstr):"
+ cat $tmp.out
+ fi
- echo "Validating corruption (direct I/O)..."
+ # Reading the full file with direct I/O should fail.
_scratch_cycle_mount
- dd if=$fsv_file bs=$FSV_BLOCK_SIZE iflag=direct status=none \
- of=/dev/null |& _filter_scratch
+ if dd if=$fsv_file bs=$fs_block_size iflag=direct status=none \
+ of=/dev/null 2>$tmp.out
+ then
+ echo "Unexpectedly was able to read full file with DIO ($paramstr)"
+ elif ! grep -q 'Input/output error' $tmp.out; then
+ echo "Wrong error reading full file with DIO ($paramstr):"
+ cat $tmp.out
+ fi
- if (( zap_offset < file_len )) && ! $is_merkle_tree; then
- echo "Validating corruption (reading just corrupted part)..."
- dd if=$fsv_file bs=1 skip=$zap_offset count=$zap_len \
- of=/dev/null status=none |& _filter_scratch
+ # Reading just the corrupted part of the file should fail.
+ if ! $is_merkle_tree; then
+ if dd if=$fsv_file bs=1 skip=$zap_offset count=$zap_len \
+ of=/dev/null status=none 2>$tmp.out; then
+ echo "Unexpectedly was able to read corrupted part ($paramstr)"
+ elif ! grep -q 'Input/output error' $tmp.out; then
+ echo "Wrong error reading corrupted part ($paramstr):"
+ cat $tmp.out
+ fi
fi
- echo "Validating corruption (reading full file via mmap)..."
+ # Reading the file via mmap should fail.
bash -c "trap '' SIGBUS; $XFS_IO_PROG -r $fsv_file \
-c 'mmap -r 0 $page_aligned_eof' \
- -c 'mread 0 $file_len'" |& filter_sigbus
+ -c 'mread 0 $file_len'" >/dev/null 2>$tmp.out
+ if ! grep -q 'Bus error' $tmp.out; then
+ echo "Didn't see SIGBUS when reading file via mmap"
+ cat $tmp.out
+ fi
+ # Reading just the corrupted part via mmap should fail.
if ! $is_merkle_tree; then
- echo "Validating corruption (reading just corrupted part via mmap)..."
bash -c "trap '' SIGBUS; $XFS_IO_PROG -r $fsv_file \
-c 'mmap -r 0 $page_aligned_eof' \
- -c 'mread $zap_offset $zap_len'" |& filter_sigbus
+ -c 'mread $zap_offset $zap_len'" >/dev/null 2>$tmp.out
+ if ! grep -q 'Bus error' $tmp.out; then
+ echo "Didn't see SIGBUS when reading corrupted part via mmap"
+ cat $tmp.out
+ fi
fi
}
@@ -132,17 +154,16 @@ corruption_test()
# disk. In the former, corruption should be detected and result in SIGBUS,
# while in the latter we would expect zeros past EOF, but no error.
corrupt_eof_block_test() {
- local file_len=$1
- local zap_len=$2
+ local block_size=$1
+ local file_len=$2
+ local zap_len=$3
local page_aligned_eof=$(round_up_to_page_boundary $file_len)
- _fsv_scratch_begin_subtest "Corruption test: EOF block"
- setup_zeroed_file $file_len false
- cmp $fsv_file $fsv_orig_file
- echo "Corrupting bytes..."
+
+ rm -rf "${SCRATCH_MNT:?}"/*
+ setup_zeroed_file $block_size $file_len false
head -c $zap_len /dev/zero | tr '\0' X \
| _fsv_scratch_corrupt_bytes $fsv_file $file_len
- echo "Reading eof block via mmap into a temporary file..."
bash -c "trap '' SIGBUS; $XFS_IO_PROG -r $fsv_file \
-c 'mmap -r 0 $page_aligned_eof' \
-c 'mread -v $file_len $zap_len'" \
@@ -153,30 +174,49 @@ corrupt_eof_block_test() {
-c "mmap -r 0 $page_aligned_eof" \
-c "mread -v $file_len $zap_len" >$tmp.eof_zero_read
- echo "Checking for SIGBUS or zeros..."
- grep -q -e '^Bus error$' $tmp.eof_block_read \
- || diff $tmp.eof_block_read $tmp.eof_zero_read \
- && echo "OK"
+ grep -q -e '^Bus error$' $tmp.eof_block_read || \
+ diff $tmp.eof_block_read $tmp.eof_zero_read
}
-# Note: these tests just overwrite some bytes without checking their original
-# values. Therefore, make sure to overwrite at least 5 or so bytes, to make it
-# nearly guaranteed that there will be a change -- even when the test file is
-# encrypted due to the test_dummy_encryption mount option being specified.
-
-corruption_test 131072 0 5
-corruption_test 131072 4091 5
-corruption_test 131072 65536 65536
-corruption_test 131072 131067 5
-
-corrupt_eof_block_test 130999 72
-
-# Merkle tree corruption.
-corruption_test 200000 100 10 true
+test_block_size()
+{
+ local block_size=$1
+
+ # Note: these tests just overwrite some bytes without checking their
+ # original values. Therefore, make sure to overwrite at least 5 or so
+ # bytes, to make it nearly guaranteed that there will be a change --
+ # even when the test file is encrypted due to the test_dummy_encryption
+ # mount option being specified.
+ corruption_test $block_size 131072 0 5
+ corruption_test $block_size 131072 4091 5
+ corruption_test $block_size 131072 65536 65536
+ corruption_test $block_size 131072 131067 5
+
+ corrupt_eof_block_test $block_size 130999 72
+
+ # Merkle tree corruption.
+ corruption_test $block_size 200000 100 10 true
+
+ # Sparse file. Corrupting the Merkle tree should still cause reads to
+ # fail, i.e. the filesystem must verify holes.
+ corruption_test $block_size 200000 100 10 true true
+}
-# Sparse file. Corrupting the Merkle tree should still cause reads to fail,
-# i.e. the filesystem must verify holes.
-corruption_test 200000 100 10 true true
+# Always test FSV_BLOCK_SIZE. Also test some other block sizes if they happen
+# to be supported.
+_fsv_scratch_begin_subtest "Corruption test with block_size=FSV_BLOCK_SIZE"
+test_block_size $FSV_BLOCK_SIZE
+for block_size in 1024 4096 16384 65536; do
+ _fsv_scratch_begin_subtest "Corruption test with block_size=$block_size"
+ if (( block_size == FSV_BLOCK_SIZE )); then
+ continue
+ fi
+ if ! _fsv_can_enable $fsv_file --block-size=$block_size; then
+ echo "block_size=$block_size is unsupported" >> $seqres.full
+ continue
+ fi
+ test_block_size $block_size
+done
# success, all done
status=0
@@ -1,84 +1,11 @@
QA output created by 574
-# Corruption test: file_len=131072 zap_offset=0 zap_len=5
-0dfbe8aa4c20b52e1b8bf3cb6cbdf193 SCRATCH_MNT/file.fsv
-Corrupting bytes...
-Validating corruption (reading full file)...
-md5sum: SCRATCH_MNT/file.fsv: Input/output error
-Validating corruption (direct I/O)...
-dd: error reading 'SCRATCH_MNT/file.fsv': Input/output error
-Validating corruption (reading just corrupted part)...
-dd: error reading 'SCRATCH_MNT/file.fsv': Input/output error
-Validating corruption (reading full file via mmap)...
-Bus error
-Validating corruption (reading just corrupted part via mmap)...
-Bus error
+# Corruption test with block_size=FSV_BLOCK_SIZE
-# Corruption test: file_len=131072 zap_offset=4091 zap_len=5
-0dfbe8aa4c20b52e1b8bf3cb6cbdf193 SCRATCH_MNT/file.fsv
-Corrupting bytes...
-Validating corruption (reading full file)...
-md5sum: SCRATCH_MNT/file.fsv: Input/output error
-Validating corruption (direct I/O)...
-dd: error reading 'SCRATCH_MNT/file.fsv': Input/output error
-Validating corruption (reading just corrupted part)...
-dd: error reading 'SCRATCH_MNT/file.fsv': Input/output error
-Validating corruption (reading full file via mmap)...
-Bus error
-Validating corruption (reading just corrupted part via mmap)...
-Bus error
+# Corruption test with block_size=1024
-# Corruption test: file_len=131072 zap_offset=65536 zap_len=65536
-0dfbe8aa4c20b52e1b8bf3cb6cbdf193 SCRATCH_MNT/file.fsv
-Corrupting bytes...
-Validating corruption (reading full file)...
-md5sum: SCRATCH_MNT/file.fsv: Input/output error
-Validating corruption (direct I/O)...
-dd: error reading 'SCRATCH_MNT/file.fsv': Input/output error
-Validating corruption (reading just corrupted part)...
-dd: error reading 'SCRATCH_MNT/file.fsv': Input/output error
-Validating corruption (reading full file via mmap)...
-Bus error
-Validating corruption (reading just corrupted part via mmap)...
-Bus error
+# Corruption test with block_size=4096
-# Corruption test: file_len=131072 zap_offset=131067 zap_len=5
-0dfbe8aa4c20b52e1b8bf3cb6cbdf193 SCRATCH_MNT/file.fsv
-Corrupting bytes...
-Validating corruption (reading full file)...
-md5sum: SCRATCH_MNT/file.fsv: Input/output error
-Validating corruption (direct I/O)...
-dd: error reading 'SCRATCH_MNT/file.fsv': Input/output error
-Validating corruption (reading just corrupted part)...
-dd: error reading 'SCRATCH_MNT/file.fsv': Input/output error
-Validating corruption (reading full file via mmap)...
-Bus error
-Validating corruption (reading just corrupted part via mmap)...
-Bus error
+# Corruption test with block_size=16384
-# Corruption test: EOF block
-f5cca0d7fbb8b02bc6118a9954d5d306 SCRATCH_MNT/file.fsv
-Corrupting bytes...
-Reading eof block via mmap into a temporary file...
-Checking for SIGBUS or zeros...
-OK
-
-# Corruption test: file_len=200000 zap_offset=100 (in Merkle tree) zap_len=10
-4a1e4325031b13f933ac4f1db9ecb63f SCRATCH_MNT/file.fsv
-Corrupting bytes...
-Validating corruption (reading full file)...
-md5sum: SCRATCH_MNT/file.fsv: Input/output error
-Validating corruption (direct I/O)...
-dd: error reading 'SCRATCH_MNT/file.fsv': Input/output error
-Validating corruption (reading full file via mmap)...
-Bus error
-
-# Corruption test: file_len=200000 (sparse) zap_offset=100 (in Merkle tree) zap_len=10
-4a1e4325031b13f933ac4f1db9ecb63f SCRATCH_MNT/file.fsv
-Corrupting bytes...
-Validating corruption (reading full file)...
-md5sum: SCRATCH_MNT/file.fsv: Input/output error
-Validating corruption (direct I/O)...
-dd: error reading 'SCRATCH_MNT/file.fsv': Input/output error
-Validating corruption (reading full file via mmap)...
-Bus error
+# Corruption test with block_size=65536