4130e2dd98e1987bd812ad5728c544731f232fa5
[xfstests-dev.git] / src / truncfile.c
1 /*
2  * Copyright (c) 2000-2001 Silicon Graphics, Inc.
3  * All Rights Reserved.
4  *
5  * This program is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU General Public License as
7  * published by the Free Software Foundation.
8  *
9  * This program is distributed in the hope that it would be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write the Free Software Foundation,
16  * Inc.,  51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
17  */
18  
19 #include "global.h"
20
21 long filesize;
22 int blocksize;
23 int count;
24 int verbose;
25 off64_t fileoffset;
26
27 void usage(char *progname);
28 void writeblk(int fd);
29 void truncfile(int fd);
30
31 void
32 usage(char *progname)
33 {
34         fprintf(stderr, "usage: %s [-l filesize] [-b blocksize] [-c count] [-s seed] [-o fileoffset (hex)] [-v] filename\n",
35                         progname);
36         exit(1);
37 }
38
39 int
40 main(int argc, char *argv[])
41 {
42         int seed, i, ch, fd;
43         char *filename = NULL;
44
45         filesize = 256*1024*1024;
46         blocksize = 512;
47         count = filesize/blocksize;
48         verbose = 0;
49         fileoffset = 0;
50         seed = time(NULL);
51         while ((ch = getopt(argc, argv, "b:l:s:c:o:v")) != EOF) {
52                 switch(ch) {
53                 case 'b':       blocksize  = atoi(optarg);      break;
54                 case 'l':       filesize   = atol(optarg);      break;
55                 case 's':       seed       = atoi(optarg);      break;
56                 case 'c':       count      = atoi(optarg);      break;
57                 case 'o':       fileoffset = strtoll(optarg, NULL, 16); break;
58                 case 'v':       verbose++;                      break;
59                 default:        usage(argv[0]);                 break;
60                 }
61         }
62         if (optind == argc-1)
63                 filename = argv[optind];
64         else
65                 usage(argv[0]);
66         printf("Seed = %d (use \"-s %d\" to re-execute this test)\n", seed, seed);
67         srandom(seed);
68
69         /*
70          * Open the file, write rand block in random places, truncate the file,
71          * repeat ad-nauseum, then close the file.
72          */
73         if ((fd = open(filename, O_RDWR|O_CREAT|O_TRUNC, 0666)) < 0) {
74                 perror("open");
75                 return 1;
76         }
77         for (i = 0; i < count; i++) {
78                 writeblk(fd);
79                 truncfile(fd);
80                 if (verbose && ((i % 100) == 0)) {
81                         printf(".");
82                         fflush(stdout);
83                 }
84         }
85         if (close(fd) < 0) {
86                 perror("close");
87                 return 1;
88         }
89         return 0;
90 }
91
92 void
93 writeblk(int fd)
94 {
95         off_t offset;
96         static char *buffer = NULL;
97
98         if ((buffer == NULL) && ((buffer = calloc(1, blocksize)) == NULL)) {
99                 perror("malloc");
100                 exit(1);
101         }
102
103         offset = random() % filesize;
104         if (lseek64(fd, (off64_t)(fileoffset + offset), SEEK_SET) < 0) {
105                 perror("lseek");
106                 exit(1);
107         }
108         *(long *)buffer = *(long *)(buffer+256) = (long)offset;
109         if (write(fd, buffer, blocksize) < blocksize) {
110                 perror("write");
111                 exit(1);
112         }
113         if (verbose > 1)
114                 printf("writing   data at offset=%llx\n",
115                        (unsigned long long)(fileoffset + offset));
116 }
117
118 void
119 truncfile(int fd)
120 {
121         off_t offset;
122
123         offset = random() % filesize;
124         if (ftruncate64(fd, (off64_t)(fileoffset + offset)) < 0) {
125                 perror("truncate");
126                 exit(1);
127         }
128         if (verbose > 1)
129                 printf("truncated file to offset %llx\n",
130                        (unsigned long long)(fileoffset + offset));
131 }