fstests: Don't use gawk's strtonum
[xfstests-dev.git] / common / punch
1 ##/bin/bash
2 # SPDX-License-Identifier: GPL-2.0
3 # Copyright (c) 2007 Silicon Graphics, Inc.  All Rights Reserved.
4 #
5 # common functions for excersizing hole punches with extent size hints etc.
6
7 # source dmap_scratch_mount etc.
8 . ./common/dmapi
9
10 _spawn_test_file() {
11         echo "# spawning test file with $*"
12         local blksize=$1
13         local file_size=`expr $2 \* $blksize`
14         local extent_size_hint=`expr $3 \* $blksize`
15         local test_file=$4
16         local reserve_space=$5
17
18         if [ $extent_size_hint -ne 0 ]; then
19                 echo "+ setting extent size hint to $extent_size_hint"
20                 $XFS_IO_PROG -f \
21                 -c "extsize $extent_size_hint" \
22                 $test_file
23         fi
24         # print extent size hint for $test_file
25         $XFS_IO_PROG -f \
26         -c "extsize" \
27         $test_file
28
29         if [ "$reserve_space" == "noresv" ]; then
30                 echo "+ not using resvsp at file creation"
31                 $XFS_IO_PROG -f \
32                 -c "truncate $file_size" \
33                 $test_file
34         else
35                 $XFS_IO_PROG -f \
36                 -c "truncate $file_size" \
37                 -c "resvsp 0 $file_size" \
38                 $test_file
39         fi
40 }
41
42 _do_punch() {
43         echo "# punching with $*"
44         # punch or bite the ear off $test_file to create a hole
45         local blksize=$1
46         local punch_offset=`expr $2 \* $blksize`
47         local punch_size=`expr $3 \* $blksize`
48         local punch_type=$4             # u for unresvsp, d for dm_punch
49         local test_file=$5
50
51         if [ "$punch_type" == "u" ]; then
52                 echo "+ hole punch using unresvsp"
53                 $XFS_IO_PROG -f \
54                 -c "unresvsp $punch_offset $punch_size" \
55                 $test_file
56         fi
57         if [ "$punch_type" == "d" ]; then
58                 echo "+ hole punch using dmapi punch_hole"
59                 ${DMAPI_QASUITE1_DIR}cmd/punch_hole -o $punch_offset -l $punch_size \
60                         ${SCRATCH_MNT}/$test_file
61         fi
62 }
63
64 _do_write() {
65         echo "# writing with $*"
66         local blksize=$1
67         local write_offset=`expr $2 \* $blksize`
68         local write_size=`expr $3 \* $blksize`
69         local test_file=$4
70
71         $XFS_IO_PROG -f \
72         -c "pwrite $write_offset $write_size" \
73         $test_file >/dev/null
74 }
75
76 _do_bmap() {
77         echo "# showing file state $*"
78         local test_file=$1
79
80         $XFS_IO_PROG -f \
81         -c "bmap -vvp" \
82         $test_file
83 }
84
85 _test_punch() {
86         echo "# testing $* ..."
87         local blksize=$1
88         # all points and sizes below are in terms of filesystem blocks
89         local extsize_hint_blks=$2              # extent size hint in FS blocks, 0=do not set
90         local file_size_blks=$3                 # the file size in blocks
91         local punch_points_blks=( $4 )  # array of places to punch holes in the file
92         local punch_sizes_blks=( $5 )   # array of size of each punch in blocks
93         local punch_types=( $6  )               # array of u=unresvsp or d=dm_punch
94         local write_points_blks=( $7 )  # array of places to pwrite in the file
95         local write_sizes_blks=( $8 )   # array of size of each write
96
97         local punch_write_order=( $9 )  # array of punch/write operation order
98                                                                         # e.g. "w p w w p" means: do 1st write...
99                                                                         # then 1st punch, 2nd & 3rd write, 2nd punch
100         local resvsp=${10}                              # if "noresv" then don't resvsp on file create
101         local filename=punch_test_file
102
103         cd /
104         _scratch_unmount >/dev/null 2>&1
105
106         _scratch_mkfs_xfs -bsize=$blksize >/dev/null 2>&1 \
107                 || _fail "mkfs failed"
108
109         local this_punch_type=""
110         local dmap_punch_used=0
111         for this_punch_type in "${punch_types[@]}"; do
112                 [ "$this_punch_type" == "d" ] && dmap_punch_used=1
113         done
114         if [ $dmap_punch_used -ne 0 ]; then
115                 # a punch type of dm_punch has been specified, do a dmapi mount
116                 echo "+ mounting with dmapi enabled"
117                 _dmapi_scratch_mount
118         else
119                 # only unresvsp punch type is used, just do a normal mount
120                 _scratch_mount
121         fi
122
123         cd $SCRATCH_MNT
124
125         # check a size is specified for each punch
126         [ ${#punch_points_blks[*]} -eq ${#punch_sizes_blks[*]} ] \
127                 || _fail "num punch points given does not equal num punch sizes"
128
129         # check a type is specified for each punch
130         [ ${#punch_points_blks[*]} -eq ${#punch_types[*]} ] \
131                 || _fail "num punch points given does not equal num punch types"
132
133         # check a size is specified for each write
134         [ ${#write_points_blks[*]} -eq ${#write_sizes_blks[*]} ] \
135                 || _fail "num write points given does not equal num write sizes"
136
137         # check punch_write_order operations match number of punches + writes
138         local total_pw_operations=`expr ${#punch_points_blks[*]} + ${#write_points_blks[*]}`
139         [ $total_pw_operations -eq ${#punch_write_order[*]} ] \
140                 || _fail "punch_write_order ops doesn't match number of punches + writes"
141
142         # create the file and setup extent size hint
143         _spawn_test_file $blksize $file_size_blks $extsize_hint_blks $filename $resvsp
144
145         # do the writes and punches
146         local operation=""
147         local punch_index=0
148         local write_index=0
149         for operation in "${punch_write_order[@]}"; do
150                 if [ "$operation" == "p" ]; then
151                         _do_punch $blksize ${punch_points_blks[$punch_index]} \
152                                 ${punch_sizes_blks[$punch_index]} ${punch_types[$punch_index]} \
153                                 $filename
154                         punch_index=`expr $punch_index + 1`
155                 fi
156                 if [ "$operation" == "w" ]; then
157                         _do_write $blksize ${write_points_blks[$write_index]} \
158                                 ${write_sizes_blks[$write_index]} $filename
159                         write_index=`expr $write_index + 1`
160                 fi
161                 sync
162                 _do_bmap $filename              # print out the state of the file
163         done
164 }
165
166 _coalesce_extents()
167 {
168         block_size=$1
169
170         [[ -z $block_size ]] && block_size=512
171
172         awk -v block_size="$block_size" -F: '
173         {
174                 range = $2;
175                 type = $3;
176
177                 split(range, bounds, "[\\[ \\.\\]]");
178                 low = bounds[3];
179                 high = bounds[5];
180
181                 if (type != prev_type) {
182                         if (prev_type != "")
183                                 printf("%u]:%s\n", (low * 512 / block_size) - 1,
184                                         prev_type);
185                         printf("%u: [%u..", out_count++,
186                                 (low * 512) / block_size);
187                         prev_type = type;
188                 }
189         }
190         END {
191                 if (prev_type != "")
192                         printf("%u]:%s\n", ((high + 1) * 512 / block_size) - 1,
193                                 prev_type);
194         }'
195 }
196
197 _filter_fiemap()
198 {
199         block_size=$1
200
201         $AWK_PROG '
202                 $3 ~ /hole/ {
203                         print $1, $2, $3;
204                         next;
205                 }
206                 $5 ~ /0x[[:xdigit:]]*8[[:xdigit:]][[:xdigit:]]/ {
207                         print $1, $2, "unwritten";
208                         next;
209                 }
210                 $5 ~ /0x[[:xdigit:]]+/ {
211                         print $1, $2, "data";
212                 }' |
213         _coalesce_extents $block_size
214 }
215
216 _filter_fiemap_flags()
217 {
218         $AWK_PROG '
219                 $3 ~ /hole/ {
220                         print $1, $2, $3;
221                         next;
222                 }
223                 $5 ~ /0x[[:xdigit:]]*8[[:xdigit:]][[:xdigit:]]/ {
224                         print $1, $2, "unwritten";
225                         next;
226                 }
227                 $5 ~ /0x[[:xdigit:]]+/ {
228                         print $1, $2, $5;
229                 }' |
230         _coalesce_extents
231 }
232
233 # Filters fiemap output to only print the 
234 # file offset column and whether or not
235 # it is an extent or a hole
236 _filter_hole_fiemap()
237 {
238         $AWK_PROG '
239                 $3 ~ /hole/ {
240                         print $1, $2, $3; 
241                         next;
242                 }   
243                 $5 ~ /0x[[:xdigit:]]+/ {
244                         print $1, $2, "extent";
245                 }' |
246         _coalesce_extents
247 }
248
249 #     10000 Unwritten preallocated extent
250 #     01000 Doesn't begin on stripe unit
251 #     00100 Doesn't end   on stripe unit
252 #     00010 Doesn't begin on stripe width
253 #     00001 Doesn't end   on stripe width
254 _filter_bmap()
255 {
256         awk '
257                 $3 ~ /hole/ {
258                         print $1, $2, $3;
259                         next;
260                 }
261                 $7 ~ /1[01][01][01][01]/ {
262                         print $1, $2, "unwritten";
263                         next;
264                 }
265                 $7 ~ /0[01][01][01][01]/ {
266                         print $1, $2, "data"
267                 }' |
268         _coalesce_extents
269 }
270
271 die_now()
272 {
273         status=1
274         exit
275 }
276
277 # test the different corner cases for zeroing a range:
278 #
279 #       1. into a hole
280 #       2. into allocated space
281 #       3. into unwritten space
282 #       4. hole -> data
283 #       5. hole -> unwritten
284 #       6. data -> hole
285 #       7. data -> unwritten
286 #       8. unwritten -> hole
287 #       9. unwritten -> data
288 #       10. hole -> data -> hole
289 #       11. data -> hole -> data
290 #       12. unwritten -> data -> unwritten
291 #       13. data -> unwritten -> data
292 #       14. data -> hole @ EOF
293 #       15. data -> hole @ 0
294 #       16. data -> cache cold ->hole
295 #       17. data -> hole in single block file
296 #
297 # Test file is removed, created and sync'd between tests.
298 #
299 # Use -k flag to keep the file between tests.  This will
300 # test the handling of pre-existing holes.
301 #
302 # Use the -d flag to not sync the file between tests.
303 # This will test the handling of delayed extents
304 #
305 # Use the -u flag to not run unwritten tests.
306 # This will eliminate some unnecessary information.
307 #
308 _test_generic_punch()
309 {
310
311         remove_testfile=1
312         sync_cmd="-c fsync"
313         unwritten_tests=1
314         OPTIND=1
315         while getopts 'dku' OPTION
316         do
317                 case $OPTION in
318                 k)      remove_testfile=
319                 ;;
320                 d)      sync_cmd=
321                 ;;
322                 u)      unwritten_tests=
323                 ;;
324                 ?)      echo Invalid flag
325                 exit 1
326                 ;;
327                 esac
328         done
329         shift $(($OPTIND - 1))
330
331         alloc_cmd=$1
332         punch_cmd=$2
333         zero_cmd=$3     #if not testing zero just set to punch
334         map_cmd=$4
335         filter_cmd=$5
336         testfile=$6
337
338         # The punch hole tests needs multiple of the largest extent size being
339         # tested, with multiple=16 it can test extent size upto 64k.
340         multiple=16
341         _4k="$((multiple * 4))k"
342         _8k="$((multiple * 8))k"
343         _12k="$((multiple * 12))k"
344         _20k="$((multiple * 20))k"
345
346         # initial test state must be defined, otherwise the first test can fail
347         # due ot stale file state left from previous tests.
348         rm -f $testfile
349
350         echo "  1. into a hole"
351         $XFS_IO_PROG -f -c "truncate $_20k" \
352                 -c "$zero_cmd $_4k $_8k" \
353                 -c "$map_cmd -v" $testfile | $filter_cmd
354         [ $? -ne 0 ] && die_now
355         _md5_checksum $testfile
356
357         echo "  2. into allocated space"
358         if [ "$remove_testfile" ]; then
359                 rm -f $testfile
360         fi
361         $XFS_IO_PROG -f -c "truncate $_20k" \
362                 -c "pwrite 0 $_20k" $sync_cmd \
363                 -c "$zero_cmd $_4k $_8k" \
364                 -c "$map_cmd -v" $testfile | $filter_cmd
365         [ $? -ne 0 ] && die_now
366         _md5_checksum $testfile
367
368         if [ "$unwritten_tests" ]; then
369                 echo "  3. into unwritten space"
370                 if [ "$remove_testfile" ]; then
371                         rm -f $testfile
372                 fi
373                 $XFS_IO_PROG -f -c "truncate $_20k" \
374                         -c "$alloc_cmd 0 $_20k" \
375                         -c "$zero_cmd $_4k $_8k" \
376                         -c "$map_cmd -v" $testfile | $filter_cmd
377                 [ $? -ne 0 ] && die_now
378                 _md5_checksum $testfile
379         fi
380
381         echo "  4. hole -> data"
382         if [ "$remove_testfile" ]; then
383                 rm -f $testfile
384         fi
385         $XFS_IO_PROG -f -c "truncate $_20k" \
386                 -c "pwrite $_8k $_8k" $sync_cmd \
387                 -c "$zero_cmd $_4k $_8k" \
388                 -c "$map_cmd -v" $testfile | $filter_cmd
389         [ $? -ne 0 ] && die_now
390         _md5_checksum $testfile
391
392         if [ "$unwritten_tests" ]; then
393                 echo "  5. hole -> unwritten"
394                 if [ "$remove_testfile" ]; then
395                         rm -f $testfile
396                 fi
397                 $XFS_IO_PROG -f -c "truncate $_20k" \
398                         -c "$alloc_cmd $_8k $_8k" \
399                         -c "$zero_cmd $_4k $_8k" \
400                         -c "$map_cmd -v" $testfile | $filter_cmd
401                 [ $? -ne 0 ] && die_now
402                 _md5_checksum $testfile
403         fi
404
405         echo "  6. data -> hole"
406         if [ "$remove_testfile" ]; then
407                 rm -f $testfile
408         fi
409         $XFS_IO_PROG -f -c "truncate $_20k" \
410                 -c "pwrite 0 $_8k" $sync_cmd \
411                  -c "$zero_cmd $_4k $_8k" \
412                 -c "$map_cmd -v" $testfile | $filter_cmd
413         [ $? -ne 0 ] && die_now
414         _md5_checksum $testfile
415
416         if [ "$unwritten_tests" ]; then
417                 echo "  7. data -> unwritten"
418                 if [ "$remove_testfile" ]; then
419                         rm -f $testfile
420                 fi
421                 $XFS_IO_PROG -f -c "truncate $_20k" \
422                         -c "pwrite 0 $_8k" $sync_cmd \
423                         -c "$alloc_cmd $_8k $_8k" \
424                         -c "$zero_cmd $_4k $_8k" \
425                         -c "$map_cmd -v" $testfile | $filter_cmd
426                 [ $? -ne 0 ] && die_now
427                 _md5_checksum $testfile
428
429                 echo "  8. unwritten -> hole"
430                 if [ "$remove_testfile" ]; then
431                         rm -f $testfile
432                 fi
433                 $XFS_IO_PROG -f -c "truncate $_20k" \
434                         -c "$alloc_cmd 0 $_8k" \
435                         -c "$zero_cmd $_4k $_8k" \
436                         -c "$map_cmd -v" $testfile | $filter_cmd
437                 [ $? -ne 0 ] && die_now
438                 _md5_checksum $testfile
439
440                 echo "  9. unwritten -> data"
441                 if [ "$remove_testfile" ]; then
442                         rm -f $testfile
443                 fi
444                 $XFS_IO_PROG -f -c "truncate $_20k" \
445                         -c "$alloc_cmd 0 $_8k" \
446                         -c "pwrite $_8k $_8k" $sync_cmd \
447                         -c "$zero_cmd $_4k $_8k" \
448                         -c "$map_cmd -v" $testfile | $filter_cmd
449                 [ $? -ne 0 ] && die_now
450                 _md5_checksum $testfile
451         fi
452
453         echo "  10. hole -> data -> hole"
454         if [ "$remove_testfile" ]; then
455                 rm -f $testfile
456         fi
457         $XFS_IO_PROG -f -c "truncate $_20k" \
458                 -c "pwrite $_8k $_4k" $sync_cmd \
459                 -c "$zero_cmd $_4k $_12k" \
460                 -c "$map_cmd -v" $testfile | $filter_cmd
461         [ $? -ne 0 ] && die_now
462         _md5_checksum $testfile
463
464         echo "  11. data -> hole -> data"
465         if [ "$remove_testfile" ]; then
466                 rm -f $testfile
467         fi
468         $XFS_IO_PROG -f -c "truncate $_20k" \
469                 -c "$alloc_cmd 0 $_20k" \
470                 -c "pwrite 0 $_8k" \
471                 -c "pwrite $_12k $_8k" $sync_cmd \
472                 -c "$punch_cmd $_8k $_4k" \
473                 -c "$zero_cmd $_4k $_12k" \
474                 -c "$map_cmd -v" $testfile | $filter_cmd
475         [ $? -ne 0 ] && die_now
476         _md5_checksum $testfile
477
478         if [ "$unwritten_tests" ]; then
479                 echo "  12. unwritten -> data -> unwritten"
480                 if [ "$remove_testfile" ]; then
481                         rm -f $testfile
482                 fi
483                 $XFS_IO_PROG -f -c "truncate $_20k" \
484                         -c "$alloc_cmd 0 $_20k" \
485                         -c "pwrite $_8k $_4k" $sync_cmd \
486                         -c "$zero_cmd $_4k $_12k" \
487                         -c "$map_cmd -v" $testfile | $filter_cmd
488                 [ $? -ne 0 ] && die_now
489                 _md5_checksum $testfile
490
491                 echo "  13. data -> unwritten -> data"
492                 if [ "$remove_testfile" ]; then
493                         rm -f $testfile
494                 fi
495                 $XFS_IO_PROG -f -c "truncate $_20k" \
496                         -c "$alloc_cmd 0 $_20k" \
497                         -c "pwrite 0k $_4k" $sync_cmd \
498                         -c "pwrite $_12k $_8k" -c "fsync" \
499                         -c "$zero_cmd $_4k $_12k" \
500                         -c "$map_cmd -v" $testfile | $filter_cmd
501                 [ $? -ne 0 ] && die_now
502                 _md5_checksum $testfile
503         fi
504
505         # Don't need to check EOF case for collapse range.
506         # VFS layer return invalid error in this case,
507         # So it is not a proper case for collapse range test of each local fs.
508         if [ "$zero_cmd" != "fcollapse" ]; then
509                 echo "  14. data -> hole @ EOF"
510                 rm -f $testfile
511                 $XFS_IO_PROG -f -c "truncate $_20k" \
512                         -c "pwrite 0 $_20k" $sync_cmd \
513                         -c "$zero_cmd $_12k $_8k" \
514                         -c "$map_cmd -v" $testfile | $filter_cmd
515                 [ $? -ne 0 ] && die_now
516                 _md5_checksum $testfile
517         fi
518
519         if [ "$zero_cmd" == "fcollapse" ]; then
520                 echo "  14. data -> hole @ 0"
521         else
522                 echo "  15. data -> hole @ 0"
523         fi
524
525         if [ "$remove_testfile" ]; then
526                 rm -f $testfile
527         fi
528         $XFS_IO_PROG -f -c "truncate $_20k" \
529                 -c "pwrite 0 $_20k" $sync_cmd \
530                 -c "$zero_cmd 0 $_8k" \
531                 -c "$map_cmd -v" $testfile | $filter_cmd
532         [ $? -ne 0 ] && die_now
533         _md5_checksum $testfile
534
535         # If zero_cmd is fcollpase, don't check unaligned offsets
536         if [ "$zero_cmd" == "fcollapse" ]; then
537                 return
538         fi
539
540         # If zero_cmd is finsert, don't check unaligned offsets
541         if [ "$zero_cmd" == "finsert" ]; then
542                 return
543         fi
544
545         echo "  16. data -> cache cold ->hole"
546         if [ "$remove_testfile" ]; then
547                 rm -f $testfile
548                 rm -f $testfile.2
549         else
550                 cp $testfile $testfile.2
551         fi
552         $XFS_IO_PROG -f -c "truncate $_20k" \
553                 -c "pwrite $_8k $_12k" -c "fsync" $testfile.2 \
554                 > /dev/null
555         $XFS_IO_PROG -f -c "truncate $_20k" \
556                 -c "pwrite 0 $_20k" $sync_cmd \
557                 -c "$zero_cmd 0k $_8k" \
558                 -c "fadvise -d" \
559                 -c "$map_cmd -v" $testfile | $filter_cmd
560         diff $testfile $testfile.2
561         [ $? -ne 0 ] && die_now
562         rm -f $testfile.2
563         _md5_checksum $testfile
564
565         # different file sizes mean we can't use md5sum to check the hole is
566         # valid. Hence use hexdump to dump the contents and chop off the last
567         # line of output that indicates the file size. We also have to fudge
568         # the extent size as that will change with file size, too - that's what
569         # the sed line noise does - it will always result in an output of [0..7]
570         # so it matches 4k block size...
571         echo "  17. data -> hole in single block file"
572         if [ "$remove_testfile" ]; then
573                 rm -f $testfile
574         fi
575         block_size=`_get_block_size $TEST_DIR`
576         $XFS_IO_PROG -f -c "truncate $block_size" \
577                 -c "pwrite 0 $block_size" $sync_cmd \
578                 -c "$zero_cmd 128 128" \
579                 -c "$map_cmd -v" $testfile | $filter_cmd | \
580                          sed -e "s/\.\.[0-9]*\]/..7\]/"
581         [ $? -ne 0 ] && die_now
582         od -x $testfile | head -n -1
583 }
584
585 _test_block_boundaries()
586 {
587
588         remove_testfile=1
589         sync_cmd="-c fsync"
590         unwritten_tests=1
591         OPTIND=1
592         while getopts 'dk' OPTION
593         do
594                 case $OPTION in
595                 k)      remove_testfile=
596                 ;;
597                 d)      sync_cmd=
598                 ;;
599                 ?)      echo Invalid flag
600                 exit 1
601                 ;;
602                 esac
603         done
604         shift $(($OPTIND - 1))
605
606         bs=$1
607         zero_cmd=$2
608         filter_cmd=$3
609         testfile=$4
610
611         # Block size plus 1
612         bs_p1=$(($bs + 1))
613         # Block size plus 2
614         bs_p2=$(($bs + 2))
615
616         # Block size minus 1
617         bs_m1=$(($bs - 1))
618
619         # Block size multiplied by 2
620         bs_t2=$(($bs * 2))
621
622         # Block size divided by 2
623         bs_d2=$(($bs / 2))
624
625         echo "zero 0, 1"
626         $XFS_IO_PROG -f -t -c "pwrite -S 0x41 0 $bs" \
627                            -c "pwrite -S 0x42 $bs $bs" \
628                            -c "$zero_cmd 0 1" \
629                            -c "pread -v 0 $bs_t2" \
630                            $testfile | $filter_cmd
631
632         echo "zero 0, $bs_m1"
633         $XFS_IO_PROG -f -t -c "pwrite -S 0x41 0 $bs" \
634                            -c "pwrite -S 0x42 $bs $bs" \
635                            -c "$zero_cmd 0 $bs_m1" \
636                            -c "pread -v 0 $bs_t2" \
637                            $testfile | $filter_cmd
638
639         echo "zero 0, $bs"
640         $XFS_IO_PROG -f -t -c "pwrite -S 0x41 0 $bs" \
641                            -c "pwrite -S 0x42 $bs $bs" \
642                            -c "$zero_cmd 0 $bs" \
643                            -c "pread -v 0 $bs_t2" \
644                            $testfile | $filter_cmd
645
646         echo "zero 0, $bs_p1"
647         $XFS_IO_PROG -f -t -c "pwrite -S 0x41 0 $bs" \
648                            -c "pwrite -S 0x42 $bs $bs" \
649                            -c "$zero_cmd 0 $bs_p1" \
650                            -c "pread -v 0 $bs_t2" \
651                            $testfile | $filter_cmd
652
653         echo "zero $bs_m1, $bs"
654         $XFS_IO_PROG -f -t -c "pwrite -S 0x41 0 $bs" \
655                            -c "pwrite -S 0x42 $bs $bs" \
656                            -c "$zero_cmd $bs_m1 $bs" \
657                            -c "pread -v 0 $bs_t2" \
658                            $testfile | $filter_cmd
659
660         echo "zero $bs_m1, $bs_p1"
661         $XFS_IO_PROG -f -t -c "pwrite -S 0x41 0 $bs" \
662                            -c "pwrite -S 0x42 $bs $bs" \
663                            -c "$zero_cmd $bs_m1 $bs_p1" \
664                            -c "pread -v 0 $bs_t2" \
665                            $testfile | $filter_cmd
666
667         echo "zero $bs_m1, $bs_p2"
668         $XFS_IO_PROG -f -t -c "pwrite -S 0x41 0 $bs" \
669                            -c "pwrite -S 0x42 $bs $bs" \
670                            -c "$zero_cmd $bs_m1 $bs_p2" \
671                            -c "pread -v 0 $bs_t2" \
672                            $testfile | $filter_cmd
673
674
675         echo "zero $bs, $bs"
676         $XFS_IO_PROG -f -t -c "pwrite -S 0x41 0 $bs" \
677                            -c "pwrite -S 0x42 $bs $bs" \
678                            -c "$zero_cmd $bs $bs" \
679                            -c "pread -v 0 $bs_t2" \
680                            $testfile | $filter_cmd
681
682
683         echo "zero $bs_d2 , $bs"
684         $XFS_IO_PROG -f -t -c "pwrite -S 0x41 0 $bs" \
685                            -c "pwrite -S 0x42 $bs $bs" \
686                            -c "$zero_cmd $bs_d2 $bs" \
687                            -c "pread -v 0 $bs_t2" \
688                            $testfile | $filter_cmd
689 }