8f4ba5c61bc8711bb90c64143c6ed13094ad0b24
[xfstests-dev.git] / tests / btrfs / 220
1 #! /bin/bash
2 # SPDX-License-Identifier: GPL-2.0
3 # Copyright (C) 2020 SUSE Linux Products GmbH. All Rights Reserved.
4 #
5 # FS QA Test 220
6 #
7 # Test all existent mount options of btrfs
8 # * device= argument is already being test by btrfs/125
9 # * space cache test already covered by test btrfs/131
10 seq=`basename $0`
11 seqres=$RESULT_DIR/$seq
12 echo "QA output created by $seq"
13
14 here=`pwd`
15 tmp=/tmp/$$
16 status=1        # failure is the default!
17 trap "cleanup; exit \$status" 0 1 2 3 15
18
19 # get standard environment, filters and checks
20 . ./common/rc
21 . ./common/filter
22
23 # remove previous $seqres.full before test
24 rm -f $seqres.full
25
26 _supported_fs btrfs
27 _require_scratch
28
29 cleanup()
30 {
31         cd /
32         rm -f $tmp.*
33 }
34
35 # Compare the mounted flags with $opt_check. When the comparison fails, $opt is
36 # echoed to help to track which option was used to trigger the unexpected
37 # results.
38 test_mount_flags()
39 {
40         local opt
41         local opt_check
42         opt="$1"
43         opt_check="$2"
44
45         active_opt=$(cat /proc/self/mounts | grep $SCRATCH_MNT | \
46                                         $AWK_PROG '{ print $4 }')
47         if [[ "$active_opt" != *$opt_check* ]]; then
48                 echo "Could not find '$opt_check' in '$active_opt', using '$opt'"
49         fi
50 }
51
52 # Mounts using opt ($1), remounts using remount_opt ($2), and remounts again
53 # using opt again (1), checking if the mount opts are being enabled/disabled by
54 # using _check arguments ($3 and $4)
55 test_enable_disable_mount_opt()
56 {
57         local opt
58         local opt_check
59         local remount_opt
60         local remount_opt_check
61         opt="$1"
62         opt_check="$2"
63         remount_opt="$3"
64         remount_opt_check="$4"
65
66         _scratch_mount "-o $opt"
67
68         test_mount_flags $opt $opt_check
69
70         _scratch_remount $remount_opt
71
72         test_mount_flags $remount_opt $remount_opt_check
73
74         _scratch_remount $opt
75
76         test_mount_flags $opt $opt_check
77
78         _scratch_unmount
79 }
80
81 # Checks if mount options are applied and reverted correctly.
82 # By using options to mount ($1) and remount ($2), this function will mount,
83 # remount, and the mount with the original args, checking if the mount options
84 # match the _check args ($3 and $4).
85
86 # Later, opt and remount_opt are swapped, testing the counterpart option if used
87 # to first mount the fs.
88 test_roundtrip_mount()
89 {
90         local opt
91         local opt_check
92         local remount_opt
93         local remount_opt_check
94         opt="$1"
95         opt_check="$2"
96         remount_opt="$3"
97         remount_opt_check="$4"
98
99         # invert the args to make sure that both options work at mount and
100         # remount time
101         test_enable_disable_mount_opt $opt $opt_check $remount_opt $remount_opt_check
102         test_enable_disable_mount_opt $remount_opt $remount_opt_check $opt $opt_check
103 }
104
105 # Just mount and check if the options were mounted correctly by comparing the
106 # results with $opt_check
107 test_mount_opt()
108 {
109         local opt
110         local opt_check
111         local active_opt
112         opt="$1"
113         opt_check="$2"
114
115         _scratch_mount "-o $opt"
116
117         test_mount_flags $opt $opt_check
118
119         _scratch_unmount
120 }
121
122 # Test mount options that should fail, usually by wrong arguments to options
123 test_should_fail()
124 {
125         local opt
126         opt="$1"
127
128         # wrong $opt on purpose, should fail
129         _try_scratch_mount "-o $opt" >/dev/null 2>&1
130         if [ $? -ne 0 ]; then
131                 return
132         fi
133         echo "Option $opt should fail to mount"
134         _scratch_unmount
135 }
136
137 # Try to mount using $opt, and bail our if the mount fails without errors. If
138 # the mount succeeds, then compare the mount options with $opt_check
139 test_optional_mount_opts()
140 {
141         local opt
142         local opt_check
143         opt="$1"
144         opt_check="$2"
145
146         # $opt not enabled, return without running any tests
147         _try_scratch_mount "-o $opt" >/dev/null 2>&1 || return
148         _scratch_unmount
149
150         # option enabled, run the test
151         test_mount_opt $opt $opt_check
152 }
153
154 # Testes related to subvolumes, from subvol and subvolid options.
155 test_subvol()
156 {
157         test_should_fail "subvol=vol2"
158
159         _scratch_mount "-o subvol=vol1"
160         if [ ! -f "$SCRATCH_MNT/file.txt" ]; then
161                 echo "file.txt not found inside vol1 using subvol=vol1 mount option"
162         fi
163         _scratch_unmount
164
165         test_should_fail "subvolid=222"
166
167         _scratch_mount "-o subvolid=256"
168         if [ ! -f "$SCRATCH_MNT/file.txt" ]; then
169                 echo "file.txt not found inside vol1 using subvolid=256 mount option"
170         fi
171         _scratch_unmount
172
173         # subvol and subvolid should point to the same subvolume
174         test_should_fail "-o subvol=vol1,subvolid=1234132"
175
176         test_mount_opt "subvol=vol1,subvolid=256" "space_cache,subvolid=256,subvol=/vol1"
177         test_roundtrip_mount "subvol=vol1" "space_cache,subvolid=256,subvol=/vol1" "subvolid=256" "space_cache,subvolid=256,subvol=/vol1"
178 }
179
180 # These options are enable at kernel compile time, so no bother if they fail
181 test_optional_kernel_features()
182 {
183         # Test options that are enabled by kernel config, and so can fail safely
184         test_optional_mount_opts "check_int" "space_cache,check_int,subvolid"
185         test_optional_mount_opts "check_int_data" "space_cache,check_int_data,subvolid"
186         test_optional_mount_opts "check_int_print_mask=123" "space_cache,check_int_print_mask=123,subvolid"
187
188         test_should_fail "fragment=invalid"
189         test_optional_mount_opts "fragment=all" "space_cache,fragment=data,fragment=metadata,subvolid"
190         test_optional_mount_opts "fragment=data" "space_cache,fragment=data,subvolid"
191         test_optional_mount_opts "fragment=metadata" "space_cache,fragment=metadata,subvolid"
192 }
193
194 test_non_revertible_options()
195 {
196         test_mount_opt "clear_cache" "relatime,space_cache,clear_cache,subvolid"
197         test_mount_opt "degraded" "relatime,degraded,space_cache,subvolid"
198
199         test_mount_opt "inode_cache" "space_cache,inode_cache,subvolid"
200
201         # nologreplay should be used only with
202         test_should_fail "nologreplay"
203         test_mount_opt "nologreplay,ro" "ro,relatime,rescue=nologreplay,space_cache"
204
205         # norecovery should be used only with. This options is an alias to nologreplay
206         test_should_fail "norecovery"
207         test_mount_opt "norecovery,ro" "ro,relatime,rescue=nologreplay,space_cache"
208         test_mount_opt "rescan_uuid_tree" "relatime,space_cache,rescan_uuid_tree,subvolid"
209         test_mount_opt "skip_balance" "relatime,space_cache,skip_balance,subvolid"
210         test_mount_opt "user_subvol_rm_allowed" "space_cache,user_subvol_rm_allowed,subvolid"
211
212         test_should_fail "rescue=invalid"
213
214         # nologreplay requires readonly
215         test_should_fail "rescue=nologreplay"
216         test_mount_opt "rescue=nologreplay,ro" "relatime,rescue=nologreplay,space_cache"
217
218         test_mount_opt "rescue=usebackuproot,ro" "relatime,space_cache,subvolid"
219 }
220
221 # All these options can be reverted (with their "no" counterpart), or can have
222 # their values set to default on remount
223 test_revertible_options()
224 {
225         test_roundtrip_mount "acl" "relatime,space_cache,subvolid" "noacl" "relatime,noacl,space_cache,subvolid"
226         test_roundtrip_mount "autodefrag" "relatime,space_cache,autodefrag" "noautodefrag" "relatime,space_cache,subvolid"
227         test_roundtrip_mount "barrier" "relatime,space_cache,subvolid" "nobarrier" "relatime,nobarrier,space_cache,subvolid"
228
229         test_should_fail "commit=-10"
230         # commit=0 sets the default, so btrfs hides this mount opt
231         test_roundtrip_mount "commit=35" "relatime,space_cache,commit=35,subvolid" "commit=0" "relatime,space_cache,subvolid"
232
233         test_should_fail "compress=invalid"
234         test_should_fail "compress-force=invalid"
235         test_roundtrip_mount "compress" "relatime,compress=zlib:3,space_cache,subvolid" "compress=lzo" "relatime,compress=lzo,space_cache,subvolid"
236         test_roundtrip_mount "compress=zstd" "relatime,compress=zstd:3,space_cache,subvolid" "compress=no" "relatime,space_cache,subvolid"
237         test_roundtrip_mount "compress-force=no" "relatime,space_cache,subvolid" "compress-force=zstd" "relatime,compress-force=zstd:3,space_cache,subvolid"
238         # zlib's max level is 9 and zstd's max level is 15
239         test_roundtrip_mount "compress=zlib:20" "relatime,compress=zlib:9,space_cache,subvolid" "compress=zstd:16" "relatime,compress=zstd:15,space_cache,subvolid"
240         test_roundtrip_mount "compress-force=lzo" "relatime,compress-force=lzo,space_cache,subvolid" "compress-force=zlib:4" "relatime,compress-force=zlib:4,space_cache,subvolid"
241
242         # on remount, if we only pass datacow after nodatacow was used it will remain with nodatasum
243         test_roundtrip_mount "nodatacow" "relatime,nodatasum,nodatacow,space_cache,subvolid" "datacow,datasum" "relatime,space_cache,subvolid"
244         # nodatacow disabled compression
245         test_roundtrip_mount "compress-force" "relatime,compress-force=zlib:3,space_cache,subvolid" "nodatacow" "relatime,nodatasum,nodatacow,space_cache,subvolid"
246
247         # nodatacow disabled both datacow and datasum, and datasum enabled datacow and datasum
248         test_roundtrip_mount "nodatacow" "relatime,nodatasum,nodatacow,space_cache,subvolid" "datasum" "relatime,space_cache,subvolid"
249         test_roundtrip_mount "nodatasum" "relatime,nodatasum,space_cache,subvolid" "datasum" "relatime,space_cache,subvolid"
250
251         test_should_fail "discard=invalid"
252         test_roundtrip_mount "discard" "relatime,discard,space_cache,subvolid" "discard=sync" "relatime,discard,space_cache,subvolid"
253         test_roundtrip_mount "discard=async" "relatime,discard=async,space_cache,subvolid" "discard=sync" "relatime,discard,space_cache,subvolid"
254         test_roundtrip_mount "discard=sync" "relatime,discard,space_cache,subvolid" "nodiscard" "relatime,space_cache,subvolid"
255
256         test_roundtrip_mount "enospc_debug" "relatime,space_cache,enospc_debug,subvolid" "noenospc_debug" "relatime,space_cache,subvolid"
257
258         test_should_fail "fatal_errors=pani"
259         # fatal_errors=bug is the default
260         test_roundtrip_mount "fatal_errors=panic" "relatime,space_cache,fatal_errors=panic,subvolid" "fatal_errors=bug" "relatime,space_cache,subvolid"
261
262         test_roundtrip_mount "flushoncommit" "relatime,flushoncommit,space_cache,subvolid" "noflushoncommit" "relatime,space_cache,subvolid"
263
264         # 2048 is the max_inline default value
265         test_roundtrip_mount "max_inline=1024" "relatime,max_inline=1024,space_cache" "max_inline=2048" "relatime,space_cache,subvolid"
266
267         test_roundtrip_mount "metadata_ratio=0" "relatime,space_cache,subvolid" "metadata_ratio=10" "space_cache,metadata_ratio=10,subvolid"
268
269         # ssd_spread implies ssd, while nossd_spread only disables ssd_spread
270         test_roundtrip_mount "ssd_spread" "relatime,ssd_spread,space_cache" "nossd" "relatime,nossd,space_cache,subvolid"
271         test_roundtrip_mount "ssd" "relatime,ssd,space_cache" "nossd" "relatime,nossd,space_cache,subvolid"
272         test_mount_opt "ssd" "relatime,ssd,space_cache"
273
274         test_should_fail "thread_pool=-10"
275         test_should_fail "thread_pool=0"
276         test_roundtrip_mount "thread_pool=10" "relatime,thread_pool=10,space_cache" "thread_pool=50" "relatime,thread_pool=50,space_cache"
277
278         test_roundtrip_mount "notreelog" "relatime,notreelog,space_cache" "treelog" "relatime,space_cache,subvolid"
279 }
280
281 # real QA test starts here
282 _scratch_mkfs >/dev/null
283
284 # create a subvolume that will be used later
285 _scratch_mount
286 $BTRFS_UTIL_PROG subvolume create "$SCRATCH_MNT/vol1" > /dev/null
287 touch "$SCRATCH_MNT/vol1/file.txt"
288 _scratch_unmount
289
290 test_optional_kernel_features
291
292 test_non_revertible_options
293
294 test_revertible_options
295
296 test_subvol
297
298 echo "Silence is golden"
299
300 status=0
301 exit