summaryrefslogtreecommitdiff
path: root/tests/btrfs/297
blob: 7afe854dce7ab87f5f05243558bdb1e564ab36c3 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
#! /bin/bash
# SPDX-License-Identifier: GPL-2.0
# Copyright (C) 2023 SUSE Linux Products GmbH. All Rights Reserved.
#
# FS QA Test 297
#
# Make sure btrfs scrub can fix parity stripe corruption
#
. ./common/preamble
_begin_fstest auto quick raid scrub

. ./common/filter

_supported_fs btrfs
_require_odirect
_require_non_zoned_device "${SCRATCH_DEV}"
_require_scratch_dev_pool 3
_fixed_by_kernel_commit 486c737f7fdc \
	"btrfs: raid56: always verify the P/Q contents for scrub"

# If neither raid5 or raid6 are supported do _notrun
if ! _check_btrfs_raid_type raid5 && ! _check_btrfs_raid_type raid6; then
	_notrun "requires either raid5 or raid6 support"
fi

workload()
{
	local profile=$1
	local nr_devs=$2

	if ! _check_btrfs_raid_type $profile; then
		echo "$profile isn't supported, skipping" >> $seqres.full
		return
	fi

	echo "=== Testing $nr_devs devices $profile ===" >> $seqres.full
	_scratch_dev_pool_get $nr_devs

	_scratch_pool_mkfs -d $profile -m single >> $seqres.full 2>&1
	# Use v2 space cache to prevent v1 space cache affecting
	# the result.
	_scratch_mount -o space_cache=v2

	# Create one 64K extent which would cover one data stripe.
	$XFS_IO_PROG -f -d -c "pwrite -S 0xaa -b 64K 0 64K" \
		"$SCRATCH_MNT/foobar" > /dev/null
	sync

	# Corrupt the P/Q stripe
	local logical=$(_btrfs_get_first_logical $SCRATCH_MNT/foobar)

	# The 2nd copy is pointed to P stripe directly.
	physical_p=$(_btrfs_get_physical ${logical} 2)
	devpath_p=$(_btrfs_get_device_path ${logical} 2)

	_scratch_unmount

	echo "Corrupt stripe P at devpath $devpath_p physical $physical_p" \
		>> $seqres.full
	$XFS_IO_PROG -d -c "pwrite -S 0xff -b 64K $physical_p 64K" $devpath_p \
		> /dev/null

	# Do a scrub to try repair the P stripe.
	_scratch_mount -o space_cache=v2
	$BTRFS_UTIL_PROG scrub start -BdR $SCRATCH_MNT >> $seqres.full 2>&1
	_scratch_unmount

	# Verify the repaired content directly
	local output=$($XFS_IO_PROG -c "pread -qv $physical_p 16" $devpath_p | _filter_xfs_io_offset)
	local expect="XXXXXXXX:  aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa  ................"

	echo "The first 16 bytes of parity stripe after scrub:" >> $seqres.full
	echo $output >> $seqres.full
	if [ "$output" != "$expect" ]; then
		echo "Unexpected parity content"
		echo "has:"
		echo "$output"
		echo "expect"
		echo "$expect"
	fi

	# Last safenet, let btrfs check --check-data-csum to do an offline scrub.
	$BTRFS_UTIL_PROG check --check-data-csum $SCRATCH_DEV >> $seqres.full 2>&1
	if [ $? -ne 0 ]; then
		echo "Error detected after the scrub"
	fi
	_scratch_dev_pool_put
}

workload raid5 2
workload raid6 3

echo "Silence is golden"
status=0
exit