diff options
author | Dave Chinner <dchinner@redhat.com> | 2013-03-15 12:28:04 +0000 |
---|---|---|
committer | Rich Johnston <rjohnston@sgi.com> | 2013-03-26 21:44:05 -0500 |
commit | 8c4905a42e10650a75c0e3966ecc044e1a9616d0 (patch) | |
tree | 1830ea2b6307fcd138dcc58ec2605c27b0a25004 /common/punch | |
parent | 401680a11c4fb08d749d1d75598c7705273e5860 (diff) |
xfstests: introduce a common directory
Introduce a top level common directory and move all the common.*
files into it. Because there is now a directory named common, the
prefix can be dropped from all the files. Convert all the tests to
use this new directory for including common files.
for f in common.*; do \
git mv `echo -n "$f " ; echo $f | sed -e 's;n\.;n/;'` \
done
Signed-off-by: Dave Chinner <dchinner@redhat.com>
Reviewed-by: Phil White <pwhite@sgi.com>
[rjohnston@sgi.com reworked for TOT changes]
Signed-off-by: Rich Johnston <rjohnston@sgi.com>
Diffstat (limited to 'common/punch')
-rw-r--r-- | common/punch | 525 |
1 files changed, 525 insertions, 0 deletions
diff --git a/common/punch b/common/punch new file mode 100644 index 00000000..cfbe5769 --- /dev/null +++ b/common/punch @@ -0,0 +1,525 @@ +##/bin/bash +# +# Copyright (c) 2007 Silicon Graphics, Inc. All Rights Reserved. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation. +# +# This program is distributed in the hope that it would be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write the Free Software Foundation, +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +# +# +# 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 / + umount $SCRATCH_MNT >/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 || _fail "mount failed" + 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() +{ + awk -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 - 1, prev_type); + printf("%u: [%u..", out_count++, low); + prev_type = type; + } + } + END { + if (prev_type != "") + printf("%u]:%s\n", high, prev_type); + }' +} + +_filter_fiemap() +{ + awk --posix ' + $3 ~ /hole/ { + print $1, $2, $3; + next; + } + $5 ~ /0x[[:xdigit:]]*8[[:xdigit:]]{2}/ { + print $1, $2, "unwritten"; + next; + } + $5 ~ /0x[[:xdigit:]]+/ { + print $1, $2, "data"; + }' | + _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 --posix ' + $3 ~ /hole/ { + print $1, $2, $3; + next; + } + $5 ~ /0x[[:xdigit:]]+/ { + print $1, $2, "extent"; + }' | + _coalesce_extents +} + + +# Prints the md5 checksum of a given file +_md5_checksum() +{ + md5sum $1 | cut -d ' ' -f1 +} + +_filter_bmap() +{ + awk ' + $3 ~ /hole/ { + print $1, $2, $3; + next; + } + $7 ~ /10000/ { + print $1, $2, "unwritten"; + next; + } + $7 ~ /00000/ { + 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 +# +_test_generic_punch() +{ + + remove_testfile=1 + sync_cmd="-c fsync" + 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)) + + 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 + xfs_io_opt=$7 #needs to be -F if not testing xfs + + echo " 1. into a hole" + if [ "$remove_testfile" ]; then + rm -f $testfile + fi + $XFS_IO_PROG $xfs_io_opt -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 $xfs_io_opt -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 + + echo " 3. into unwritten space" + if [ "$remove_testfile" ]; then + rm -f $testfile + fi + $XFS_IO_PROG $xfs_io_opt -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 + + echo " 4. hole -> data" + if [ "$remove_testfile" ]; then + rm -f $testfile + fi + $XFS_IO_PROG $xfs_io_opt -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 + + echo " 5. hole -> unwritten" + if [ "$remove_testfile" ]; then + rm -f $testfile + fi + $XFS_IO_PROG $xfs_io_opt -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 + + echo " 6. data -> hole" + if [ "$remove_testfile" ]; then + rm -f $testfile + fi + $XFS_IO_PROG $xfs_io_opt -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 + + echo " 7. data -> unwritten" + if [ "$remove_testfile" ]; then + rm -f $testfile + fi + $XFS_IO_PROG $xfs_io_opt -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 $xfs_io_opt -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 $xfs_io_opt -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 + + echo " 10. hole -> data -> hole" + if [ "$remove_testfile" ]; then + rm -f $testfile + fi + $XFS_IO_PROG $xfs_io_opt -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 $xfs_io_opt -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 + + echo " 12. unwritten -> data -> unwritten" + if [ "$remove_testfile" ]; then + rm -f $testfile + fi + $XFS_IO_PROG $xfs_io_opt -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 $xfs_io_opt -f -c "truncate 20k" \ + -c "$alloc_cmd 0 20k" \ + -c "pwrite 0k 8k" $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 + + echo " 14. data -> hole @ EOF" + rm -f $testfile + $XFS_IO_PROG $xfs_io_opt -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 + + echo " 15. data -> hole @ 0" + if [ "$remove_testfile" ]; then + rm -f $testfile + fi + $XFS_IO_PROG $xfs_io_opt -f -c "truncate 20k" \ + -c "pwrite 0 20k" $sync_cmd \ + -c "$zero_cmd 0k 8k" \ + -c "$map_cmd -v" $testfile | $filter_cmd + [ $? -ne 0 ] && die_now + _md5_checksum $testfile + + 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 $xfs_io_opt -f -c "truncate 20k" \ + -c "pwrite 8k 12k" -c "fsync" $testfile.2 \ + > /dev/null + $XFS_IO_PROG $xfs_io_opt -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 + + echo " 17. data -> hole in single block file" + if [ "$remove_testfile" ]; then + rm -f $testfile + fi + block_size=`stat -f $TEST_DEV | grep "Block size" | cut -d " " -f3` + $XFS_IO_PROG $xfs_io_opt -f -c "truncate $block_size" \ + -c "pwrite 0 $block_size" $sync_cmd \ + -c "$zero_cmd 128 128" \ + -c "$map_cmd -v" $testfile | $filter_cmd + [ $? -ne 0 ] && die_now + _md5_checksum $testfile + +} |