xfs/007: fix regressions on V4 filesystems
[xfstests-dev.git] / tests / xfs / 136
1 #! /bin/bash
2 # SPDX-License-Identifier: GPL-2.0
3 # Copyright (c) 2000-2005 Silicon Graphics, Inc.  All Rights Reserved.
4 #
5 # FS QA Test No. 136
6 #
7 # Test the attr2 code
8 # Let's look, xfs_db, at the inode and its literal area for the
9 # extents and the attributes 
10 #
11 . ./common/preamble
12 _begin_fstest attr2
13
14 # Import common functions.
15 . ./common/filter
16 . ./common/attr
17
18 # real QA test starts here
19
20 #_notrun "Need to fix up filtering before checkin" 
21
22 # Modify as appropriate.
23 _supported_fs xfs
24
25 _require_scratch
26 _require_attrs
27
28 export MKFS_OPTIONS="-i size=512,attr=2"
29 _scratch_mkfs_xfs > /dev/null 2>&1
30 _scratch_mount
31
32 file=$SCRATCH_MNT/file
33 touch $file
34 inum=`ls -i $file | awk '{print $1}'`
35 echo "inum=$inum"
36
37 _filter()
38 {
39     sed -e "s#$tmp#TMP#g"
40 }
41
42 add_eas()
43 {
44     start=$1
45     end=$2
46     echo ""; echo "** add $start..$end EAs **"
47     i=$start
48     while [ $i -le $end ]; do 
49         ${ATTR_PROG} -s name.$i -V value $file >/dev/null
50         let i=$i+1
51     done
52 }
53
54 rm_eas()
55 {
56     start=$1
57     end=$2
58     echo ""; echo "** rm $start..$end EAs **"
59     i=$start
60     while [ $i -le $end ]; do 
61         ${ATTR_PROG} -r name.$i $file >/dev/null
62         let i=$i+1
63     done
64 }
65
66 do_extents()
67 {
68     num=$1
69     echo ""; echo "** $num extents **"
70     $here/src/makeextents -v -p -w -n $num $file
71 }
72
73 _print_inode()
74 {
75     _scratch_unmount
76     _scratch_xfs_db -r -c "inode $inum" -c "print"  |\
77     awk '
78         /nextents/ { print; next }
79         /naextents/ { print; next }
80         /u\./ { print; next }
81         /a\./ { print; next }
82         /forkoff/ { printf("core.forkoff = %d (%d bytes)\n", $3, $3*8); next }
83         /format/ { print; next }
84         /size/ { print; next }
85     '
86     _scratch_mount
87 }
88
89 _print_inode_u()
90 {
91     _scratch_unmount
92     _scratch_xfs_db -r -c "inode $inum" -c "print u"
93     _scratch_mount
94 }
95
96 _print_inode_a()
97 {
98     _scratch_unmount
99     _scratch_xfs_db -r -c "inode $inum" -c "print a"
100     _scratch_mount
101 }
102
103 _test_add_eas()
104 {
105         _print_inode
106
107         add_eas 1 1
108         _print_inode
109
110         add_eas 2 2
111         _print_inode
112
113         add_eas 3 4
114         _print_inode
115
116         add_eas 5 8
117         _print_inode
118
119         add_eas 9 16
120         _print_inode
121
122         add_eas 17 20
123         _print_inode
124
125         add_eas 21 21
126         _print_inode
127
128         add_eas 22 22
129         _print_inode
130
131         add_eas 23 23
132         _print_inode
133
134         add_eas 24 24
135         _print_inode
136
137         add_eas 25 25
138         _print_inode
139
140         add_eas 26 30
141         _print_inode
142
143         add_eas 31 35
144         _print_inode
145
146         rm_eas 1 34
147         _print_inode
148 }
149
150 _test_add_extents()
151 {
152         # now do the extents
153
154         #build up
155         j=1
156         while [ $j -le 30 ]; do
157             do_extents $j
158             _print_inode
159             let j=$j+2
160         done
161
162         #scale down
163         j=30
164         while [ $j -ge 1 ]; do
165             do_extents $j
166             _print_inode
167             let j=$j-2
168         done
169
170         #build up
171         j=1
172         while [ $j -le 30 ]; do
173             do_extents $j
174             _print_inode
175             let j=$j+2
176         done
177 }
178
179 #
180 # Using a nested loop,
181 # for various number of data extents,
182 # try adding EAs and then removing EAs
183 # Check that when we play with the EAs that we don't mess with the extents
184 #
185 _test_extents_eas()
186 {
187         # now do the EAs with the extents
188
189         extents_max=400
190         extents_inc=10
191         EAs_max=100
192         EAs_inc=5
193         for i in `seq 1 $extents_inc $extents_max`; do
194             do_extents $i
195             echo "--- extents: $i ---"
196             _print_inode
197             _print_inode_u > $tmp.u1
198             for j in `seq 1 $EAs_inc $EAs_max`; do
199                 let k=$k+$EAs_inc-1
200                 add_eas $j $k
201             done
202             # should have same extents
203             _print_inode
204             _print_inode_u > $tmp.u2
205             rm_eas 1 $EAs_max
206             _print_inode_u > $tmp.u3
207
208             echo ""
209             echo "*** Extent differences before and after EAs added ***"
210             diff -s $tmp.u1 $tmp.u2 | _filter
211             echo ""
212             if ! diff $tmp.u1 $tmp.u2 >/dev/null; then 
213                 echo "Data extents magically changed"
214                 exit
215             fi
216
217             echo ""
218             echo "*** Extent differences before and after EAs removed ***"
219             diff -s $tmp.u2 $tmp.u3 | _filter
220             echo ""
221             if ! diff $tmp.u2 $tmp.u3 >/dev/null; then 
222                 echo "Data extents magically changed"
223                 exit
224             fi
225         done
226 }
227
228 #
229 # The counterpart of _test_extents_eas
230 # with the nested loops reversed.
231 # For various number of EAs, try adding extents
232 # Check that when we play with the data extents that we don't mess with the EAs
233 #
234 _test_eas_extents()
235 {
236         # now do the EAs with the extents
237
238         extents_max=400
239         extents_inc=10
240         EAs_max=100
241         EAs_inc=5
242         for j in `seq 1 $EAs_inc $EAs_max`; do
243
244             let k=$k+$EAs_inc-1
245             add_eas $j $k
246             echo "--- EAs: $j ---"
247
248             _print_inode
249             _print_inode_a > $tmp.a1
250             for i in `seq 1 $extents_inc $extents_max`; do
251                 do_extents $i
252             done
253
254             # should have same EAs
255             _print_inode
256             _print_inode_a > $tmp.a2
257             >$file 
258             _print_inode_a > $tmp.a3
259
260             echo ""
261             echo "*** EA differences before and after extents added ***"
262             diff -s $tmp.a1 $tmp.a2 | _filter
263             echo ""
264             if ! diff $tmp.a1 $tmp.a2 >/dev/null; then 
265                 echo "EAs magically changed"
266                 exit
267             fi
268
269             echo ""
270             echo "*** EA differences before and after extents removed ***"
271             diff -s $tmp.a2 $tmp.a3 | _filter
272             echo ""
273             if ! diff $tmp.a2 $tmp.a3 >/dev/null; then 
274                 echo "EAs magically changed"
275                 exit
276             fi
277         done
278 }
279
280 #
281 # test to see how we go 
282
283 #
284 # test to ensure it fits a max sf EA
285 #
286 # literal part of inode starts at offset 100 (decimal)
287 # for 512 bytes inode that gives 412 bytes of literal area
288 #
289 # min btree root (numrecs=3) => 3 * 16 + (4 or 8)
290 # for 8 byte alignment => 56 bytes
291 # => 512 - 156 = 356 bytes 
292 #
293 # SF EA of form
294 #   totsize: 2 bytes
295 #   count:   1 byte
296 #   nlen:    1 byte
297 #   vlen:    1 byte
298 #   flags:   1 byte
299 #   name:    nlen
300 #   value:   vlen
301 #
302 # => 6+nlen+vlen
303 #
304 # for nlen=4 "name"
305 # vlen = 356 - (6+4) = 346
306
307 #
308 _test_initial_sf_ea()
309 {
310         rm $file
311         touch $file
312         vlen=402
313         vlen=300
314         dd if=/dev/zero bs=1 count=$vlen | ${ATTR_PROG} -s name $file
315         _print_inode
316 }
317
318 # main
319
320 _test_add_eas
321 _test_add_extents
322 _test_extents_eas
323 _test_eas_extents
324 #_test_initial_sf_ea
325
326 # do a test with a variety of sized EAs
327
328 # success, all done
329 status=0
330 exit