fsx: Replace use of bzero() with memset()
[xfstests-dev.git] / common.punch
1 ##/bin/sh
2 #
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         umount $SCRATCH_MNT >/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 || _fail "mount failed"
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 }