mirror of
https://github.com/linux-apfs/apfstests.git
synced 2026-05-01 15:01:44 -07:00
Test for detecting unwritten extent related corruption reading+writing under swap.
This commit is contained in:
@@ -0,0 +1,81 @@
|
|||||||
|
#! /bin/sh
|
||||||
|
# XFS QA Test No. 084
|
||||||
|
#
|
||||||
|
# Exercises unwritten extent reads and writes, looking
|
||||||
|
# for data corruption (zeroes read) near the end of file.
|
||||||
|
#
|
||||||
|
#-----------------------------------------------------------------------
|
||||||
|
# Copyright (c) 2000-2004 Silicon Graphics, Inc. All Rights Reserved.
|
||||||
|
#
|
||||||
|
# This program is free software; you can redistribute it and/or modify it
|
||||||
|
# under the terms of version 2 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.
|
||||||
|
#
|
||||||
|
# Further, this software is distributed without any warranty that it is
|
||||||
|
# free of the rightful claim of any third person regarding infringement
|
||||||
|
# or the like. Any license provided herein, whether implied or
|
||||||
|
# otherwise, applies only to this software file. Patent licenses, if
|
||||||
|
# any, provided herein do not apply to combinations of this program with
|
||||||
|
# other software, or any other product whatsoever.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License along
|
||||||
|
# with this program; if not, write the Free Software Foundation, Inc., 59
|
||||||
|
# Temple Place - Suite 330, Boston MA 02111-1307, USA.
|
||||||
|
#
|
||||||
|
# Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
|
||||||
|
# Mountain View, CA 94043, or:
|
||||||
|
#
|
||||||
|
# http://www.sgi.com
|
||||||
|
#
|
||||||
|
# For further information regarding this notice, see:
|
||||||
|
#
|
||||||
|
# http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
|
||||||
|
#-----------------------------------------------------------------------
|
||||||
|
#
|
||||||
|
# creator
|
||||||
|
owner=nathans@sgi.com
|
||||||
|
|
||||||
|
seq=`basename $0`
|
||||||
|
echo "QA output created by $seq"
|
||||||
|
|
||||||
|
here=`pwd`
|
||||||
|
tmp=/tmp/$$
|
||||||
|
status=1 # failure is the default!
|
||||||
|
trap "rm -f $tmp.*; exit \$status" 0 1 2 3 15
|
||||||
|
|
||||||
|
# get standard environment, filters and checks
|
||||||
|
. ./common.rc
|
||||||
|
. ./common.filter
|
||||||
|
|
||||||
|
_filter_resv()
|
||||||
|
{
|
||||||
|
sed -e "s,$TEST_DIR/resv,[TESTFILE],g"
|
||||||
|
}
|
||||||
|
|
||||||
|
pgsize=`$here/src/feature -p`
|
||||||
|
|
||||||
|
# -i == number of iterations
|
||||||
|
# -l == bytes to leak on each iteration
|
||||||
|
# -b == read/write block size
|
||||||
|
# -s == preallocation size
|
||||||
|
|
||||||
|
# real QA test starts here
|
||||||
|
echo
|
||||||
|
echo "*** First case - I/O blocksize same as pagesize"
|
||||||
|
$here/src/resvtest -i 20 -b $pgsize "$TEST_DIR/resv" | _filter_resv
|
||||||
|
[ $? -eq 0 ] && echo done
|
||||||
|
rm -f "$TEST_DIR/mumble"
|
||||||
|
|
||||||
|
echo
|
||||||
|
echo "*** Second case - 512 byte I/O blocksize"
|
||||||
|
$here/src/resvtest -i 40 -b 512 "$TEST_DIR/resv" | _filter_resv
|
||||||
|
[ $? -eq 0 ] && echo done
|
||||||
|
rm -f "$TEST_DIR/grumble"
|
||||||
|
|
||||||
|
# success, all done
|
||||||
|
status=0
|
||||||
|
exit
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
QA output created by 084
|
||||||
|
|
||||||
|
*** First case - I/O blocksize same as pagesize
|
||||||
|
reserved 40960000 bytes for [TESTFILE] using XFS_IOC_RESVSP64
|
||||||
|
done
|
||||||
|
|
||||||
|
*** Second case - 512 byte I/O blocksize
|
||||||
|
reserved 40960000 bytes for [TESTFILE] using XFS_IOC_RESVSP64
|
||||||
|
done
|
||||||
@@ -144,3 +144,4 @@ ioctl nathans@sgi.com
|
|||||||
081 logprint quota
|
081 logprint quota
|
||||||
082 logprint
|
082 logprint
|
||||||
083 rw auto
|
083 rw auto
|
||||||
|
084 ioctl rw auto
|
||||||
|
|||||||
+9
-3
@@ -1,5 +1,5 @@
|
|||||||
#
|
#
|
||||||
# Copyright (c) 2000-2003 Silicon Graphics, Inc. All Rights Reserved.
|
# Copyright (c) 2000-2004 Silicon Graphics, Inc. All Rights Reserved.
|
||||||
#
|
#
|
||||||
# This program is free software; you can redistribute it and/or modify it
|
# This program is free software; you can redistribute it and/or modify it
|
||||||
# under the terms of version 2 of the GNU General Public License as
|
# under the terms of version 2 of the GNU General Public License as
|
||||||
@@ -36,8 +36,8 @@ include $(TOPDIR)/include/builddefs
|
|||||||
TARGETS = alloc acl_get bstat devzero dirstress fault feature \
|
TARGETS = alloc acl_get bstat devzero dirstress fault feature \
|
||||||
fill fill2 getpagesize holes xfsctl loggen lstat64 \
|
fill fill2 getpagesize holes xfsctl loggen lstat64 \
|
||||||
nametest permname randholes runas truncfile usemem \
|
nametest permname randholes runas truncfile usemem \
|
||||||
fstest mmapcat append_reader append_writer \
|
fileread fstest mmapcat append_reader append_writer \
|
||||||
dirperf metaperf enospc_unlink
|
dirperf metaperf enospc_unlink resvtest scaleread
|
||||||
ifeq ($(ENABLE_DBM), yes)
|
ifeq ($(ENABLE_DBM), yes)
|
||||||
TARGETS += dbtest
|
TARGETS += dbtest
|
||||||
endif
|
endif
|
||||||
@@ -77,5 +77,11 @@ loggen: loggen.o
|
|||||||
fstest: fstest.o
|
fstest: fstest.o
|
||||||
$(LINKTEST)
|
$(LINKTEST)
|
||||||
|
|
||||||
|
#scaleread: scaleread.o $(LDLIBS)
|
||||||
|
# $(LINKTEST)
|
||||||
|
|
||||||
|
resvtest: resvtest.o
|
||||||
|
$(LINKTEST)
|
||||||
|
|
||||||
acl_get: acl_get.o $(LIBACL) $(LIBATTR)
|
acl_get: acl_get.o $(LIBACL) $(LIBATTR)
|
||||||
$(LINKTEST) $(LIBACL) $(LIBATTR) $(LDLIBS)
|
$(LINKTEST) $(LIBACL) $(LIBATTR) $(LDLIBS)
|
||||||
|
|||||||
+165
@@ -0,0 +1,165 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2004 Silicon Graphics, Inc. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of version 2 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.
|
||||||
|
*
|
||||||
|
* Further, this software is distributed without any warranty that it is
|
||||||
|
* free of the rightful claim of any third person regarding infringement
|
||||||
|
* or the like. Any license provided herein, whether implied or
|
||||||
|
* otherwise, applies only to this software file. Patent licenses, if
|
||||||
|
* any, provided herein do not apply to combinations of this program with
|
||||||
|
* other software, or any other product whatsoever.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along
|
||||||
|
* with this program; if not, write the Free Software Foundation, Inc., 59
|
||||||
|
* Temple Place - Suite 330, Boston MA 02111-1307, USA.
|
||||||
|
*
|
||||||
|
* Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
|
||||||
|
* Mountain View, CA 94043, or:
|
||||||
|
*
|
||||||
|
* http://www.sgi.com
|
||||||
|
*
|
||||||
|
* For further information regarding this notice, see:
|
||||||
|
*
|
||||||
|
* http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "global.h"
|
||||||
|
|
||||||
|
int
|
||||||
|
main(int argc, char **argv)
|
||||||
|
{
|
||||||
|
int c, i, j, n, err = 0;
|
||||||
|
int writefd, readfd;
|
||||||
|
long iterations = 100;
|
||||||
|
long psize, bsize, leaksize = 32 * 1024 * 1024;
|
||||||
|
char *filename;
|
||||||
|
char *readbuffer, *writebuffer;
|
||||||
|
off64_t resvsize;
|
||||||
|
xfs_flock64_t resvsp;
|
||||||
|
|
||||||
|
psize = bsize = getpagesize();
|
||||||
|
resvsize = bsize * (off64_t) 10000;
|
||||||
|
|
||||||
|
while ((c = getopt(argc, argv, "b:i:l:s:")) != EOF) {
|
||||||
|
switch(c) {
|
||||||
|
case 'b':
|
||||||
|
bsize = atol(optarg);
|
||||||
|
break;
|
||||||
|
case 'i':
|
||||||
|
iterations = atol(optarg);
|
||||||
|
break;
|
||||||
|
case 'l':
|
||||||
|
leaksize = atol(optarg);
|
||||||
|
break;
|
||||||
|
case 's':
|
||||||
|
resvsize = (off64_t) atoll(optarg);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
err++;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (optind > argc + 1)
|
||||||
|
err++;
|
||||||
|
|
||||||
|
if (err) {
|
||||||
|
printf("Usage: %s [-b blksize] [-l leaksize] [-r resvsize]\n",
|
||||||
|
argv[0]);
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
filename = argv[optind];
|
||||||
|
|
||||||
|
readbuffer = memalign(psize, bsize);
|
||||||
|
writebuffer = memalign(psize, bsize);
|
||||||
|
if (!readbuffer || !writebuffer) {
|
||||||
|
perror("open");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
memset(writebuffer, 'A', sizeof(writebuffer));
|
||||||
|
|
||||||
|
unlink(filename);
|
||||||
|
writefd = open(filename, O_RDWR | O_CREAT | O_EXCL, S_IRUSR | S_IWUSR);
|
||||||
|
if (writefd < 0) {
|
||||||
|
perror("open");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
readfd = open(filename, O_RDONLY);
|
||||||
|
if (readfd < 0) {
|
||||||
|
perror("open");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* preallocate file space */
|
||||||
|
resvsp.l_whence = 0;
|
||||||
|
resvsp.l_start = 0;
|
||||||
|
resvsp.l_len = resvsize;
|
||||||
|
if (ioctl(writefd, XFS_IOC_RESVSP64, &resvsp) < 0) {
|
||||||
|
fprintf(stdout, "attempt to reserve %lld bytes for %s "
|
||||||
|
"using %s failed: %s (%d)\n",
|
||||||
|
resvsize, filename, "XFS_IOC_RESVSP64",
|
||||||
|
strerror(errno), errno);
|
||||||
|
} else {
|
||||||
|
fprintf(stdout, "reserved %lld bytes for %s using %s\n",
|
||||||
|
resvsize, filename, "XFS_IOC_RESVSP64");
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Space is now preallocated, start IO --
|
||||||
|
* write at current offset, pressurize, seek to zero on reader
|
||||||
|
* and read up to current write offset.
|
||||||
|
*/
|
||||||
|
|
||||||
|
n = 0;
|
||||||
|
while (++n < iterations) {
|
||||||
|
char *p;
|
||||||
|
int numerrors;
|
||||||
|
|
||||||
|
if (write(writefd, writebuffer, sizeof(writebuffer)) < 0) {
|
||||||
|
perror("write");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Apply some memory pressure
|
||||||
|
* (allocate another chunk and touch all pages)
|
||||||
|
*/
|
||||||
|
for (i = 0; i < (leaksize / psize); i++) {
|
||||||
|
p = malloc(psize);
|
||||||
|
if (p)
|
||||||
|
p[7] = '7';
|
||||||
|
}
|
||||||
|
sleep(1);
|
||||||
|
lseek(readfd, SEEK_SET, 0);
|
||||||
|
numerrors = 0;
|
||||||
|
for (j = 0; j < n; j++) {
|
||||||
|
if (read(readfd, readbuffer, sizeof(readbuffer)) < 0) {
|
||||||
|
perror("read");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
for (i = 0; i < sizeof(readbuffer); i++) {
|
||||||
|
if (readbuffer[i] != 'A') {
|
||||||
|
fprintf(stderr,
|
||||||
|
"errors detected in file, pos: %d (%lld+%d), nwrites: %d [val=0x%x].\n",
|
||||||
|
j, (long long)j * 4096,
|
||||||
|
i, n, readbuffer[i]);
|
||||||
|
numerrors++;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (numerrors > 10) {
|
||||||
|
exit(1);
|
||||||
|
} else if (numerrors) {
|
||||||
|
fprintf(stdout, "\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user