common: kill _supported_os
[xfstests-dev.git] / tests / ext4 / 022
1 #! /bin/bash
2 # SPDX-License-Identifier: GPL-2.0
3 # Copyright (c) 2016 SUSE Linux Products GmbH.  All Rights Reserved.
4 #
5 # FS QA Test 022
6 #
7 # Test extending of i_extra_isize code
8 #
9 seq=`basename $0`
10 seqres=$RESULT_DIR/$seq
11 echo "QA output created by $seq"
12
13 here=`pwd`
14 tmp=/tmp/$$
15 status=1        # failure is the default!
16 trap "_cleanup; exit \$status" 0 1 2 3 15
17
18 _cleanup()
19 {
20         cd /
21         rm -f $tmp.*
22 }
23
24 do_setfattr()
25 {
26         $SETFATTR_PROG $@ 2>&1 | _filter_scratch
27 }
28
29 # get standard environment, filters and checks
30 . ./common/rc
31 . ./common/filter
32 . ./common/attr
33
34 # remove previous $seqres.full before test
35 rm -f $seqres.full
36
37 # real QA test starts here
38 _supported_fs ext4
39 _require_scratch
40 _require_dumpe2fs
41 _require_command "$DEBUGFS_PROG" debugfs
42 _require_attrs
43
44 # Use large inodes to have enough space for experimentation
45 INODE_SIZE=1024
46 # Block size
47 BLOCK_SIZE=4096
48 # We leave this amount of bytes for xattrs
49 XATTR_SPACE=256
50 # We grow extra_isize by this much
51 GROW_EXTRA_ISIZE=80
52 # We grow minimum requested isize by this much
53 GROW_MIN_EXTRA_ISIZE=16
54
55 export MKFS_OPTIONS="-I $INODE_SIZE -b $BLOCK_SIZE"
56 _scratch_mkfs >> $seqres.full 2>&1
57
58 ISIZE=$($DUMPE2FS_PROG -h $SCRATCH_DEV 2>/dev/null |
59         grep "^Desired extra isize:" | awk '{print $4}')
60 # 32 bytes for header and 4 bytes for terminator
61 BLOCK_XATTR_SPACE=$(($BLOCK_SIZE - 36))
62 GOOD_OLD_ISIZE=128
63 WANT_ISIZE=$(($INODE_SIZE-$GOOD_OLD_ISIZE-$XATTR_SPACE))
64 NEW_ISIZE=$(($WANT_ISIZE+$GROW_EXTRA_ISIZE))
65 NEW_MIN_ISIZE=$(($WANT_ISIZE+$GROW_MIN_EXTRA_ISIZE))
66
67 if [ $WANT_ISIZE -lt $ISIZE ]; then
68         _notrun "This test requires at least $XATTR_SPACE free in the inode"
69 fi
70
71 $DEBUGFS_PROG -w -R "ssv want_extra_isize $WANT_ISIZE" $SCRATCH_DEV >> $seqres.full 2>&1
72 $DEBUGFS_PROG -w -R "ssv min_extra_isize $WANT_ISIZE" $SCRATCH_DEV >> $seqres.full 2>&1
73
74 _scratch_mount
75
76 FNAMES=("empty" "couple_xattrs" "just_enough_xattrs" "one_extra_xattr"
77         "full_xattrs" "one_extra_xattr_ext" "full_xattrs_ext"
78         "full_xattrs_almost_full_ext" "full_xattrs_full_ext")
79 create_xattr_file()
80 {
81         FILE=$SCRATCH_MNT/${FNAMES[$1]}
82         touch $FILE
83         for (( i = 0; i < $2; i++ )); do
84                 do_setfattr -n "user.$i" -v "aa" $FILE || break
85         done
86 }
87
88 # Test file without xattrs
89 create_xattr_file 0 0
90
91 # Test file with couple of xattrs but which still has enough space
92 # One xattr consumes 24 bytes + 4 bytes for header + 4 bytes for terminator
93 # => 104 bytes consumed (152 bytes still free)
94 create_xattr_file 1 4
95
96 # Test file with xattrs which still has just enough space
97 # One xattr consumes 24 bytes + 4 bytes for header + 4 bytes for terminator
98 # => 176 bytes consumed (80 bytes still free)
99 create_xattr_file 2 7
100
101 # Test file with xattrs which has one xattr which needs moving
102 # One xattr consumes 24 bytes + 4 bytes for header + 4 bytes for terminator
103 # => 200 bytes consumed (56 bytes still free)
104 create_xattr_file 3 8
105
106 # Test file with xattrs which has xattr space almost full
107 # One xattr consumes 24 bytes + 4 bytes for header + 4 bytes for terminator
108 # => 248 bytes consumed (8 bytes still free)
109 create_xattr_file 4 10
110
111 # Test file with xattrs which has one xattr which needs moving and external
112 # xattr block allocated
113 # One xattr consumes 24 bytes + 4 bytes for header + 4 bytes for terminator
114 # => 200 bytes consumed (56 bytes still free)
115 create_xattr_file 5 8
116 do_setfattr -n "user.e0" -v "01234567890123456789012345678901234567890123456789" "$SCRATCH_MNT/${FNAMES[5]}"
117
118 # Test file with xattrs which has xattr space in inode almost full and external
119 # xattr block allocated
120 # One xattr consumes 24 bytes + 4 bytes for header + 4 bytes for terminator
121 # => 248 bytes consumed (8 bytes still free)
122 create_xattr_file 6 11
123
124 # Test file with xattrs which has xattr space in inode almost full and external
125 # xattr block allocated and almost full so that inode can still expand to
126 # s_min_extra_isize
127 # 10 xattrs fit into inode, rest goes into xattr block (one xattr consumes
128 # 24 bytes)
129 create_xattr_file 7 $((10 + ($BLOCK_XATTR_SPACE - $GROW_MIN_EXTRA_ISIZE) / 24))
130
131 # Test file with xattrs which has xattr space in inode almost full and external
132 # xattr block allocated and full
133 # 10 xattrs fit into inode, rest goes into xattr block (one xattr consumes
134 # 24 bytes)
135 create_xattr_file 8 $((10 + $BLOCK_XATTR_SPACE / 24))
136
137 _scratch_unmount
138
139 # Filesystem prepared, update extra_isize
140
141 $DEBUGFS_PROG -w -R "ssv want_extra_isize $NEW_ISIZE" $SCRATCH_DEV >> $seqres.full 2>&1
142 $DEBUGFS_PROG -w -R "ssv min_extra_isize $NEW_MIN_ISIZE" $SCRATCH_DEV >> $seqres.full 2>&1
143
144 _scratch_mount
145
146 # Dirty each inode to force expansion of extra_isize
147 for FILE in ${FNAMES[@]}; do
148         echo "aaaa" >$SCRATCH_MNT/$FILE
149 done
150
151 # Dump all xattrs to see whether nothing broke
152 for FILE in ${FNAMES[@]}; do
153         _getfattr -h -d --absolute-names $SCRATCH_MNT/$FILE 2>/dev/null | \
154                 _filter_scratch | sort
155 done
156
157 _scratch_unmount
158
159 # Dump everything via debugfs to check whether sizes got extended as expected
160 for FILE in ${FNAMES[@]}; do
161         $DEBUGFS_PROG -R "stat $FILE" $SCRATCH_DEV 2>/dev/null | \
162                 grep "^Size of extra inode fields:"
163 done
164
165 # success, all done
166 status=0
167 exit