Sync with latest and greatest Apple sources (which, among other things, fix

the style flag).

Submitted by: Conrad Minshall <conrad@apple.com>
Reviewed by: jkh
Obtained from: Apple Computer, Inc.
This commit is contained in:
Jordan K. Hubbard 2003-04-23 23:42:23 +00:00
parent 5de7693b9f
commit f2e30adc3f
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=113949

View File

@ -4,7 +4,7 @@
* @APPLE_LICENSE_HEADER_START@
*
* The contents of this file constitute Original Code as defined in and
* are subject to the Apple Public Source License Version 1.1 (the
* are subject to the Apple Public Source License Version 1.2 (the
* "License"). You may not use this file except in compliance with the
* License. Please obtain a copy of the License at
* http://www.apple.com/publicsource and read it before using this file.
@ -22,7 +22,7 @@
* File: fsx.c
* Author: Avadis Tevanian, Jr.
*
* File system exerciser.
* File system exerciser.
*
* Rewrite and enhancements 1998-2001 Conrad Minshall -- conrad@mac.com
*
@ -31,7 +31,11 @@
* Small changes to work under Linux -- davej@suse.de
*
* Sundry porting patches from Guy Harris 12/2001
*
* Checks for mmap last-page zero fill.
*
* $FreeBSD$
*
*/
#include <sys/types.h>
@ -118,7 +122,7 @@ int lite = 0; /* -L flag */
long numops = -1; /* -N flag */
int randomoplen = 1; /* -O flag disables it */
int seed = 1; /* -S flag */
int mapped_writes = 1; /* -W flag disables */
int mapped_writes = 1; /* -W flag disables */
int mapped_reads = 1; /* -R flag disables it */
int fsxgoodfd = 0;
FILE * fsxlogf = NULL;
@ -211,7 +215,7 @@ logdump(void)
lp = &oplog[i];
if ((closeopen = lp->operation < 0))
lp->operation = ~ lp->operation;
switch (lp->operation) {
case OP_MAPREAD:
prt("MAPREAD\t0x%x thru 0x%x\t(0x%x bytes)",
@ -292,8 +296,7 @@ save_buffer(char *buffer, off_t bufferlength, int fd)
if (size_by_seek == (off_t)-1)
prterr("save_buffer: lseek eof");
else if (bufferlength > size_by_seek) {
warn("save_buffer: .fsxgood file too short... will
save 0x%llx bytes instead of 0x%llx\n", (unsigned long long)size_by_seek,
warn("save_buffer: .fsxgood file too short... will save 0x%llx bytes instead of 0x%llx\n", (unsigned long long)size_by_seek,
(unsigned long long)bufferlength);
bufferlength = size_by_seek;
}
@ -302,14 +305,13 @@ save 0x%llx bytes instead of 0x%llx\n", (unsigned long long)size_by_seek,
ret = lseek(fd, (off_t)0, SEEK_SET);
if (ret == (off_t)-1)
prterr("save_buffer: lseek 0");
byteswritten = write(fd, buffer, (size_t)bufferlength);
if (byteswritten != bufferlength) {
if (byteswritten == -1)
prterr("save_buffer write");
else
warn("save_buffer: short write, 0x%x bytes instead
of 0x%llx\n",
warn("save_buffer: short write, 0x%x bytes instead of 0x%llx\n",
(unsigned)byteswritten,
(unsigned long long)bufferlength);
}
@ -320,7 +322,7 @@ void
report_failure(int status)
{
logdump();
if (fsxgoodfd) {
if (good_buf) {
save_buffer(good_buf, file_size, fsxgoodfd);
@ -335,7 +337,7 @@ report_failure(int status)
#define short_at(cp) ((unsigned short)((*((unsigned char *)(cp)) << 8) | \
*(((unsigned char *)(cp)) + 1)))
*(((unsigned char *)(cp)) + 1)))
void
check_buffers(unsigned offset, unsigned size)
@ -354,10 +356,10 @@ check_buffers(unsigned offset, unsigned size)
c = good_buf[offset];
t = temp_buf[i];
if (c != t) {
if (n == 0) {
if (n == 0) {
bad = short_at(&temp_buf[i]);
prt("0x%5x\t0x%04x\t0x%04x", offset,
short_at(&good_buf[offset]), bad);
prt("0x%5x\t0x%04x\t0x%04x", offset,
short_at(&good_buf[offset]), bad);
op = temp_buf[offset & 1 ? i+1 : i];
}
n++;
@ -368,15 +370,13 @@ check_buffers(unsigned offset, unsigned size)
size--;
}
if (n) {
prt("\t0x%5x\n", n);
prt("\t0x%5x\n", n);
if (bad)
prt("operation# (mod 256) for the bad data
may be %u\n", ((unsigned)op & 0xff));
prt("operation# (mod 256) for the bad data may be %u\n", ((unsigned)op & 0xff));
else
prt("operation# (mod 256) for the bad data
unknown, check HOLE and EXTEND ops\n");
prt("operation# (mod 256) for the bad data unknown, check HOLE and EXTEND ops\n");
} else
prt("????????????????\n");
prt("????????????????\n");
report_failure(110);
}
}
@ -415,7 +415,7 @@ check_trunc_hack(void)
prt("no extend on truncate! not posix!\n");
exit(130);
}
ftruncate(fd, 0);
ftruncate(fd, (off_t)0);
}
@ -447,7 +447,7 @@ doread(unsigned offset, unsigned size)
if (!quiet && ((progressinterval &&
testcalls % progressinterval == 0) ||
(debug &&
(monitorstart == -1 ||
(monitorstart == -1 ||
(offset + size > monitorstart &&
(monitorend == -1 || offset <= monitorend))))))
prt("%lu read\t0x%x thru\t0x%x\t(0x%x bytes)\n", testcalls,
@ -470,6 +470,33 @@ doread(unsigned offset, unsigned size)
}
void
check_eofpage(char *s, unsigned offset, char *p, int size)
{
unsigned last_page, should_be_zero;
if (offset + size <= (file_size & ~page_mask))
return;
/*
* we landed in the last page of the file
* test to make sure the VM system provided 0's
* beyond the true end of the file mapping
* (as required by mmap def in 1996 posix 1003.1)
*/
last_page = ((int)p + (offset & page_mask) + size) & ~page_mask;
for (should_be_zero = last_page + (file_size & page_mask);
should_be_zero < last_page + page_size;
should_be_zero++)
if (*(char *)should_be_zero) {
prt("Mapped %s: non-zero data past EOF (0x%llx) page offset 0x%x is 0x%04x\n",
s, file_size - 1, should_be_zero & page_mask,
short_at(should_be_zero));
report_failure(205);
}
}
void
domapread(unsigned offset, unsigned size)
{
@ -499,7 +526,7 @@ domapread(unsigned offset, unsigned size)
if (!quiet && ((progressinterval &&
testcalls % progressinterval == 0) ||
(debug &&
(monitorstart == -1 ||
(monitorstart == -1 ||
(offset + size > monitorstart &&
(monitorend == -1 || offset <= monitorend))))))
prt("%lu mapread\t0x%x thru\t0x%x\t(0x%x bytes)\n", testcalls,
@ -508,13 +535,15 @@ domapread(unsigned offset, unsigned size)
pg_offset = offset & page_mask;
map_size = pg_offset + size;
if ((p = (char *)mmap(0, map_size, PROT_READ, MAP_FILE |
MAP_SHARED, fd,
if ((p = (char *)mmap(0, map_size, PROT_READ, MAP_FILE | MAP_SHARED, fd,
(off_t)(offset - pg_offset))) == (char *)-1) {
prterr("domapread: mmap");
prterr("domapread: mmap");
report_failure(190);
}
memcpy(temp_buf, p + pg_offset, size);
check_eofpage("Read", offset, p, size);
if (munmap(p, map_size) != 0) {
prterr("domapread: munmap");
report_failure(191);
@ -528,7 +557,7 @@ void
gendata(char *original_buf, char *good_buf, unsigned offset, unsigned size)
{
while (size--) {
good_buf[offset] = testcalls % 256;
good_buf[offset] = testcalls % 256;
if (offset % 2)
good_buf[offset] += original_buf[offset];
offset++;
@ -569,7 +598,7 @@ dowrite(unsigned offset, unsigned size)
if (!quiet && ((progressinterval &&
testcalls % progressinterval == 0) ||
(debug &&
(monitorstart == -1 ||
(monitorstart == -1 ||
(offset + size > monitorstart &&
(monitorend == -1 || offset <= monitorend))))))
prt("%lu write\t0x%x thru\t0x%x\t(0x%x bytes)\n", testcalls,
@ -627,15 +656,15 @@ domapwrite(unsigned offset, unsigned size)
if (!quiet && ((progressinterval &&
testcalls % progressinterval == 0) ||
(debug &&
(monitorstart == -1 ||
(monitorstart == -1 ||
(offset + size > monitorstart &&
(monitorend == -1 || offset <= monitorend))))))
prt("%lu mapwrite\t0x%x thru\t0x%x\t(0x%x bytes)\n", testcalls,
offset, offset + size - 1, size);
if (file_size > cur_filesize) {
if (ftruncate(fd, file_size) == -1) {
prterr("domapwrite: ftruncate");
if (ftruncate(fd, file_size) == -1) {
prterr("domapwrite: ftruncate");
exit(201);
}
}
@ -645,7 +674,7 @@ domapwrite(unsigned offset, unsigned size)
if ((p = (char *)mmap(0, map_size, PROT_READ | PROT_WRITE,
MAP_FILE | MAP_SHARED, fd,
(off_t)(offset - pg_offset))) == (char *)-1) {
prterr("domapwrite: mmap");
prterr("domapwrite: mmap");
report_failure(202);
}
memcpy(p + pg_offset, good_buf + offset, size);
@ -653,6 +682,9 @@ domapwrite(unsigned offset, unsigned size)
prterr("domapwrite: msync");
report_failure(203);
}
check_eofpage("Write", offset, p, size);
if (munmap(p, map_size) != 0) {
prterr("domapwrite: munmap");
report_failure(204);
@ -680,14 +712,13 @@ dotruncate(unsigned size)
if (testcalls <= simulatedopcount)
return;
if ((progressinterval && testcalls % progressinterval == 0) ||
(debug && (monitorstart == -1 || monitorend == -1 ||
size <= monitorend)))
prt("%lu trunc\tfrom 0x%x to 0x%x\n", testcalls, oldsize,
size);
prt("%lu trunc\tfrom 0x%x to 0x%x\n", testcalls, oldsize, size);
if (ftruncate(fd, (off_t)size) == -1) {
prt("ftruncate1: %x\n", size);
prt("ftruncate1: %x\n", size);
prterr("dotruncate: ftruncate");
report_failure(160);
}
@ -713,7 +744,7 @@ writefileimage()
report_failure(172);
}
if (lite ? 0 : ftruncate(fd, file_size) == -1) {
prt("ftruncate2: %llx\n", (unsigned long long)file_size);
prt("ftruncate2: %llx\n", (unsigned long long)file_size);
prterr("writefileimage: ftruncate");
report_failure(173);
}
@ -722,7 +753,7 @@ writefileimage()
void
docloseopen(void)
{
{
if (testcalls <= simulatedopcount)
return;
@ -748,10 +779,10 @@ test(void)
unsigned long rv = random();
unsigned long op = rv % (3 + !lite + mapped_writes);
/* turn off the map read if necessary */
/* turn off the map read if necessary */
if (op == 2 && !mapped_reads)
op = 0;
if (op == 2 && !mapped_reads)
op = 0;
if (simulatedopcount > 0 && testcalls == simulatedopcount)
writefileimage();
@ -774,7 +805,7 @@ test(void)
* TRUNCATE: op = 3
* MAPWRITE: op = 3 or 4
*/
if (lite ? 0 : op == 3 && (style & 1) == 0) /* vanilla truncate? */
if (lite ? 0 : op == 3 && style == 0) /* vanilla truncate? */
dotruncate(random() % maxfilelen);
else {
if (randomoplen)
@ -827,16 +858,12 @@ void
usage(void)
{
fprintf(stdout, "usage: %s",
"fsx [-dnqLOW] [-b opnum] [-c Prob] [-l flen] [-m
start:end] [-o oplen] [-p progressinterval] [-r readbdy] [-s style] [-t
truncbdy] [-w writebdy] [-D startingop] [-N numops] [-P dirpath] [-S seed]
fname\n\
"fsx [-dnqLOW] [-b opnum] [-c Prob] [-l flen] [-m start:end] [-o oplen] [-p progressinterval] [-r readbdy] [-s style] [-t truncbdy] [-w writebdy] [-D startingop] [-N numops] [-P dirpath] [-S seed] fname\n\
-b opnum: beginning operation number (default 1)\n\
-c P: 1 in P chance of file close+open at each op (default infinity)\n\
-d: debug output for all operations\n\
-l flen: the upper bound on file size (default 262144)\n\
-m startop:endop: monitor (print debug output) specified byte range
(default 0:infinity)\n\
-m startop:endop: monitor (print debug output) specified byte range (default 0:infinity)\n\
-n: no verifications of file size\n\
-o oplen: the upper bound on operation size (default 65536)\n\
-p progressinterval: debug output at specified operation interval\n\
@ -849,10 +876,10 @@ fname\n\
-L: fsxLite - no file creations & no file size changes\n\
-N numops: total # operations to do (default infinity)\n\
-O: use oplen (see -o flag) for every op (default random)\n\
-P: save .fsxlog and .fsxgood files in dirpath (default ./)\n\
-P dirpath: save .fsxlog and .fsxgood files in dirpath (default ./)\n\
-S seed: for random # generator (default 1) 0 gets timestamp\n\
-W: mapped write operations DISabled\n\
-R: read() system calls only (mapped reads disabled)\n\
-R: mapped read operations DISabled)\n\
fname: this filename is REQUIRED (no default)\n");
exit(90);
}
@ -895,7 +922,7 @@ getnum(char *s, char **e)
int
main(int argc, char **argv)
{
int i, style, ch;
int i, ch;
char *endp;
char goodfile[1024];
char logfile[1024];
@ -914,8 +941,7 @@ main(int argc, char **argv)
case 'b':
simulatedopcount = getnum(optarg, &endp);
if (!quiet)
fprintf(stdout, "Will begin at operation
%ld\n",
fprintf(stdout, "Will begin at operation %ld\n",
simulatedopcount);
if (simulatedopcount == 0)
usage();
@ -992,7 +1018,7 @@ main(int argc, char **argv)
usage();
break;
case 'L':
lite = 1;
lite = 1;
break;
case 'N':
numops = getnum(optarg, &endp);
@ -1008,11 +1034,11 @@ main(int argc, char **argv)
strncpy(logfile, optarg, sizeof(logfile));
strcat(logfile, "/");
break;
case 'R':
mapped_reads = 0;
break;
case 'R':
mapped_reads = 0;
break;
case 'S':
seed = getnum(optarg, &endp);
seed = getnum(optarg, &endp);
if (seed == 0)
seed = time(0) % 10000;
if (!quiet)
@ -1021,7 +1047,7 @@ main(int argc, char **argv)
usage();
break;
case 'W':
mapped_writes = 0;
mapped_writes = 0;
if (!quiet)
fprintf(stdout, "mapped writes DISABLED\n");
break;
@ -1099,12 +1125,11 @@ main(int argc, char **argv)
prterr(fname);
warn("main: error on write");
} else
warn("main: short write, 0x%x bytes instead
of 0x%x\n",
warn("main: short write, 0x%x bytes instead of 0x%x\n",
(unsigned)written, maxfilelen);
exit(98);
}
} else
} else
check_trunc_hack();
while (numops == -1 || numops--)
@ -1119,3 +1144,4 @@ of 0x%x\n",
exit(0);
return 0;
}