1 # SPDX-License-Identifier: GPL-2.0+
5 # Test the basic functionality of filesystems with case-insensitive
9 seqres=$RESULT_DIR/$seq
10 echo "QA output created by $seq"
11 status=1 # failure is thea default
20 _require_scratch_nocheck
21 _require_scratch_casefold
26 sdev=$(_short_dev ${SCRATCH_DEV})
31 pt_file1=$(echo -e "coração")
32 pt_file2=$(echo -e "corac\xcc\xa7\xc3\xa3o" | tr a-z A-Z)
34 fr_file2=$(echo -e "french_caf\xc3\xa9.txt")
35 fr_file1=$(echo -e "french_cafe\xcc\x81.txt")
37 ar_file1=$(echo -e "arabic_\xdb\x92\xd9\x94.txt")
38 ar_file2=$(echo -e "arabic_\xdb\x93.txt" | tr a-z A-Z)
40 jp_file1=$(echo -e "japanese_\xe3\x82\xb2.txt")
41 jp_file2=$(echo -e "japanese_\xe3\x82\xb1\xe3\x82\x99.txt")
43 # '\xc3\x00' is an invalid sequence. Despite that, the sequences
44 # below could match, if we ignored the error. But we don't want
45 # to be greedy at normalization, so at the first error we treat
46 # the entire sequence as an opaque blob. Therefore, these two
48 blob_file1=$(echo -e "corac\xcc\xa7\xc3")
49 blob_file2=$(echo -e "coraç\xc3")
58 touch "${basedir}/${exact}"
59 [ -f "${basedir}/${lookup}" ] || \
60 echo "lookup of ${exact} using ${lookup} failed"
61 _casefold_check_exact_name "${basedir}" "${exact}" || \
62 echo "Created file ${exact} with wrong name."
65 # CI search should fail.
66 bad_basic_create_lookup()
72 touch "${basedir}/${exact}"
73 [ -f "${basedir}/${lookup}" ] && \
74 echo "Lookup of ${exact} using ${lookup} should fail"
78 test_casefold_lookup()
80 local basedir=${SCRATCH_MNT}/casefold_lookup
83 _casefold_set_attr ${basedir}
85 basic_create_lookup "${basedir}" "${filename1}" "${filename2}"
86 basic_create_lookup "${basedir}" "${pt_file1}" "${pt_file2}"
87 basic_create_lookup "${basedir}" "${fr_file1}" "${fr_file2}"
88 basic_create_lookup "${basedir}" "${ar_file1}" "${ar_file2}"
89 basic_create_lookup "${basedir}" "${jp_file1}" "${jp_file2}"
92 test_bad_casefold_lookup()
94 local basedir=${SCRATCH_MNT}/casefold_lookup
98 bad_basic_create_lookup ${basedir} ${blob_file1} ${blob_file2}
101 do_create_and_remove()
107 basic_create_lookup ${basedir} ${exact} ${casefold}
108 rm -f ${basedir}/${exact}
109 [ -f ${basedir}/${exact} ] && \
110 echo "File ${exact} was not removed using exact name"
112 basic_create_lookup ${basedir} ${exact} ${casefold}
113 rm -f ${basedir}/${casefold}
114 [ -f ${basedir}/${exact} ] && \
115 echo "File ${exact} was not removed using inexact name"
118 # remove and recreate
119 test_create_and_remove()
121 local basedir=${SCRATCH_MNT}/create_and_remove
124 _casefold_set_attr ${basedir}
125 do_create_and_remove "${basedir}" "${pt_file1}" "${pt_file2}"
126 do_create_and_remove "${basedir}" "${jp_file1}" "${jp_file2}"
127 do_create_and_remove "${basedir}" "${ar_file1}" "${ar_file2}"
128 do_create_and_remove "${basedir}" "${fr_file1}" "${fr_file2}"
131 test_casefold_flag_basic()
133 local basedir=${SCRATCH_MNT}/basic
136 _casefold_set_attr ${basedir}
137 _casefold_lsattr_dir ${basedir} | _filter_scratch
139 _casefold_unset_attr ${basedir}
140 _casefold_lsattr_dir ${basedir} | _filter_scratch
143 test_casefold_flag_removal()
145 local basedir=${SCRATCH_MNT}/casefold_flag_removal
148 _casefold_set_attr ${basedir}
149 _casefold_lsattr_dir ${basedir} | _filter_scratch
151 # Try to remove +F attribute on non empty directory
152 touch ${basedir}/${filename1}
153 _casefold_unset_attr ${basedir} &>/dev/null
154 _casefold_lsattr_dir ${basedir} | _filter_scratch
157 # Test Inheritance of casefold flag
158 test_casefold_flag_inheritance()
160 local basedir=${SCRATCH_MNT}/flag_inheritance
161 local dirpath1="d1/d2/d3"
162 local dirpath2="D1/D2/D3"
165 _casefold_set_attr ${basedir}
167 mkdir -p ${basedir}/${dirpath1}
168 _casefold_lsattr_dir ${basedir}/${dirpath1} | _filter_scratch
170 [ -d ${basedir}/${dirpath2} ] || \
171 echo "Directory CI Lookup failed."
172 _casefold_check_exact_name "${basedir}" "${dirpath1}" || \
173 echo "Created directory with wrong name."
175 touch ${basedir}/${dirpath2}/${filename1}
176 [ -f ${basedir}/${dirpath1}/${filename2} ] || \
177 echo "Couldn't create file on casefolded parent."
180 # Test nesting of sensitive directory inside insensitive directory.
181 test_nesting_sensitive_insensitive_tree_simple()
183 local basedir=${SCRATCH_MNT}/sd1
186 _casefold_set_attr ${basedir}
188 mkdir -p ${basedir}/sd1
189 _casefold_set_attr ${basedir}/sd1
191 mkdir ${basedir}/sd1/sd2
192 _casefold_unset_attr ${basedir}/sd1/sd2
194 touch ${basedir}/sd1/sd2/${filename1}
195 [ -f ${basedir}/sd1/sd2/${filename1} ] || \
196 echo "Exact nested file lookup failed."
197 [ -f ${basedir}/sd1/SD2/${filename1} ] || \
198 echo "Nested file lookup failed."
199 [ -f ${basedir}/sd1/SD2/${filename2} ] && \
200 echo "Wrong file lookup passed, should have fail."
203 test_nesting_sensitive_insensitive_tree_complex()
205 # Test nested-directories
206 local basedir=${SCRATCH_MNT}/nesting
209 _casefold_set_attr ${basedir}
212 _casefold_set_attr ${basedir}/nd1
213 mkdir ${basedir}/nd1/nd2
214 _casefold_unset_attr ${basedir}/nd1/nd2
215 mkdir ${basedir}/nd1/nd2/nd3
216 _casefold_set_attr ${basedir}/nd1/nd2/nd3
217 mkdir ${basedir}/nd1/nd2/nd3/nd4
218 _casefold_unset_attr ${basedir}/nd1/nd2/nd3/nd4
219 mkdir ${basedir}/nd1/nd2/nd3/nd4/nd5
220 _casefold_set_attr ${basedir}/nd1/nd2/nd3/nd4/nd5
222 [ -d ${basedir}/ND1/ND2/nd3/ND4/nd5 ] || \
223 echo "Nest-dir Lookup failed."
224 [ -d ${basedir}/nd1/nd2/nd3/nd4/ND5 ] && \
225 echo "ND5: Nest-dir Lookup passed, it should fail."
226 [ -d ${basedir}/nd1/nd2/nd3/ND4/nd5 ] || \
227 echo "Nest-dir Lookup failed."
228 [ -d ${basedir}/nd1/nd2/ND3/nd4/ND5 ] && \
229 echo "ND3: Nest-dir Lookup passed, it should fail."
232 test_symlink_with_inexact_name()
234 local basedir=${SCRATCH_MNT}/symlink
237 _casefold_set_attr ${basedir}
239 mkdir ${basedir}/ind1
240 mkdir ${basedir}/ind2
241 _casefold_set_attr ${basedir}/ind1
242 touch ${basedir}/ind1/target
244 ln -s ${basedir}/ind1/TARGET ${basedir}/ind2/link
245 [ -L ${basedir}/ind2/link ] || echo "Not a symlink."
246 readlink -e ${basedir}/ind2/link | _filter_scratch
249 do_test_name_preserve()
255 touch ${basedir}/${exact}
256 rm ${basedir}/${exact}
258 touch ${basedir}/${casefold}
259 _casefold_check_exact_name ${basedir} ${casefold} ||
260 echo "${casefold} was not created with exact name"
263 # Name-preserving tests
264 # We create a file with a name, delete it and create again with an
265 # equivalent name. If the negative dentry wasn't invalidated, the
266 # file might be created using $1 instead of $2.
269 local basedir=${SCRATCH_MNT}/test_name_preserve
272 _casefold_set_attr ${basedir}
274 do_test_name_preserve "${basedir}" "${pt_file1}" "${pt_file2}"
275 do_test_name_preserve "${basedir}" "${jp_file1}" "${jp_file2}"
276 do_test_name_preserve "${basedir}" "${ar_file1}" "${ar_file2}"
277 do_test_name_preserve "${basedir}" "${fr_file1}" "${fr_file2}"
280 do_test_dir_name_preserve()
286 mkdir ${basedir}/${exact}
287 rmdir ${basedir}/${exact}
289 mkdir ${basedir}/${casefold}
290 _casefold_check_exact_name ${basedir} ${casefold} ||
291 echo "${casefold} was not created with exact name"
294 test_dir_name_preserve()
296 local basedir=${SCRATCH_MNT}/"dir-test_name_preserve"
299 _casefold_set_attr ${basedir}
301 do_test_dir_name_preserve "${basedir}" "${pt_file1}" "${pt_file2}"
302 do_test_dir_name_preserve "${basedir}" "${jp_file1}" "${jp_file2}"
303 do_test_dir_name_preserve "${basedir}" "${ar_file1}" "${ar_file2}"
304 do_test_dir_name_preserve "${basedir}" "${fr_file1}" "${fr_file2}"
309 local basedir=${SCRATCH_MNT}/reuse
314 _casefold_set_attr ${basedir}
316 touch ${basedir}/${reuse1}
317 rm -f ${basedir}/${reuse1} || echo "File lookup failed."
318 touch ${basedir}/${reuse2}
319 _casefold_check_exact_name "${basedir}" "${reuse2}" || \
320 echo "File created with wrong name"
321 _casefold_check_exact_name "${basedir}" "${reuse1}" && \
322 echo "File created with the old name"
325 test_create_with_same_name()
327 local basedir=${SCRATCH_MNT}/same_name
330 _casefold_set_attr ${basedir}
332 mkdir -p ${basedir}/same1/same1
333 touch ${basedir}/SAME1/sAME1/sAMe1
334 touch -c ${basedir}/SAME1/sAME1/same1 ||
335 echo "Would create a new file instead of using old one"
340 local basedir=${SCRATCH_MNT}/rename
343 _casefold_set_attr ${basedir}
345 # Move to an equivalent name should not work
346 mv ${basedir}/rename ${basedir}/rename 2>&1 | \
349 _casefold_check_exact_name ${basedir} "rename" || \
350 echo "Name shouldn't change."
353 # Test openfd with casefold.
354 # 1. Delete a file after gettings its fd.
355 # 2. Then create new dir with same name
356 test_casefold_openfd()
358 local basedir=${SCRATCH_MNT}/openfd
363 _casefold_set_attr ${basedir}
365 exec 3<> ${basedir}/${ofd1}
366 rm -rf ${basedir}/${ofd1}
367 mkdir ${basedir}/${ofd2}
368 [ -d ${basedir}/${ofd2} ] || echo "Not a directory"
369 _casefold_check_exact_name ${basedir} "${ofd2}" ||
370 echo "openfd file was created using old name"
371 rm -rf ${basedir}/${ofd2}
375 # Test openfd with casefold.
376 # 1. Delete a file after gettings its fd.
377 # 2. Then create new file with same name
378 # 3. Read from open-fd and write into new file.
379 test_casefold_openfd2()
381 local basedir=${SCRATCH_MNT}/openfd2
386 _casefold_set_attr ${basedir}
388 date > ${basedir}/${ofd1}
389 exec 3<> ${basedir}/${ofd1}
390 rm -rf ${basedir}/${ofd1}
391 touch ${basedir}/${ofd1}
392 [ -f ${basedir}/${ofd2} ] || echo "Not a file"
394 echo $data >> ${basedir}/${ofd1}
398 test_hard_link_lookups()
400 local basedir=${SCRATCH_MNT}/hard_link
403 _casefold_set_attr ${basedir}
406 ln ${basedir}/H1 ${SCRATCH_MNT}/h1
407 cnt=`stat -c %h ${basedir}/h1`
408 [ $cnt -eq 1 ] && echo "Unable to create hardlink"
410 # Create hardlink for casefold dir file and inside regular dir.
411 touch ${SCRATCH_MNT}/h2
412 ln ${SCRATCH_MNT}/h2 ${basedir}/H2
413 cnt=`stat -c %h ${basedir}/h2`
414 [ $cnt -eq 1 ] && echo "Unable to create hardlink"
417 test_xattrs_lookups()
419 local basedir=${SCRATCH_MNT}/xattrs
422 _casefold_set_attr ${basedir}
424 mkdir -p ${basedir}/x
426 ${SETFATTR_PROG} -n user.foo -v bar ${basedir}/x
427 ${GETFATTR_PROG} --absolute-names -n user.foo \
428 ${basedir}/x | _filter_scratch
430 touch ${basedir}/x/f1
431 ${SETFATTR_PROG} -n user.foo -v bar ${basedir}/x/f1
432 ${GETFATTR_PROG} --absolute-names -n user.foo \
433 ${basedir}/x/f1 | _filter_scratch
436 test_lookup_large_directory()
438 local basedir=${SCRATCH_MNT}/large
441 _casefold_set_attr ${basedir}
443 touch $(seq -f "${basedir}/file%g" 0 2000)
445 # We really want to spawn a single process here, to speed up the
446 # test, but we don't want the output of 2k files, except for
448 cat $(seq -f "${basedir}/FILE%g" 0 2000) || \
449 echo "Case on large dir failed"
452 test_strict_mode_invalid_filename()
454 local basedir=${SCRATCH_MNT}/strict
457 _casefold_set_attr ${basedir}
459 # These creation commands should fail, since we are on strict
461 touch "${basedir}/${blob_file1}" 2>&1 | _filter_scratch
462 touch "${basedir}/${blob_file2}" 2>&1 | _filter_scratch
469 _scratch_mkfs_casefold >>$seqres.full 2>&1
474 "\(${sdev}\): Using encoding defined by superblock: utf8" || \
475 _fail "Could not mount with encoding: utf8"
477 test_casefold_flag_basic
479 test_bad_casefold_lookup
480 test_create_and_remove
481 test_casefold_flag_removal
482 test_casefold_flag_inheritance
483 test_nesting_sensitive_insensitive_tree_simple
484 test_nesting_sensitive_insensitive_tree_complex
485 test_symlink_with_inexact_name
487 test_dir_name_preserve
489 test_create_with_same_name
492 test_casefold_openfd2
493 test_hard_link_lookups
495 test_lookup_large_directory
501 _scratch_mkfs_casefold_strict >>$seqres.full 2>&1
504 test_strict_mode_invalid_filename