xfs: fix old fuzz test invocations of xfs_repair
[xfstests-dev.git] / tests / generic / 556
1 # SPDX-License-Identifier: GPL-2.0+
2 #!/bin/bash
3 # FS QA Test No. 556
4 #
5 # Test the basic functionality of filesystems with case-insensitive
6 # support.
7
8 seq=`basename $0`
9 seqres=$RESULT_DIR/$seq
10 echo "QA output created by $seq"
11 status=1 # failure is thea default
12
13 . ./common/rc
14 . ./common/filter
15 . ./common/casefold
16 . ./common/attr
17
18 _supported_fs generic
19 _require_scratch_nocheck
20 _require_scratch_casefold
21 _require_symlinks
22 _require_check_dmesg
23 _require_attrs
24
25 sdev=$(_short_dev ${SCRATCH_DEV})
26
27 filename1="file.txt"
28 filename2="FILE.TXT"
29
30 pt_file1=$(echo -e "coração")
31 pt_file2=$(echo -e "corac\xcc\xa7\xc3\xa3o" | tr a-z A-Z)
32
33 fr_file2=$(echo -e "french_caf\xc3\xa9.txt")
34 fr_file1=$(echo -e "french_cafe\xcc\x81.txt")
35
36 ar_file1=$(echo -e "arabic_\xdb\x92\xd9\x94.txt")
37 ar_file2=$(echo -e "arabic_\xdb\x93.txt" | tr a-z A-Z)
38
39 jp_file1=$(echo -e "japanese_\xe3\x82\xb2.txt")
40 jp_file2=$(echo -e "japanese_\xe3\x82\xb1\xe3\x82\x99.txt")
41
42 # '\xc3\x00' is an invalid sequence. Despite that, the sequences
43 # below could match, if we ignored the error.  But we don't want
44 # to be greedy at normalization, so at the first error we treat
45 # the entire sequence as an opaque blob.  Therefore, these two
46 # must NOT match.
47 blob_file1=$(echo -e "corac\xcc\xa7\xc3")
48 blob_file2=$(echo -e "coraç\xc3")
49
50 # Test helpers
51 basic_create_lookup()
52 {
53         local basedir=${1}
54         local exact=${2}
55         local lookup=${3}
56
57         touch "${basedir}/${exact}"
58         [ -f "${basedir}/${lookup}" ] || \
59                 echo "lookup of ${exact} using ${lookup} failed"
60         _casefold_check_exact_name "${basedir}" "${exact}" || \
61                 echo "Created file ${exact} with wrong name."
62 }
63
64 # CI search should fail.
65 bad_basic_create_lookup()
66 {
67         local basedir=${1}
68         local exact=${2}
69         local lookup=${3}
70
71         touch "${basedir}/${exact}"
72         [ -f "${basedir}/${lookup}" ] && \
73                 echo "Lookup of ${exact} using ${lookup} should fail"
74 }
75
76 # Testcases
77 test_casefold_lookup()
78 {
79         local basedir=${SCRATCH_MNT}/casefold_lookup
80
81         mkdir -p ${basedir}
82         _casefold_set_attr ${basedir}
83
84         basic_create_lookup "${basedir}" "${filename1}" "${filename2}"
85         basic_create_lookup "${basedir}" "${pt_file1}" "${pt_file2}"
86         basic_create_lookup "${basedir}" "${fr_file1}" "${fr_file2}"
87         basic_create_lookup "${basedir}" "${ar_file1}" "${ar_file2}"
88         basic_create_lookup "${basedir}" "${jp_file1}" "${jp_file2}"
89 }
90
91 test_bad_casefold_lookup()
92 {
93         local basedir=${SCRATCH_MNT}/casefold_lookup
94
95         mkdir -p ${basedir}
96
97         bad_basic_create_lookup ${basedir} ${blob_file1} ${blob_file2}
98 }
99
100 do_create_and_remove()
101 {
102         local basedir=${1}
103         local exact=${2}
104         local casefold=${3}
105
106         basic_create_lookup ${basedir} ${exact} ${casefold}
107         rm -f ${basedir}/${exact}
108         [ -f ${basedir}/${exact} ] && \
109                 echo "File ${exact} was not removed using exact name"
110
111         basic_create_lookup ${basedir} ${exact} ${casefold}
112         rm -f ${basedir}/${casefold}
113         [ -f ${basedir}/${exact} ] && \
114                 echo "File ${exact} was not removed using inexact name"
115 }
116
117 # remove and recreate
118 test_create_and_remove()
119 {
120         local basedir=${SCRATCH_MNT}/create_and_remove
121         mkdir -p ${basedir}
122
123         _casefold_set_attr ${basedir}
124         do_create_and_remove "${basedir}" "${pt_file1}" "${pt_file2}"
125         do_create_and_remove "${basedir}" "${jp_file1}" "${jp_file2}"
126         do_create_and_remove "${basedir}" "${ar_file1}" "${ar_file2}"
127         do_create_and_remove "${basedir}" "${fr_file1}" "${fr_file2}"
128 }
129
130 test_casefold_flag_basic()
131 {
132         local basedir=${SCRATCH_MNT}/basic
133
134         mkdir -p ${basedir}
135         _casefold_set_attr ${basedir}
136         _casefold_lsattr_dir ${basedir} | _filter_scratch
137
138         _casefold_unset_attr ${basedir}
139         _casefold_lsattr_dir ${basedir} | _filter_scratch
140 }
141
142 test_casefold_flag_removal()
143 {
144         local basedir=${SCRATCH_MNT}/casefold_flag_removal
145
146         mkdir -p ${basedir}
147         _casefold_set_attr ${basedir}
148         _casefold_lsattr_dir ${basedir} | _filter_scratch
149
150         # Try to remove +F attribute on non empty directory
151         touch ${basedir}/${filename1}
152         _casefold_unset_attr ${basedir} &>/dev/null
153         _casefold_lsattr_dir ${basedir} | _filter_scratch
154 }
155
156 # Test Inheritance of casefold flag
157 test_casefold_flag_inheritance()
158 {
159         local basedir=${SCRATCH_MNT}/flag_inheritance
160         local dirpath1="d1/d2/d3"
161         local dirpath2="D1/D2/D3"
162
163         mkdir -p ${basedir}
164         _casefold_set_attr ${basedir}
165
166         mkdir -p ${basedir}/${dirpath1}
167         _casefold_lsattr_dir ${basedir}/${dirpath1} | _filter_scratch
168
169         [ -d ${basedir}/${dirpath2} ] || \
170                 echo "Directory CI Lookup failed."
171         _casefold_check_exact_name "${basedir}" "${dirpath1}" || \
172                 echo "Created directory with wrong name."
173
174         touch ${basedir}/${dirpath2}/${filename1}
175         [ -f ${basedir}/${dirpath1}/${filename2} ] || \
176                 echo "Couldn't create file on casefolded parent."
177 }
178
179 # Test nesting of sensitive directory inside insensitive directory.
180 test_nesting_sensitive_insensitive_tree_simple()
181 {
182         local basedir=${SCRATCH_MNT}/sd1
183
184         mkdir -p ${basedir}
185         _casefold_set_attr ${basedir}
186
187         mkdir -p ${basedir}/sd1
188         _casefold_set_attr ${basedir}/sd1
189
190         mkdir ${basedir}/sd1/sd2
191         _casefold_unset_attr ${basedir}/sd1/sd2
192
193         touch ${basedir}/sd1/sd2/${filename1}
194         [ -f ${basedir}/sd1/sd2/${filename1} ] || \
195                 echo "Exact nested file lookup failed."
196         [ -f ${basedir}/sd1/SD2/${filename1} ] || \
197                 echo "Nested file lookup failed."
198         [ -f ${basedir}/sd1/SD2/${filename2} ] && \
199                 echo "Wrong file lookup passed, should have fail."
200 }
201
202 test_nesting_sensitive_insensitive_tree_complex()
203 {
204         # Test nested-directories
205         local basedir=${SCRATCH_MNT}/nesting
206
207         mkdir -p ${basedir}
208         _casefold_set_attr ${basedir}
209
210         mkdir ${basedir}/nd1
211         _casefold_set_attr ${basedir}/nd1
212         mkdir ${basedir}/nd1/nd2
213         _casefold_unset_attr ${basedir}/nd1/nd2
214         mkdir ${basedir}/nd1/nd2/nd3
215         _casefold_set_attr ${basedir}/nd1/nd2/nd3
216         mkdir ${basedir}/nd1/nd2/nd3/nd4
217         _casefold_unset_attr ${basedir}/nd1/nd2/nd3/nd4
218         mkdir ${basedir}/nd1/nd2/nd3/nd4/nd5
219         _casefold_set_attr ${basedir}/nd1/nd2/nd3/nd4/nd5
220
221         [ -d ${basedir}/ND1/ND2/nd3/ND4/nd5 ] || \
222                 echo "Nest-dir Lookup failed."
223         [ -d ${basedir}/nd1/nd2/nd3/nd4/ND5 ] && \
224                 echo "ND5: Nest-dir Lookup passed, it should fail."
225         [ -d ${basedir}/nd1/nd2/nd3/ND4/nd5 ] || \
226                 echo "Nest-dir Lookup failed."
227         [ -d ${basedir}/nd1/nd2/ND3/nd4/ND5 ] && \
228                 echo "ND3: Nest-dir Lookup passed, it should fail."
229 }
230
231 test_symlink_with_inexact_name()
232 {
233         local basedir=${SCRATCH_MNT}/symlink
234
235         mkdir -p ${basedir}
236         _casefold_set_attr ${basedir}
237
238         mkdir ${basedir}/ind1
239         mkdir ${basedir}/ind2
240         _casefold_set_attr ${basedir}/ind1
241         touch ${basedir}/ind1/target
242
243         ln -s ${basedir}/ind1/TARGET ${basedir}/ind2/link
244         [ -L ${basedir}/ind2/link ] || echo "Not a symlink."
245         readlink -e ${basedir}/ind2/link | _filter_scratch
246 }
247
248 do_test_name_preserve()
249 {
250         local basedir=${1}
251         local exact=${2}
252         local casefold=${3}
253
254         touch ${basedir}/${exact}
255         rm ${basedir}/${exact}
256
257         touch ${basedir}/${casefold}
258         _casefold_check_exact_name ${basedir} ${casefold} ||
259                 echo "${casefold} was not created with exact name"
260 }
261
262 # Name-preserving tests
263 # We create a file with a name, delete it and create again with an
264 # equivalent name.  If the negative dentry wasn't invalidated, the
265 # file might be created using $1 instead of $2.
266 test_name_preserve()
267 {
268         local basedir=${SCRATCH_MNT}/test_name_preserve
269
270         mkdir -p ${basedir}
271         _casefold_set_attr ${basedir}
272
273         do_test_name_preserve "${basedir}" "${pt_file1}" "${pt_file2}"
274         do_test_name_preserve "${basedir}" "${jp_file1}" "${jp_file2}"
275         do_test_name_preserve "${basedir}" "${ar_file1}" "${ar_file2}"
276         do_test_name_preserve "${basedir}" "${fr_file1}" "${fr_file2}"
277 }
278
279 do_test_dir_name_preserve()
280 {
281         local basedir=${1}
282         local exact=${2}
283         local casefold=${3}
284
285         mkdir ${basedir}/${exact}
286         rmdir ${basedir}/${exact}
287
288         mkdir ${basedir}/${casefold}
289         _casefold_check_exact_name ${basedir} ${casefold} ||
290                 echo "${casefold} was not created with exact name"
291 }
292
293 test_dir_name_preserve()
294 {
295         local basedir=${SCRATCH_MNT}/"dir-test_name_preserve"
296
297         mkdir -p ${basedir}
298         _casefold_set_attr ${basedir}
299
300         do_test_dir_name_preserve "${basedir}" "${pt_file1}" "${pt_file2}"
301         do_test_dir_name_preserve "${basedir}" "${jp_file1}" "${jp_file2}"
302         do_test_dir_name_preserve "${basedir}" "${ar_file1}" "${ar_file2}"
303         do_test_dir_name_preserve "${basedir}" "${fr_file1}" "${fr_file2}"
304 }
305
306 test_name_reuse()
307 {
308         local basedir=${SCRATCH_MNT}/reuse
309         local reuse1=fileX
310         local reuse2=FILEX
311
312         mkdir ${basedir}
313         _casefold_set_attr ${basedir}
314
315         touch ${basedir}/${reuse1}
316         rm -f ${basedir}/${reuse1} || echo "File lookup failed."
317         touch ${basedir}/${reuse2}
318         _casefold_check_exact_name "${basedir}" "${reuse2}" || \
319                 echo "File created with wrong name"
320         _casefold_check_exact_name "${basedir}" "${reuse1}" && \
321                 echo "File created with the old name"
322 }
323
324 test_create_with_same_name()
325 {
326         local basedir=${SCRATCH_MNT}/same_name
327
328         mkdir ${basedir}
329         _casefold_set_attr ${basedir}
330
331         mkdir -p ${basedir}/same1/same1
332         touch ${basedir}/SAME1/sAME1/sAMe1
333         touch -c ${basedir}/SAME1/sAME1/same1 ||
334                 echo "Would create a new file instead of using old one"
335 }
336
337 test_file_rename()
338 {
339         local basedir=${SCRATCH_MNT}/rename
340
341         mkdir -p ${basedir}
342         _casefold_set_attr ${basedir}
343
344         touch ${basedir}/rename
345
346         # Move to an equivalent name should not work
347         mv ${basedir}/rename ${basedir}/RENAME 2>&1 | \
348                 _filter_scratch
349
350         _casefold_check_exact_name ${basedir} "rename" || \
351                 echo "Name shouldn't change."
352 }
353
354 # Test openfd with casefold.
355 # 1. Delete a file after gettings its fd.
356 # 2. Then create new dir with same name
357 test_casefold_openfd()
358 {
359         local basedir=${SCRATCH_MNT}/openfd
360         local ofd1="openfd"
361         local ofd2="OPENFD"
362
363         mkdir -p ${basedir}
364         _casefold_set_attr ${basedir}
365
366         exec 3<> ${basedir}/${ofd1}
367         rm -rf ${basedir}/${ofd1}
368         mkdir ${basedir}/${ofd2}
369         [ -d ${basedir}/${ofd2} ] || echo "Not a directory"
370         _casefold_check_exact_name ${basedir} "${ofd2}" ||
371                 echo "openfd file was created using old name"
372         rm -rf ${basedir}/${ofd2}
373         exec 3>&-
374 }
375
376 # Test openfd with casefold.
377 # 1. Delete a file after gettings its fd.
378 # 2. Then create new file with same name
379 # 3. Read from open-fd and write into new file.
380 test_casefold_openfd2()
381 {
382         local basedir=${SCRATCH_MNT}/openfd2
383         local ofd1="openfd"
384         local ofd2="OPENFD"
385
386         mkdir ${basedir}
387         _casefold_set_attr ${basedir}
388
389         date > ${basedir}/${ofd1}
390         exec 3<> ${basedir}/${ofd1}
391         rm -rf ${basedir}/${ofd1}
392         touch ${basedir}/${ofd1}
393         [ -f ${basedir}/${ofd2} ] || echo "Not a file"
394         read data <&3
395         echo $data >> ${basedir}/${ofd1}
396         exec 3>&-
397 }
398
399 test_hard_link_lookups()
400 {
401         local basedir=${SCRATCH_MNT}/hard_link
402
403         mkdir ${basedir}
404         _casefold_set_attr ${basedir}
405
406         touch ${basedir}/h1
407         ln ${basedir}/H1 ${SCRATCH_MNT}/h1
408         cnt=`stat -c %h ${basedir}/h1`
409         [ $cnt -eq 1 ] && echo "Unable to create hardlink"
410
411         # Create hardlink for casefold dir file and inside regular dir.
412         touch ${SCRATCH_MNT}/h2
413         ln ${SCRATCH_MNT}/h2 ${basedir}/H2
414         cnt=`stat -c %h ${basedir}/h2`
415         [ $cnt -eq 1 ] && echo "Unable to create hardlink"
416 }
417
418 test_xattrs_lookups()
419 {
420         local basedir=${SCRATCH_MNT}/xattrs
421
422         mkdir ${basedir}
423         _casefold_set_attr ${basedir}
424
425         mkdir -p ${basedir}/x
426
427         ${SETFATTR_PROG} -n user.foo -v bar ${basedir}/x
428         ${GETFATTR_PROG} --absolute-names -n user.foo \
429                 ${basedir}/x | _filter_scratch
430
431         touch ${basedir}/x/f1
432         ${SETFATTR_PROG} -n user.foo -v bar ${basedir}/x/f1
433         ${GETFATTR_PROG} --absolute-names -n user.foo \
434                 ${basedir}/x/f1 | _filter_scratch
435 }
436
437 test_lookup_large_directory()
438 {
439         local basedir=${SCRATCH_MNT}/large
440
441         mkdir -p ${basedir}
442         _casefold_set_attr ${basedir}
443
444         touch $(seq -f "${basedir}/file%g" 0 2000)
445
446         # We really want to spawn a single process here, to speed up the
447         # test, but we don't want the output of 2k files, except for
448         # errors.
449         cat $(seq -f "${basedir}/FILE%g" 0 2000) || \
450                 echo "Case on large dir failed"
451 }
452
453 test_strict_mode_invalid_filename()
454 {
455         local basedir=${SCRATCH_MNT}/strict
456
457         mkdir -p ${basedir}
458         _casefold_set_attr ${basedir}
459
460         # These creation commands should fail, since we are on strict
461         # mode.
462         touch "${basedir}/${blob_file1}" 2>&1 | _filter_scratch
463         touch "${basedir}/${blob_file2}" 2>&1 | _filter_scratch
464 }
465
466 #############
467 # Run tests #
468 #############
469
470 _scratch_mkfs_casefold >>$seqres.full 2>&1
471
472 _scratch_mount
473
474 _check_dmesg_for \
475         "\(${sdev}\): Using encoding defined by superblock: utf8" || \
476         _fail "Could not mount with encoding: utf8"
477
478 test_casefold_flag_basic
479 test_casefold_lookup
480 test_bad_casefold_lookup
481 test_create_and_remove
482 test_casefold_flag_removal
483 test_casefold_flag_inheritance
484 test_nesting_sensitive_insensitive_tree_simple
485 test_nesting_sensitive_insensitive_tree_complex
486 test_symlink_with_inexact_name
487 test_name_preserve
488 test_dir_name_preserve
489 test_name_reuse
490 test_create_with_same_name
491 test_file_rename
492 test_casefold_openfd
493 test_casefold_openfd2
494 test_hard_link_lookups
495 test_xattrs_lookups
496 test_lookup_large_directory
497
498 _scratch_unmount
499 _check_scratch_fs
500
501 # Test Strict Mode
502 _scratch_mkfs_casefold_strict >>$seqres.full 2>&1
503 _scratch_mount
504
505 test_strict_mode_invalid_filename
506
507 _scratch_unmount
508 _check_scratch_fs
509
510 status=0
511 exit