]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - tests/zfs-tests/tests/functional/casenorm/mixed_create_failure.ksh
Vendor import of openzfs master @ 184df27eef0abdc7ab2105b21257f753834b936b
[FreeBSD/FreeBSD.git] / tests / zfs-tests / tests / functional / casenorm / mixed_create_failure.ksh
1 #!/bin/ksh -p
2 #
3 #
4 # This file and its contents are supplied under the terms of the
5 # Common Development and Distribution License ("CDDL"), version 1.0.
6 # You may only use this file in accordance with the terms of version
7 # 1.0 of the CDDL.
8 #
9 # A full copy of the text of the CDDL should have accompanied this
10 # source.  A copy of the CDDL is also available via the Internet at
11 # http://www.illumos.org/license/CDDL.
12 #
13 #
14 # Copyright 2018 Nutanix Inc.  All rights reserved.
15 #
16
17 . $STF_SUITE/tests/functional/casenorm/casenorm.kshlib
18
19 # DESCRIPTION:
20 # For the filesystem with casesensitivity=mixed, normalization=none,
21 # when multiple files with the same name (differing only in case) are created,
22 # the number of files is limited to what can fit in a fatzap leaf-block.
23 # And beyond that, it fails with ENOSPC.
24 #
25 # Ensure that the create/rename operations fail gracefully and not trigger an
26 # ASSERT.
27 #
28 # STRATEGY:
29 # Repeat the below steps for objects: files, directories, symlinks and hardlinks
30 # 1. Create objects with same name but varying in case.
31 #    E.g. 'abcdefghijklmnop', 'Abcdefghijklmnop', 'ABcdefghijklmnop' etc.
32 #    The create should fail with ENOSPC.
33 # 2. Create an object with name 'tmp_obj' and try to rename it to name that we
34 #    failed to add in step 1 above.
35 #    This should fail as well.
36
37 verify_runnable "global"
38
39 function cleanup
40 {
41         destroy_testfs
42 }
43
44 log_onexit cleanup
45 log_assert "With mixed mode: ensure create fails with ENOSPC beyond a certain limit"
46
47 create_testfs "-o casesensitivity=mixed -o normalization=none"
48
49 # Different object types
50 obj_type=('file' 'dir' 'symlink' 'hardlink')
51
52 # Commands to create different object types
53 typeset -A ops
54 ops['file']='touch'
55 ops['dir']='mkdir'
56 ops['symlink']='ln -s'
57 ops['hardlink']='ln'
58
59 # This function tests the following for a give object type :
60 # - Create multiple objects with the same name (varying only in case).
61 #   Ensure that it eventually fails once the leaf-block limit is exceeded.
62 # - Create another object with a different name. And attempt rename it to the
63 #   name (for which the create had failed in the previous step).
64 #   This should fail as well.
65 # Args :
66 #   $1 - object type (file/dir/symlink/hardlink)
67 #   $2 - test directory
68 #
69 function test_ops
70 {
71         typeset obj_type=$1
72         typeset testdir=$2
73
74         target_obj='target-file'
75
76         op="${ops[$obj_type]}"
77
78         log_note "The op : $op"
79         log_note "testdir=$testdir obj_type=$obj_type"
80
81         test_path="$testdir/$obj_type"
82         mkdir $test_path
83         log_note "Created test dir $test_path"
84
85         if [[ $obj_type = "symlink" || $obj_type = "hardlink" ]]; then
86                 touch $test_path/$target_obj
87                 log_note "Created target: $test_path/$target_obj"
88                 op="$op $test_path/$target_obj"
89         fi
90
91         log_note "op : $op"
92         names='{a,A}{b,B}{c,C}{d,D}{e,E}{f,F}{g,G}{h,H}{i,I}{j,J}{k,K}{l,L}'
93         for name in $names; do
94                 cmd="$op $test_path/$name"
95                 out=$($cmd 2>&1)
96                 ret=$?
97                 log_note "cmd: $cmd ret: $ret out=$out"
98                 if (($ret != 0)); then
99                         if [[ $out = *@(No space left on device)* ]]; then
100                                 save_name="$test_path/$name"
101                                 break;
102                         else
103                                 log_err "$cmd failed with unexpected error : $out"
104                         fi
105                 fi
106         done
107
108         log_note 'Test rename \"sample_name\" rename'
109         TMP_OBJ="$test_path/tmp_obj"
110         cmd="$op $TMP_OBJ"
111         out=$($cmd 2>&1)
112         ret=$?
113         if (($ret != 0)); then
114                 log_err "cmd:$cmd failed out:$out"
115         fi
116
117         # Now, try to rename the tmp_obj to the name which we failed to add earlier.
118         # This should fail as well.
119         out=$(mv $TMP_OBJ $save_name 2>&1)
120         ret=$?
121         if (($ret != 0)); then
122                 if [[ $out = *@(No space left on device)* ]]; then
123                         log_note "$cmd failed as expected : $out"
124                 else
125                         log_err "$cmd failed with : $out"
126                 fi
127         fi
128 }
129
130 for obj_type in ${obj_type[*]};
131 do
132         log_note "Testing create of $obj_type"
133         test_ops $obj_type $TESTDIR
134 done
135
136 log_pass "Mixed mode FS: Ops on large number of colliding names fail gracefully"