open_by_handle: make -h (help) a valid option
[xfstests-dev.git] / src / resvtest.c
1 /*
2  * Copyright (c) 2004 Silicon Graphics, Inc.  All Rights Reserved.
3  * This program is free software; you can redistribute it and/or modify
4  * it under the terms of the GNU General Public License as published by
5  * the Free Software Foundation; either version 2 of the License, or
6  * (at your option) any later version.
7  *
8  * This program is distributed in the hope that it will be useful,
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11  * GNU General Public License for more details.
12  *
13  * You should have received a copy of the GNU General Public License
14  * along with this program; if not, write to the Free Software
15  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307
16  * USA
17  *
18  * Contact information: Silicon Graphics, Inc., 1500 Crittenden Lane,
19  * Mountain View, CA 94043, USA, or: http://www.sgi.com
20  */ 
21
22 #include "global.h"
23
24 int
25 main(int argc, char **argv)
26 {
27         int             c, i, j, n, err = 0;
28         int             writefd, readfd;
29         long            iterations = 100;
30         long            psize, bsize, leaksize = 32 * 1024 * 1024;
31         char            *filename;
32         char            *readbuffer, *writebuffer;
33         off64_t         resvsize;
34         xfs_flock64_t   resvsp;
35
36         psize = bsize = getpagesize();
37         resvsize = bsize * (off64_t) 10000;
38
39         while ((c = getopt(argc, argv, "b:i:l:s:")) != EOF) {
40                 switch(c) {
41                 case 'b':
42                         bsize = atol(optarg);
43                         break;
44                 case 'i':
45                         iterations = atol(optarg);
46                         break;
47                 case 'l':
48                         leaksize = atol(optarg);
49                         break;
50                 case 's':
51                         resvsize = (off64_t) atoll(optarg);
52                         break;
53                 default:
54                         err++;
55                         break;
56                 }
57         }
58
59         if (optind > argc + 1)
60                 err++;
61
62         if (err) {
63                 printf("Usage: %s [-b blksize] [-l leaksize] [-r resvsize]\n",
64                         argv[0]);
65                 exit(0);
66         }
67
68         filename = argv[optind];
69
70         readbuffer = memalign(psize, bsize);
71         writebuffer = memalign(psize, bsize);
72         if (!readbuffer || !writebuffer) {
73                 perror("open");
74                 exit(1);
75         }
76         memset(writebuffer, 'A', bsize);
77
78         unlink(filename);
79         writefd = open(filename, O_RDWR | O_CREAT | O_EXCL, S_IRUSR | S_IWUSR);
80         if (writefd < 0) {
81                 perror("open");
82                 exit(1);
83         }
84         readfd = open(filename, O_RDONLY);
85         if (readfd < 0) {
86                 perror("open");
87                 exit(1);
88         }
89
90         /* preallocate file space */
91         resvsp.l_whence = 0;
92         resvsp.l_start = 0;
93         resvsp.l_len = resvsize;
94         if (xfsctl(filename, writefd, XFS_IOC_RESVSP64, &resvsp) < 0) {
95                 fprintf(stdout, "attempt to reserve %lld bytes for %s "
96                                 "using %s failed: %s (%d)\n", 
97                                 (long long int)resvsize, filename, "XFS_IOC_RESVSP64",
98                                 strerror(errno), errno);
99         } else {
100                 fprintf(stdout, "reserved %lld bytes for %s using %s\n",
101                                 (long long int)resvsize, filename, "XFS_IOC_RESVSP64");
102         }
103
104         /* Space is now preallocated, start IO --
105          * write at current offset, pressurize, seek to zero on reader
106          * and read up to current write offset.
107          */
108
109         n = 0;
110         while (++n < iterations) {
111                 char *p;
112                 int numerrors;
113
114                 if (write(writefd, writebuffer, bsize) < 0) {
115                         perror("write");
116                         exit(1);
117                 }
118
119                 /* Apply some memory pressure 
120                  * (allocate another chunk and touch all pages)
121                  */
122                 for (i = 0; i < (leaksize / psize); i++) {
123                         p = malloc(psize);
124                         if (p)
125                                 p[7] = '7';
126                 }
127                 sleep(1);
128                 lseek(readfd, SEEK_SET, 0);
129                 numerrors = 0;
130                 for (j = 0; j < n; j++) {
131                         if (read(readfd, readbuffer, bsize) < 0) {
132                                 perror("read");
133                                 exit(1);
134                         }
135                         for (i = 0; i < bsize; i++) {
136                                 if (readbuffer[i] != 'A') {
137                                         fprintf(stderr,
138 "errors detected in file, pos: %d (%lld+%d), nwrites: %d [val=0x%x].\n",
139                                                 j, (long long)j * 4096,
140                                                 i, n, readbuffer[i]);
141                                         numerrors++;
142                                         break;
143                                 }
144                         }
145                 }
146                 if (numerrors > 10) {
147                         exit(1);
148                 } else if (numerrors) {
149                         fprintf(stdout, "\n");
150                 }
151         }
152
153         return(0);
154 }