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