| // SPDX-License-Identifier: GPL-2.0 |
| /* |
| * Copyright (c) 2000-2001 Silicon Graphics, Inc. |
| * All Rights Reserved. |
| */ |
| |
| #include "global.h" |
| |
| long filesize; |
| int blocksize; |
| int count; |
| int verbose; |
| off64_t fileoffset; |
| |
| void usage(char *progname); |
| void writeblk(int fd); |
| void truncfile(int fd); |
| |
| void |
| usage(char *progname) |
| { |
| fprintf(stderr, "usage: %s [-l filesize] [-b blocksize] [-c count] [-s seed] [-o fileoffset (hex)] [-v] filename\n", |
| progname); |
| exit(1); |
| } |
| |
| int |
| main(int argc, char *argv[]) |
| { |
| int seed, i, ch, fd; |
| char *filename = NULL; |
| |
| filesize = 256*1024*1024; |
| blocksize = 512; |
| count = filesize/blocksize; |
| verbose = 0; |
| fileoffset = 0; |
| seed = time(NULL); |
| while ((ch = getopt(argc, argv, "b:l:s:c:o:v")) != EOF) { |
| switch(ch) { |
| case 'b': blocksize = atoi(optarg); break; |
| case 'l': filesize = atol(optarg); break; |
| case 's': seed = atoi(optarg); break; |
| case 'c': count = atoi(optarg); break; |
| case 'o': fileoffset = strtoll(optarg, NULL, 16); break; |
| case 'v': verbose++; break; |
| default: usage(argv[0]); break; |
| } |
| } |
| if (optind == argc-1) |
| filename = argv[optind]; |
| else |
| usage(argv[0]); |
| printf("Seed = %d (use \"-s %d\" to re-execute this test)\n", seed, seed); |
| srandom(seed); |
| |
| /* |
| * Open the file, write rand block in random places, truncate the file, |
| * repeat ad-nauseum, then close the file. |
| */ |
| if ((fd = open(filename, O_RDWR|O_CREAT|O_TRUNC, 0666)) < 0) { |
| perror("open"); |
| return 1; |
| } |
| for (i = 0; i < count; i++) { |
| writeblk(fd); |
| truncfile(fd); |
| if (verbose && ((i % 100) == 0)) { |
| printf("."); |
| fflush(stdout); |
| } |
| } |
| if (close(fd) < 0) { |
| perror("close"); |
| return 1; |
| } |
| return 0; |
| } |
| |
| void |
| writeblk(int fd) |
| { |
| off_t offset; |
| static char *buffer = NULL; |
| |
| if ((buffer == NULL) && ((buffer = calloc(1, blocksize)) == NULL)) { |
| perror("malloc"); |
| exit(1); |
| } |
| |
| offset = random() % filesize; |
| if (lseek64(fd, (off64_t)(fileoffset + offset), SEEK_SET) < 0) { |
| perror("lseek"); |
| exit(1); |
| } |
| *(long *)buffer = *(long *)(buffer+256) = (long)offset; |
| if (write(fd, buffer, blocksize) < blocksize) { |
| perror("write"); |
| exit(1); |
| } |
| if (verbose > 1) |
| printf("writing data at offset=%llx\n", |
| (unsigned long long)(fileoffset + offset)); |
| } |
| |
| void |
| truncfile(int fd) |
| { |
| off_t offset; |
| |
| offset = random() % filesize; |
| if (ftruncate64(fd, (off64_t)(fileoffset + offset)) < 0) { |
| perror("truncate"); |
| exit(1); |
| } |
| if (verbose > 1) |
| printf("truncated file to offset %llx\n", |
| (unsigned long long)(fileoffset + offset)); |
| } |