stress2: Update tool to list both DATA and HOLES in a file.

Added a regression test.
This commit is contained in:
Peter Holm 2022-10-24 09:45:32 +02:00
parent d3975204e4
commit 799db59e9a
2 changed files with 114 additions and 22 deletions

View File

@ -0,0 +1,77 @@
#!/bin/sh
#
# SPDX-License-Identifier: BSD-2-Clause-FreeBSD
#
# Copyright (c) 2022 Peter Holm <pho@FreeBSD.org>
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
#
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
# SUCH DAMAGE.
#
# A SEEK_HOLE / SEEK_DATA test scenario
[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1
. ../default.cfg
prog=$(basename "$0" .sh)
exp=/tmp/$prog.exp
here=`pwd`
log=/tmp/$prog.log
cc -o /tmp/lsholes -Wall -Wextra -O2 $here/../tools/lsholes.c | exit 1
cat > $exp <<EXP
Min hole size is 32768, file size is 524288000.
data #1 @ 0, size=32768)
hole #2 @ 32768, size=32768
data #3 @ 65536, size=32768)
hole #4 @ 98304, size=32768
data #5 @ 131072, size=32768)
hole #6 @ 163840, size=524091392
data #7 @ 524255232, size=32768)
hole #8 @ 524288000, size=0
EXP
set -eu
mdconfig -l | grep -q md$mdstart && mdconfig -d -u $mdstart
mdconfig -s 2g -u $mdstart
newfs -U /dev/md$mdstart > /dev/null
mount /dev/md$mdstart $mntpoint
set +e
file=$mntpoint/file
truncate -s 500m $file
bs=`getconf MIN_HOLE_SIZE $file`
printf "\001" | dd of=$file seek=$((0*bs)) bs=1 count=1 conv=notrunc status=none
printf "\002" | dd of=$file seek=$((2*bs)) bs=1 count=1 conv=notrunc status=none
printf "\003" | dd of=$file seek=$((4*bs)) bs=1 count=1 conv=notrunc status=none
s1=0
s2=0
/tmp/lsholes $file > $log 2>&1; s1=$?
cat $log
cmp -s $exp $log || s2=1
umount $mntpoint
mdconfig -d -u $mdstart
rm -f /tmp/lsholes $exp $log
exit $((s1 + s2))

View File

@ -40,7 +40,8 @@ main(int argc, char *argv[])
{
struct stat st;
off_t data, hole, pos;
long mx;
long mn;
intmax_t siz;
int fd, n;
char *name;
@ -54,33 +55,47 @@ main(int argc, char *argv[])
err(1, "open(%s)", name);
if (fstat(fd, &st))
err(1, "fstat()");
if ((mx = fpathconf(fd, _PC_MIN_HOLE_SIZE)) == -1)
if ((mn = fpathconf(fd, _PC_MIN_HOLE_SIZE)) == -1)
err(1, "fpathconf()");
fprintf(stderr, "file \"%s\" size = %jd, _PC_MIN_HOLE_SIZE = %ld\n",
name, (intmax_t)st.st_size, mx);
fprintf(stderr, "Min hole size is %ld, file size is %jd.\n",
mn, (intmax_t)st.st_size);
n = 1;
pos = 0;
while (pos < st.st_size) {
if ((hole = lseek(fd, pos, SEEK_HOLE)) == -1)
hole = lseek(fd, pos, SEEK_HOLE);
if (hole == -1 && errno != ENXIO)
err(1, "lseek(SEEK_HOLE)");
if ((data = lseek(fd, hole, SEEK_DATA)) == -1) {
if (errno == ENXIO) {
if (hole == st.st_size)
break;
fprintf(stderr,
"No data after hole @ %jd\n",
(intmax_t)hole);
break;
}
err(1, "lseek(SEEK_DATA)");
data = lseek(fd, pos, SEEK_DATA);
if (data == -1 && errno != ENXIO)
err(1, "lseek(SEEK_data)");
if (hole >= 0 && data >= 0 && hole > data) {
siz = hole - data;
printf("data #%d @ %ld, size=%jd)\n",
n, (intmax_t)data, siz);
n++;
pos += siz;
}
if (hole >= 0 && data >= 0 && hole < data) {
siz = data - hole;
printf("hole #%d @ %ld, size=%jd\n",
n, (intmax_t)hole, siz);
n++;
pos += siz;
}
if (hole >= 0 && data == -1) {
siz = st.st_size - hole;
printf("hole #%d @ %ld, size=%jd\n",
n, (intmax_t)hole, siz);
n++;
pos += siz;
}
pos = data;
printf("hole #%d @ %jd (0x%jx), size=%jd (0x%jx)\n",
n, (intmax_t)hole, (intmax_t)hole, (intmax_t)(data - hole),
(intmax_t)(data - hole));
n++;
}
if (hole == st.st_size) {
/* EOF */
printf("hole #%d @ %ld, size=%jd\n",
n, (intmax_t)hole, 0L);
}
close(fd);
if (hole != st.st_size)
errx(1, "No implicit hole at EOF");
}