summaryrefslogtreecommitdiff
path: root/tests/xfs/516
blob: 1bf6f858d5286d775f605f36757d1bd285f8bfa1 (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
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
#! /bin/bash
# SPDX-License-Identifier: GPL-2.0-or-later
# Copyright (c) 2020, Oracle and/or its affiliates.  All Rights Reserved.
#
# FS QA Test No. 516
#
# Update sunit and width and make sure that the filesystem still passes
# xfs_repair afterwards.

. ./common/preamble
_begin_fstest auto quick

# Override the default cleanup function.
_cleanup()
{
	rm -f $tmp.*
	cd /
}

# Import common functions.
. ./common/fuzzy

# real QA test starts here
_supported_fs xfs
_require_scratch_nocheck

# Assume that if we can run scrub on the test dev we can run it on the scratch
# fs too.
run_scrub=0
_supports_xfs_scrub $TEST_DIR $TEST_DEV && run_scrub=1

log()
{
	echo "$*" | _tee_kernlog $seqres.full
}

__test_mount_opts()
{
	local mounted=0

	# Try to mount the fs with our test options.
	_try_scratch_mount "$@" >> $seqres.full 2>&1 && mounted=1
	if [ $mounted -gt 0 ]; then
		# Implant a sentinel file to see if repair nukes the directory
		# later.  Scrub, unmount, and check for errors.
		echo moo > $SCRATCH_MNT/a
		grep "$SCRATCH_MNT" /proc/mounts >> $seqres.full
		test $run_scrub -gt 0 && \
			_scratch_scrub -n >> $seqres.full
		_scratch_unmount
		_scratch_xfs_repair -n >> $seqres.full 2>&1 || \
			echo "Repair found problems."
	else
		echo "mount failed" >> $seqres.full
	fi
	_scratch_xfs_get_sb_field unit >> $seqres.full
	_scratch_xfs_get_sb_field width  >> $seqres.full

	# Run xfs_repair in repair mode to see if it can be baited into nuking
	# the root filesystem on account of the sunit update.
	_scratch_xfs_repair >> $seqres.full 2>&1

	# If the previous mount succeeded, mount the fs and look for the file
	# we implanted.
	if [ $mounted -gt 0 ]; then
		_scratch_mount
		test -f $SCRATCH_MNT/a || echo "Root directory got nuked."
		_scratch_unmount
	fi

	echo >> $seqres.full
}

test_sunit_opts()
{
	echo "Format with 4k stripe unit; 1x stripe width" >> $seqres.full
	_scratch_mkfs -b size=4k -d sunit=8,swidth=8 >> $seqres.full 2>&1

	__test_mount_opts "$@"
}

test_su_opts()
{
	local mounted=0

	echo "Format with 256k stripe unit; 4x stripe width" >> $seqres.full
	_scratch_mkfs -b size=1k -d su=256k,sw=4 >> $seqres.full 2>&1

	__test_mount_opts "$@"
}

test_repair_detection()
{
	local mounted=0

	echo "Format with 256k stripe unit; 4x stripe width" >> $seqres.full
	_scratch_mkfs -b size=1k -d su=256k,sw=4 >> $seqres.full 2>&1

	# Try to mount the fs with our test options.
	_try_scratch_mount >> $seqres.full 2>&1 && mounted=1
	if [ $mounted -gt 0 ]; then
		# Implant a sentinel file to see if repair nukes the directory
		# later.  Scrub, unmount, and check for errors.
		echo moo > $SCRATCH_MNT/a
		grep "$SCRATCH_MNT" /proc/mounts >> $seqres.full
		test $run_scrub -gt 0 && \
			_scratch_scrub -n >> $seqres.full
		_scratch_unmount
		_scratch_xfs_repair -n >> $seqres.full 2>&1 || \
			echo "Repair found problems."
	else
		echo "mount failed" >> $seqres.full
	fi

	# Update the superblock like the kernel used to do.
	_scratch_xfs_get_sb_field unit >> $seqres.full
	_scratch_xfs_get_sb_field width >> $seqres.full
	_scratch_xfs_set_sb_field unit 256 >> $seqres.full
	_scratch_xfs_set_sb_field width 1024 >> $seqres.full
	_scratch_xfs_get_sb_field unit >> $seqres.full
	_scratch_xfs_get_sb_field width >> $seqres.full

	# Run xfs_repair in repair mode to see if it can be baited into nuking
	# the root filesystem on account of the sunit update.
	_scratch_xfs_repair >> $seqres.full 2>&1

	# If the previous mount succeeded, mount the fs and look for the file
	# we implanted.
	if [ $mounted -gt 0 ]; then
		_scratch_mount
		test -f $SCRATCH_MNT/a || echo "Root directory got nuked."
		_scratch_unmount
	fi

	echo >> $seqres.full
}

# Format with a 256k stripe unit and 4x stripe width, and try various mount
# options that want to change that and see if they blow up.  Normally you
# would never change the stripe *unit*, so it's no wonder this is not well
# tested.

log "Test: no raid parameters"
test_su_opts

log "Test: 256k stripe unit; 4x stripe width"
test_su_opts -o sunit=512,swidth=2048

log "Test: 256k stripe unit; 5x stripe width"
test_su_opts -o sunit=512,swidth=2560

# Note: Larger stripe units probably won't mount
log "Test: 512k stripe unit; 4x stripe width"
test_su_opts -o sunit=1024,swidth=4096

log "Test: 512k stripe unit; 3x stripe width"
test_su_opts -o sunit=1024,swidth=3072

# Note: Should succeed with kernel warnings, and should not create repair
# failures or nuke the root directory.
log "Test: 128k stripe unit; 8x stripe width"
test_su_opts -o sunit=256,swidth=2048

# Note: Should succeed without nuking the root dir
log "Test: Repair of 128k stripe unit; 8x stripe width"
test_repair_detection

# Brian Foster noticed a bug in an earlier version of the patch that avoids
# updating the ondisk sunit/swidth values if they would cause later repair
# failures.  The bug was that we wouldn't convert the kernel mount option sunit
# value to the correct incore units until after computing the inode geometry.
# This caused it to behave incorrectly when the filesystem was formatted with
# sunit=1fsb and the mount options try to increase swidth.
log "Test: Formatting with sunit=1fsb,swidth=1fsb and mounting with larger swidth"
test_sunit_opts -o sunit=8,swidth=64

# success, all done
status=0
exit