mirror of
https://github.com/linux-apfs/apfstests.git
synced 2026-05-01 15:01:44 -07:00
4ba5b50735
When testing FS instances of block size other than 4k, the output of fiemap command will not match those in *.out files. This commit adds an optional "block size" argument to _filter_fiemap() which prints fiemap output in units of block size. Signed-off-by: Chandan Rajendra <chandan@linux.vnet.ibm.com> Tested-by: Zorro Lang <zlang@redhat.com> Signed-off-by: Eryu Guan <guaneryu@gmail.com>
690 lines
17 KiB
Plaintext
690 lines
17 KiB
Plaintext
##/bin/bash
|
|
# SPDX-License-Identifier: GPL-2.0
|
|
# Copyright (c) 2007 Silicon Graphics, Inc. All Rights Reserved.
|
|
#
|
|
# common functions for excersizing hole punches with extent size hints etc.
|
|
|
|
# source dmap_scratch_mount etc.
|
|
. ./common/dmapi
|
|
|
|
_spawn_test_file() {
|
|
echo "# spawning test file with $*"
|
|
local blksize=$1
|
|
local file_size=`expr $2 \* $blksize`
|
|
local extent_size_hint=`expr $3 \* $blksize`
|
|
local test_file=$4
|
|
local reserve_space=$5
|
|
|
|
if [ $extent_size_hint -ne 0 ]; then
|
|
echo "+ setting extent size hint to $extent_size_hint"
|
|
$XFS_IO_PROG -f \
|
|
-c "extsize $extent_size_hint" \
|
|
$test_file
|
|
fi
|
|
# print extent size hint for $test_file
|
|
$XFS_IO_PROG -f \
|
|
-c "extsize" \
|
|
$test_file
|
|
|
|
if [ "$reserve_space" == "noresv" ]; then
|
|
echo "+ not using resvsp at file creation"
|
|
$XFS_IO_PROG -f \
|
|
-c "truncate $file_size" \
|
|
$test_file
|
|
else
|
|
$XFS_IO_PROG -f \
|
|
-c "truncate $file_size" \
|
|
-c "resvsp 0 $file_size" \
|
|
$test_file
|
|
fi
|
|
}
|
|
|
|
_do_punch() {
|
|
echo "# punching with $*"
|
|
# punch or bite the ear off $test_file to create a hole
|
|
local blksize=$1
|
|
local punch_offset=`expr $2 \* $blksize`
|
|
local punch_size=`expr $3 \* $blksize`
|
|
local punch_type=$4 # u for unresvsp, d for dm_punch
|
|
local test_file=$5
|
|
|
|
if [ "$punch_type" == "u" ]; then
|
|
echo "+ hole punch using unresvsp"
|
|
$XFS_IO_PROG -f \
|
|
-c "unresvsp $punch_offset $punch_size" \
|
|
$test_file
|
|
fi
|
|
if [ "$punch_type" == "d" ]; then
|
|
echo "+ hole punch using dmapi punch_hole"
|
|
${DMAPI_QASUITE1_DIR}cmd/punch_hole -o $punch_offset -l $punch_size \
|
|
${SCRATCH_MNT}/$test_file
|
|
fi
|
|
}
|
|
|
|
_do_write() {
|
|
echo "# writing with $*"
|
|
local blksize=$1
|
|
local write_offset=`expr $2 \* $blksize`
|
|
local write_size=`expr $3 \* $blksize`
|
|
local test_file=$4
|
|
|
|
$XFS_IO_PROG -f \
|
|
-c "pwrite $write_offset $write_size" \
|
|
$test_file >/dev/null
|
|
}
|
|
|
|
_do_bmap() {
|
|
echo "# showing file state $*"
|
|
local test_file=$1
|
|
|
|
$XFS_IO_PROG -f \
|
|
-c "bmap -vvp" \
|
|
$test_file
|
|
}
|
|
|
|
_test_punch() {
|
|
echo "# testing $* ..."
|
|
local blksize=$1
|
|
# all points and sizes below are in terms of filesystem blocks
|
|
local extsize_hint_blks=$2 # extent size hint in FS blocks, 0=do not set
|
|
local file_size_blks=$3 # the file size in blocks
|
|
local punch_points_blks=( $4 ) # array of places to punch holes in the file
|
|
local punch_sizes_blks=( $5 ) # array of size of each punch in blocks
|
|
local punch_types=( $6 ) # array of u=unresvsp or d=dm_punch
|
|
local write_points_blks=( $7 ) # array of places to pwrite in the file
|
|
local write_sizes_blks=( $8 ) # array of size of each write
|
|
|
|
local punch_write_order=( $9 ) # array of punch/write operation order
|
|
# e.g. "w p w w p" means: do 1st write...
|
|
# then 1st punch, 2nd & 3rd write, 2nd punch
|
|
local resvsp=${10} # if "noresv" then don't resvsp on file create
|
|
local filename=punch_test_file
|
|
|
|
cd /
|
|
_scratch_unmount >/dev/null 2>&1
|
|
|
|
_scratch_mkfs_xfs -bsize=$blksize >/dev/null 2>&1 \
|
|
|| _fail "mkfs failed"
|
|
|
|
local this_punch_type=""
|
|
local dmap_punch_used=0
|
|
for this_punch_type in "${punch_types[@]}"; do
|
|
[ "$this_punch_type" == "d" ] && dmap_punch_used=1
|
|
done
|
|
if [ $dmap_punch_used -ne 0 ]; then
|
|
# a punch type of dm_punch has been specified, do a dmapi mount
|
|
echo "+ mounting with dmapi enabled"
|
|
_dmapi_scratch_mount
|
|
else
|
|
# only unresvsp punch type is used, just do a normal mount
|
|
_scratch_mount
|
|
fi
|
|
|
|
cd $SCRATCH_MNT
|
|
|
|
# check a size is specified for each punch
|
|
[ ${#punch_points_blks[*]} -eq ${#punch_sizes_blks[*]} ] \
|
|
|| _fail "num punch points given does not equal num punch sizes"
|
|
|
|
# check a type is specified for each punch
|
|
[ ${#punch_points_blks[*]} -eq ${#punch_types[*]} ] \
|
|
|| _fail "num punch points given does not equal num punch types"
|
|
|
|
# check a size is specified for each write
|
|
[ ${#write_points_blks[*]} -eq ${#write_sizes_blks[*]} ] \
|
|
|| _fail "num write points given does not equal num write sizes"
|
|
|
|
# check punch_write_order operations match number of punches + writes
|
|
local total_pw_operations=`expr ${#punch_points_blks[*]} + ${#write_points_blks[*]}`
|
|
[ $total_pw_operations -eq ${#punch_write_order[*]} ] \
|
|
|| _fail "punch_write_order ops doesn't match number of punches + writes"
|
|
|
|
# create the file and setup extent size hint
|
|
_spawn_test_file $blksize $file_size_blks $extsize_hint_blks $filename $resvsp
|
|
|
|
# do the writes and punches
|
|
local operation=""
|
|
local punch_index=0
|
|
local write_index=0
|
|
for operation in "${punch_write_order[@]}"; do
|
|
if [ "$operation" == "p" ]; then
|
|
_do_punch $blksize ${punch_points_blks[$punch_index]} \
|
|
${punch_sizes_blks[$punch_index]} ${punch_types[$punch_index]} \
|
|
$filename
|
|
punch_index=`expr $punch_index + 1`
|
|
fi
|
|
if [ "$operation" == "w" ]; then
|
|
_do_write $blksize ${write_points_blks[$write_index]} \
|
|
${write_sizes_blks[$write_index]} $filename
|
|
write_index=`expr $write_index + 1`
|
|
fi
|
|
sync
|
|
_do_bmap $filename # print out the state of the file
|
|
done
|
|
}
|
|
|
|
_coalesce_extents()
|
|
{
|
|
block_size=$1
|
|
|
|
[[ -z $block_size ]] && block_size=512
|
|
|
|
awk -v block_size="$block_size" -F: '
|
|
{
|
|
range = $2;
|
|
type = $3;
|
|
|
|
split(range, bounds, "[\\[ \\.\\]]");
|
|
low = bounds[3];
|
|
high = bounds[5];
|
|
|
|
if (type != prev_type) {
|
|
if (prev_type != "")
|
|
printf("%u]:%s\n", (low * 512 / block_size) - 1,
|
|
prev_type);
|
|
printf("%u: [%u..", out_count++,
|
|
(low * 512) / block_size);
|
|
prev_type = type;
|
|
}
|
|
}
|
|
END {
|
|
if (prev_type != "")
|
|
printf("%u]:%s\n", ((high + 1) * 512 / block_size) - 1,
|
|
prev_type);
|
|
}'
|
|
}
|
|
|
|
_filter_fiemap()
|
|
{
|
|
block_size=$1
|
|
|
|
$AWK_PROG '
|
|
$3 ~ /hole/ {
|
|
print $1, $2, $3;
|
|
next;
|
|
}
|
|
$5 ~ /0x[[:xdigit:]]*8[[:xdigit:]][[:xdigit:]]/ {
|
|
print $1, $2, "unwritten";
|
|
next;
|
|
}
|
|
$5 ~ /0x[[:xdigit:]]+/ {
|
|
print $1, $2, "data";
|
|
}' |
|
|
_coalesce_extents $block_size
|
|
}
|
|
|
|
_filter_fiemap_flags()
|
|
{
|
|
$AWK_PROG '
|
|
$3 ~ /hole/ {
|
|
print $1, $2, $3;
|
|
next;
|
|
}
|
|
$5 ~ /0x[[:xdigit:]]*8[[:xdigit:]][[:xdigit:]]/ {
|
|
print $1, $2, "unwritten";
|
|
next;
|
|
}
|
|
$5 ~ /0x[[:xdigit:]]+/ {
|
|
print $1, $2, $5;
|
|
}' |
|
|
_coalesce_extents
|
|
}
|
|
|
|
# Filters fiemap output to only print the
|
|
# file offset column and whether or not
|
|
# it is an extent or a hole
|
|
_filter_hole_fiemap()
|
|
{
|
|
$AWK_PROG '
|
|
$3 ~ /hole/ {
|
|
print $1, $2, $3;
|
|
next;
|
|
}
|
|
$5 ~ /0x[[:xdigit:]]+/ {
|
|
print $1, $2, "extent";
|
|
}' |
|
|
_coalesce_extents
|
|
}
|
|
|
|
# 10000 Unwritten preallocated extent
|
|
# 01000 Doesn't begin on stripe unit
|
|
# 00100 Doesn't end on stripe unit
|
|
# 00010 Doesn't begin on stripe width
|
|
# 00001 Doesn't end on stripe width
|
|
_filter_bmap()
|
|
{
|
|
awk '
|
|
$3 ~ /hole/ {
|
|
print $1, $2, $3;
|
|
next;
|
|
}
|
|
$7 ~ /1[01][01][01][01]/ {
|
|
print $1, $2, "unwritten";
|
|
next;
|
|
}
|
|
$7 ~ /0[01][01][01][01]/ {
|
|
print $1, $2, "data"
|
|
}' |
|
|
_coalesce_extents
|
|
}
|
|
|
|
die_now()
|
|
{
|
|
status=1
|
|
exit
|
|
}
|
|
|
|
# test the different corner cases for zeroing a range:
|
|
#
|
|
# 1. into a hole
|
|
# 2. into allocated space
|
|
# 3. into unwritten space
|
|
# 4. hole -> data
|
|
# 5. hole -> unwritten
|
|
# 6. data -> hole
|
|
# 7. data -> unwritten
|
|
# 8. unwritten -> hole
|
|
# 9. unwritten -> data
|
|
# 10. hole -> data -> hole
|
|
# 11. data -> hole -> data
|
|
# 12. unwritten -> data -> unwritten
|
|
# 13. data -> unwritten -> data
|
|
# 14. data -> hole @ EOF
|
|
# 15. data -> hole @ 0
|
|
# 16. data -> cache cold ->hole
|
|
# 17. data -> hole in single block file
|
|
#
|
|
# Test file is removed, created and sync'd between tests.
|
|
#
|
|
# Use -k flag to keep the file between tests. This will
|
|
# test the handling of pre-existing holes.
|
|
#
|
|
# Use the -d flag to not sync the file between tests.
|
|
# This will test the handling of delayed extents
|
|
#
|
|
# Use the -u flag to not run unwritten tests.
|
|
# This will eliminate some unnecessary information.
|
|
#
|
|
_test_generic_punch()
|
|
{
|
|
|
|
remove_testfile=1
|
|
sync_cmd="-c fsync"
|
|
unwritten_tests=1
|
|
OPTIND=1
|
|
while getopts 'dku' OPTION
|
|
do
|
|
case $OPTION in
|
|
k) remove_testfile=
|
|
;;
|
|
d) sync_cmd=
|
|
;;
|
|
u) unwritten_tests=
|
|
;;
|
|
?) echo Invalid flag
|
|
exit 1
|
|
;;
|
|
esac
|
|
done
|
|
shift $(($OPTIND - 1))
|
|
|
|
alloc_cmd=$1
|
|
punch_cmd=$2
|
|
zero_cmd=$3 #if not testing zero just set to punch
|
|
map_cmd=$4
|
|
filter_cmd=$5
|
|
testfile=$6
|
|
|
|
# The punch hole tests needs multiple of the largest extent size being
|
|
# tested, with multiple=16 it can test extent size upto 64k.
|
|
multiple=16
|
|
_4k="$((multiple * 4))k"
|
|
_8k="$((multiple * 8))k"
|
|
_12k="$((multiple * 12))k"
|
|
_20k="$((multiple * 20))k"
|
|
|
|
# initial test state must be defined, otherwise the first test can fail
|
|
# due ot stale file state left from previous tests.
|
|
rm -f $testfile
|
|
|
|
echo " 1. into a hole"
|
|
$XFS_IO_PROG -f -c "truncate $_20k" \
|
|
-c "$zero_cmd $_4k $_8k" \
|
|
-c "$map_cmd -v" $testfile | $filter_cmd
|
|
[ $? -ne 0 ] && die_now
|
|
_md5_checksum $testfile
|
|
|
|
echo " 2. into allocated space"
|
|
if [ "$remove_testfile" ]; then
|
|
rm -f $testfile
|
|
fi
|
|
$XFS_IO_PROG -f -c "truncate $_20k" \
|
|
-c "pwrite 0 $_20k" $sync_cmd \
|
|
-c "$zero_cmd $_4k $_8k" \
|
|
-c "$map_cmd -v" $testfile | $filter_cmd
|
|
[ $? -ne 0 ] && die_now
|
|
_md5_checksum $testfile
|
|
|
|
if [ "$unwritten_tests" ]; then
|
|
echo " 3. into unwritten space"
|
|
if [ "$remove_testfile" ]; then
|
|
rm -f $testfile
|
|
fi
|
|
$XFS_IO_PROG -f -c "truncate $_20k" \
|
|
-c "$alloc_cmd 0 $_20k" \
|
|
-c "$zero_cmd $_4k $_8k" \
|
|
-c "$map_cmd -v" $testfile | $filter_cmd
|
|
[ $? -ne 0 ] && die_now
|
|
_md5_checksum $testfile
|
|
fi
|
|
|
|
echo " 4. hole -> data"
|
|
if [ "$remove_testfile" ]; then
|
|
rm -f $testfile
|
|
fi
|
|
$XFS_IO_PROG -f -c "truncate $_20k" \
|
|
-c "pwrite $_8k $_8k" $sync_cmd \
|
|
-c "$zero_cmd $_4k $_8k" \
|
|
-c "$map_cmd -v" $testfile | $filter_cmd
|
|
[ $? -ne 0 ] && die_now
|
|
_md5_checksum $testfile
|
|
|
|
if [ "$unwritten_tests" ]; then
|
|
echo " 5. hole -> unwritten"
|
|
if [ "$remove_testfile" ]; then
|
|
rm -f $testfile
|
|
fi
|
|
$XFS_IO_PROG -f -c "truncate $_20k" \
|
|
-c "$alloc_cmd $_8k $_8k" \
|
|
-c "$zero_cmd $_4k $_8k" \
|
|
-c "$map_cmd -v" $testfile | $filter_cmd
|
|
[ $? -ne 0 ] && die_now
|
|
_md5_checksum $testfile
|
|
fi
|
|
|
|
echo " 6. data -> hole"
|
|
if [ "$remove_testfile" ]; then
|
|
rm -f $testfile
|
|
fi
|
|
$XFS_IO_PROG -f -c "truncate $_20k" \
|
|
-c "pwrite 0 $_8k" $sync_cmd \
|
|
-c "$zero_cmd $_4k $_8k" \
|
|
-c "$map_cmd -v" $testfile | $filter_cmd
|
|
[ $? -ne 0 ] && die_now
|
|
_md5_checksum $testfile
|
|
|
|
if [ "$unwritten_tests" ]; then
|
|
echo " 7. data -> unwritten"
|
|
if [ "$remove_testfile" ]; then
|
|
rm -f $testfile
|
|
fi
|
|
$XFS_IO_PROG -f -c "truncate $_20k" \
|
|
-c "pwrite 0 $_8k" $sync_cmd \
|
|
-c "$alloc_cmd $_8k $_8k" \
|
|
-c "$zero_cmd $_4k $_8k" \
|
|
-c "$map_cmd -v" $testfile | $filter_cmd
|
|
[ $? -ne 0 ] && die_now
|
|
_md5_checksum $testfile
|
|
|
|
echo " 8. unwritten -> hole"
|
|
if [ "$remove_testfile" ]; then
|
|
rm -f $testfile
|
|
fi
|
|
$XFS_IO_PROG -f -c "truncate $_20k" \
|
|
-c "$alloc_cmd 0 $_8k" \
|
|
-c "$zero_cmd $_4k $_8k" \
|
|
-c "$map_cmd -v" $testfile | $filter_cmd
|
|
[ $? -ne 0 ] && die_now
|
|
_md5_checksum $testfile
|
|
|
|
echo " 9. unwritten -> data"
|
|
if [ "$remove_testfile" ]; then
|
|
rm -f $testfile
|
|
fi
|
|
$XFS_IO_PROG -f -c "truncate $_20k" \
|
|
-c "$alloc_cmd 0 $_8k" \
|
|
-c "pwrite $_8k $_8k" $sync_cmd \
|
|
-c "$zero_cmd $_4k $_8k" \
|
|
-c "$map_cmd -v" $testfile | $filter_cmd
|
|
[ $? -ne 0 ] && die_now
|
|
_md5_checksum $testfile
|
|
fi
|
|
|
|
echo " 10. hole -> data -> hole"
|
|
if [ "$remove_testfile" ]; then
|
|
rm -f $testfile
|
|
fi
|
|
$XFS_IO_PROG -f -c "truncate $_20k" \
|
|
-c "pwrite $_8k $_4k" $sync_cmd \
|
|
-c "$zero_cmd $_4k $_12k" \
|
|
-c "$map_cmd -v" $testfile | $filter_cmd
|
|
[ $? -ne 0 ] && die_now
|
|
_md5_checksum $testfile
|
|
|
|
echo " 11. data -> hole -> data"
|
|
if [ "$remove_testfile" ]; then
|
|
rm -f $testfile
|
|
fi
|
|
$XFS_IO_PROG -f -c "truncate $_20k" \
|
|
-c "$alloc_cmd 0 $_20k" \
|
|
-c "pwrite 0 $_8k" \
|
|
-c "pwrite $_12k $_8k" $sync_cmd \
|
|
-c "$punch_cmd $_8k $_4k" \
|
|
-c "$zero_cmd $_4k $_12k" \
|
|
-c "$map_cmd -v" $testfile | $filter_cmd
|
|
[ $? -ne 0 ] && die_now
|
|
_md5_checksum $testfile
|
|
|
|
if [ "$unwritten_tests" ]; then
|
|
echo " 12. unwritten -> data -> unwritten"
|
|
if [ "$remove_testfile" ]; then
|
|
rm -f $testfile
|
|
fi
|
|
$XFS_IO_PROG -f -c "truncate $_20k" \
|
|
-c "$alloc_cmd 0 $_20k" \
|
|
-c "pwrite $_8k $_4k" $sync_cmd \
|
|
-c "$zero_cmd $_4k $_12k" \
|
|
-c "$map_cmd -v" $testfile | $filter_cmd
|
|
[ $? -ne 0 ] && die_now
|
|
_md5_checksum $testfile
|
|
|
|
echo " 13. data -> unwritten -> data"
|
|
if [ "$remove_testfile" ]; then
|
|
rm -f $testfile
|
|
fi
|
|
$XFS_IO_PROG -f -c "truncate $_20k" \
|
|
-c "$alloc_cmd 0 $_20k" \
|
|
-c "pwrite 0k $_4k" $sync_cmd \
|
|
-c "pwrite $_12k $_8k" -c "fsync" \
|
|
-c "$zero_cmd $_4k $_12k" \
|
|
-c "$map_cmd -v" $testfile | $filter_cmd
|
|
[ $? -ne 0 ] && die_now
|
|
_md5_checksum $testfile
|
|
fi
|
|
|
|
# Don't need to check EOF case for collapse range.
|
|
# VFS layer return invalid error in this case,
|
|
# So it is not a proper case for collapse range test of each local fs.
|
|
if [ "$zero_cmd" != "fcollapse" ]; then
|
|
echo " 14. data -> hole @ EOF"
|
|
rm -f $testfile
|
|
$XFS_IO_PROG -f -c "truncate $_20k" \
|
|
-c "pwrite 0 $_20k" $sync_cmd \
|
|
-c "$zero_cmd $_12k $_8k" \
|
|
-c "$map_cmd -v" $testfile | $filter_cmd
|
|
[ $? -ne 0 ] && die_now
|
|
_md5_checksum $testfile
|
|
fi
|
|
|
|
if [ "$zero_cmd" == "fcollapse" ]; then
|
|
echo " 14. data -> hole @ 0"
|
|
else
|
|
echo " 15. data -> hole @ 0"
|
|
fi
|
|
|
|
if [ "$remove_testfile" ]; then
|
|
rm -f $testfile
|
|
fi
|
|
$XFS_IO_PROG -f -c "truncate $_20k" \
|
|
-c "pwrite 0 $_20k" $sync_cmd \
|
|
-c "$zero_cmd 0 $_8k" \
|
|
-c "$map_cmd -v" $testfile | $filter_cmd
|
|
[ $? -ne 0 ] && die_now
|
|
_md5_checksum $testfile
|
|
|
|
# If zero_cmd is fcollpase, don't check unaligned offsets
|
|
if [ "$zero_cmd" == "fcollapse" ]; then
|
|
return
|
|
fi
|
|
|
|
# If zero_cmd is finsert, don't check unaligned offsets
|
|
if [ "$zero_cmd" == "finsert" ]; then
|
|
return
|
|
fi
|
|
|
|
echo " 16. data -> cache cold ->hole"
|
|
if [ "$remove_testfile" ]; then
|
|
rm -f $testfile
|
|
rm -f $testfile.2
|
|
else
|
|
cp $testfile $testfile.2
|
|
fi
|
|
$XFS_IO_PROG -f -c "truncate $_20k" \
|
|
-c "pwrite $_8k $_12k" -c "fsync" $testfile.2 \
|
|
> /dev/null
|
|
$XFS_IO_PROG -f -c "truncate $_20k" \
|
|
-c "pwrite 0 $_20k" $sync_cmd \
|
|
-c "$zero_cmd 0k $_8k" \
|
|
-c "fadvise -d" \
|
|
-c "$map_cmd -v" $testfile | $filter_cmd
|
|
diff $testfile $testfile.2
|
|
[ $? -ne 0 ] && die_now
|
|
rm -f $testfile.2
|
|
_md5_checksum $testfile
|
|
|
|
# different file sizes mean we can't use md5sum to check the hole is
|
|
# valid. Hence use hexdump to dump the contents and chop off the last
|
|
# line of output that indicates the file size. We also have to fudge
|
|
# the extent size as that will change with file size, too - that's what
|
|
# the sed line noise does - it will always result in an output of [0..7]
|
|
# so it matches 4k block size...
|
|
echo " 17. data -> hole in single block file"
|
|
if [ "$remove_testfile" ]; then
|
|
rm -f $testfile
|
|
fi
|
|
block_size=`_get_block_size $TEST_DIR`
|
|
$XFS_IO_PROG -f -c "truncate $block_size" \
|
|
-c "pwrite 0 $block_size" $sync_cmd \
|
|
-c "$zero_cmd 128 128" \
|
|
-c "$map_cmd -v" $testfile | $filter_cmd | \
|
|
sed -e "s/\.\.[0-9]*\]/..7\]/"
|
|
[ $? -ne 0 ] && die_now
|
|
od -x $testfile | head -n -1
|
|
}
|
|
|
|
_test_block_boundaries()
|
|
{
|
|
|
|
remove_testfile=1
|
|
sync_cmd="-c fsync"
|
|
unwritten_tests=1
|
|
OPTIND=1
|
|
while getopts 'dk' OPTION
|
|
do
|
|
case $OPTION in
|
|
k) remove_testfile=
|
|
;;
|
|
d) sync_cmd=
|
|
;;
|
|
?) echo Invalid flag
|
|
exit 1
|
|
;;
|
|
esac
|
|
done
|
|
shift $(($OPTIND - 1))
|
|
|
|
bs=$1
|
|
zero_cmd=$2
|
|
filter_cmd=$3
|
|
testfile=$4
|
|
|
|
# Block size plus 1
|
|
bs_p1=$(($bs + 1))
|
|
# Block size plus 2
|
|
bs_p2=$(($bs + 2))
|
|
|
|
# Block size minus 1
|
|
bs_m1=$(($bs - 1))
|
|
|
|
# Block size multiplied by 2
|
|
bs_t2=$(($bs * 2))
|
|
|
|
# Block size divided by 2
|
|
bs_d2=$(($bs / 2))
|
|
|
|
echo "zero 0, 1"
|
|
$XFS_IO_PROG -f -t -c "pwrite -S 0x41 0 $bs" \
|
|
-c "pwrite -S 0x42 $bs $bs" \
|
|
-c "$zero_cmd 0 1" \
|
|
-c "pread -v 0 $bs_t2" \
|
|
$testfile | $filter_cmd
|
|
|
|
echo "zero 0, $bs_m1"
|
|
$XFS_IO_PROG -f -t -c "pwrite -S 0x41 0 $bs" \
|
|
-c "pwrite -S 0x42 $bs $bs" \
|
|
-c "$zero_cmd 0 $bs_m1" \
|
|
-c "pread -v 0 $bs_t2" \
|
|
$testfile | $filter_cmd
|
|
|
|
echo "zero 0, $bs"
|
|
$XFS_IO_PROG -f -t -c "pwrite -S 0x41 0 $bs" \
|
|
-c "pwrite -S 0x42 $bs $bs" \
|
|
-c "$zero_cmd 0 $bs" \
|
|
-c "pread -v 0 $bs_t2" \
|
|
$testfile | $filter_cmd
|
|
|
|
echo "zero 0, $bs_p1"
|
|
$XFS_IO_PROG -f -t -c "pwrite -S 0x41 0 $bs" \
|
|
-c "pwrite -S 0x42 $bs $bs" \
|
|
-c "$zero_cmd 0 $bs_p1" \
|
|
-c "pread -v 0 $bs_t2" \
|
|
$testfile | $filter_cmd
|
|
|
|
echo "zero $bs_m1, $bs"
|
|
$XFS_IO_PROG -f -t -c "pwrite -S 0x41 0 $bs" \
|
|
-c "pwrite -S 0x42 $bs $bs" \
|
|
-c "$zero_cmd $bs_m1 $bs" \
|
|
-c "pread -v 0 $bs_t2" \
|
|
$testfile | $filter_cmd
|
|
|
|
echo "zero $bs_m1, $bs_p1"
|
|
$XFS_IO_PROG -f -t -c "pwrite -S 0x41 0 $bs" \
|
|
-c "pwrite -S 0x42 $bs $bs" \
|
|
-c "$zero_cmd $bs_m1 $bs_p1" \
|
|
-c "pread -v 0 $bs_t2" \
|
|
$testfile | $filter_cmd
|
|
|
|
echo "zero $bs_m1, $bs_p2"
|
|
$XFS_IO_PROG -f -t -c "pwrite -S 0x41 0 $bs" \
|
|
-c "pwrite -S 0x42 $bs $bs" \
|
|
-c "$zero_cmd $bs_m1 $bs_p2" \
|
|
-c "pread -v 0 $bs_t2" \
|
|
$testfile | $filter_cmd
|
|
|
|
|
|
echo "zero $bs, $bs"
|
|
$XFS_IO_PROG -f -t -c "pwrite -S 0x41 0 $bs" \
|
|
-c "pwrite -S 0x42 $bs $bs" \
|
|
-c "$zero_cmd $bs $bs" \
|
|
-c "pread -v 0 $bs_t2" \
|
|
$testfile | $filter_cmd
|
|
|
|
|
|
echo "zero $bs_d2 , $bs"
|
|
$XFS_IO_PROG -f -t -c "pwrite -S 0x41 0 $bs" \
|
|
-c "pwrite -S 0x42 $bs $bs" \
|
|
-c "$zero_cmd $bs_d2 $bs" \
|
|
-c "pread -v 0 $bs_t2" \
|
|
$testfile | $filter_cmd
|
|
}
|