1 // SPDX-License-Identifier: GPL-2.0
3 * Copyright (c) 2000-2001 Silicon Graphics, Inc.
9 int verbose; /* print lots of debugging info */
11 void usage(char *progname);
12 void writeblks(int fd, long filesize, int blocksize,
13 int interleave, int base, int rev);
14 int readblks(int fd, long filesize, int blocksize,
15 int interleave, int count);
20 fprintf(stderr, "usage: %s [-l filesize] [-b blocksize] [-i interleave]\n"
21 "\t\t[-c count] [-r(everse)] [-v(erbose)] filename\n",
27 main(int argc, char *argv[])
29 int interleave, blocksize, count, rev, i, ch, fd;
31 char *filename = NULL;
36 count = interleave = 4;
38 while ((ch = getopt(argc, argv, "b:l:i:c:rv")) != EOF) {
40 case 'b': blocksize = atoi(optarg); break;
41 case 'c': count = atoi(optarg); break;
42 case 'i': interleave = atoi(optarg); break;
43 case 'l': filesize = atol(optarg); break;
44 case 'v': verbose++; break;
45 case 'r': rev++; break;
46 default: usage(argv[0]); break;
50 filename = argv[optind];
53 if ((filesize % (blocksize*interleave)) != 0) {
54 filesize -= filesize % (blocksize * interleave);
55 printf("filesize not a multiple of blocksize*interleave,\n");
56 printf("reducing filesize to %ld\n", filesize);
58 if (count > interleave) {
60 printf("count of passes is too large, setting to %d\n", count);
61 } else if (count < 1) {
63 printf("count of passes is too small, setting to %d\n", count);
66 if ((fd = open(filename, O_RDWR|O_CREAT|O_TRUNC, 0666)) < 0) {
72 * Avoid allocation patterns being perturbed by different speculative
73 * preallocation beyond EOF configurations by first truncating the file
74 * to the expected maximum file size.
76 if (ftruncate(fd, filesize) < 0) {
81 for (i = 0; i < count; i++) {
82 writeblks(fd, filesize, blocksize, interleave, i, rev);
84 errs=readblks(fd, filesize, blocksize, interleave, count);
90 printf("%d errors detected during readback\n", errs);
97 writeblks(int fd, long filesize, int blocksize, int interleave, int base, int rev)
102 if ((buffer = calloc(1, blocksize)) == NULL) {
108 offset = (filesize-blocksize) - (base * blocksize);
110 offset = base * blocksize;
113 if (lseek(fd, offset, SEEK_SET) < 0) {
117 *(long *)buffer = *(long *)(buffer+256) = offset;
118 if (write(fd, buffer, blocksize) < blocksize) {
123 printf("writing data at offset=%ld, delta=%d, value 0x%lx and 0x%lx\n",
124 offset-base*blocksize, base,
126 *(long *)(buffer+256));
130 offset -= interleave*blocksize;
134 offset += interleave*blocksize;
135 if (offset >= filesize)
141 /* pad file out to full length */
143 if (lseek(fd, filesize-1, SEEK_SET)<0) {
147 if (write(fd, zero, 1)!=1) {
157 readblks(int fd, long filesize, int blocksize, int interleave, int count)
164 if ((buffer = calloc(interleave, blocksize)) == NULL) {
168 xfer = interleave * blocksize;
170 if (lseek(fd, (long)0, SEEK_SET) < 0) {
174 for (offset = 0; offset < filesize; offset += xfer) {
175 if ((i = read(fd, buffer, xfer) < xfer)) {
180 printf("short read: %d of %d bytes read\n", i, xfer);
184 for (tmp = buffer, i = 0; i < count; i++, tmp += blocksize) {
185 if ( (*(long *)tmp != (offset+i*blocksize)) ||
186 (*(long *)(tmp+256) != (offset+i*blocksize)) ) {
187 printf("mismatched data at offset=%ld, delta=%d, expected 0x%lx, got 0x%lx and 0x%lx\n",