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