Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/sys/contrib/openzfs/tests/zfs-tests/cmd/file/file_trunc.c
48674 views
1
// SPDX-License-Identifier: CDDL-1.0
2
/*
3
* CDDL HEADER START
4
*
5
* The contents of this file are subject to the terms of the
6
* Common Development and Distribution License (the "License").
7
* You may not use this file except in compliance with the License.
8
*
9
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10
* or https://opensource.org/licenses/CDDL-1.0.
11
* See the License for the specific language governing permissions
12
* and limitations under the License.
13
*
14
* When distributing Covered Code, include this CDDL HEADER in each
15
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16
* If applicable, add the following below this CDDL HEADER, with the
17
* fields enclosed by brackets "[]" replaced with your own identifying
18
* information: Portions Copyright [yyyy] [name of copyright owner]
19
*
20
* CDDL HEADER END
21
*/
22
23
/*
24
* Copyright 2007 Sun Microsystems, Inc. All rights reserved.
25
* Use is subject to license terms.
26
*/
27
28
/*
29
* Copyright (c) 2012, 2014 by Delphix. All rights reserved.
30
*/
31
32
#include <stdio.h>
33
#include <stdlib.h>
34
#include <unistd.h>
35
#include <limits.h>
36
#include <errno.h>
37
#include <fcntl.h>
38
#include <sys/types.h>
39
#include <sys/stat.h>
40
#include <sys/statvfs.h>
41
#include <sys/time.h>
42
#include <sys/ioctl.h>
43
#include <sys/wait.h>
44
#include <sys/param.h>
45
#include <string.h>
46
#include <time.h>
47
#include <inttypes.h>
48
49
#define FSIZE 256*1024*1024
50
#define BSIZE 512
51
52
/* Initialize Globals */
53
static long fsize = FSIZE;
54
static size_t bsize = BSIZE;
55
static int count = 0;
56
static int rflag = 0;
57
static uint_t seed = 0;
58
static int vflag = 0;
59
static int errflag = 0;
60
static off_t offset = 0;
61
static char *filename = NULL;
62
63
static void usage(char *execname);
64
static void parse_options(int argc, char *argv[]);
65
static void do_write(int fd);
66
static void do_trunc(int fd);
67
68
static void
69
usage(char *execname)
70
{
71
(void) fprintf(stderr,
72
"usage: %s [-b blocksize] [-c count] [-f filesize]"
73
" [-o offset] [-s seed] [-r] [-v] filename\n", execname);
74
(void) exit(1);
75
}
76
77
int
78
main(int argc, char *argv[])
79
{
80
int i = 0;
81
int fd = -1;
82
83
parse_options(argc, argv);
84
85
fd = open(filename, O_RDWR|O_CREAT|O_TRUNC, 0666);
86
if (fd < 0) {
87
perror("open");
88
exit(3);
89
}
90
91
for (i = 0; count == 0 || i < count; i++) {
92
(void) do_write(fd);
93
(void) do_trunc(fd);
94
}
95
96
(void) close(fd);
97
return (0);
98
}
99
100
static void
101
parse_options(int argc, char *argv[])
102
{
103
int c;
104
105
extern char *optarg;
106
extern int optind, optopt;
107
108
count = fsize / bsize;
109
seed = (uint_t)time(NULL);
110
while ((c = getopt(argc, argv, "b:c:f:o:rs:v")) != -1) {
111
switch (c) {
112
case 'b':
113
bsize = atoi(optarg);
114
break;
115
116
case 'c':
117
count = atoi(optarg);
118
break;
119
120
case 'f':
121
fsize = atoi(optarg);
122
break;
123
124
case 'o':
125
offset = atoi(optarg);
126
break;
127
128
case 'r':
129
rflag++;
130
break;
131
132
case 's':
133
seed = atoi(optarg);
134
break;
135
136
case 'v':
137
vflag++;
138
break;
139
140
case ':':
141
(void) fprintf(stderr,
142
"Option -%c requires an operand\n", optopt);
143
errflag++;
144
break;
145
146
case '?':
147
(void) fprintf(stderr,
148
"Unrecognized option: -%c\n", optopt);
149
errflag++;
150
break;
151
}
152
153
if (errflag) {
154
(void) usage(argv[0]);
155
}
156
}
157
if (argc <= optind) {
158
(void) fprintf(stderr,
159
"No filename specified\n");
160
usage(argv[0]);
161
}
162
filename = argv[optind];
163
164
if (vflag) {
165
(void) fprintf(stderr, "Seed = %d\n", seed);
166
}
167
srandom(seed);
168
}
169
170
static void
171
do_write(int fd)
172
{
173
off_t roffset = 0;
174
char *buf = NULL;
175
char *rbuf = NULL;
176
177
buf = (char *)calloc(1, bsize);
178
rbuf = (char *)calloc(1, bsize);
179
if (buf == NULL || rbuf == NULL) {
180
perror("malloc");
181
exit(4);
182
}
183
184
roffset = random() % fsize;
185
if (lseek64(fd, (offset + roffset), SEEK_SET) < 0) {
186
perror("lseek");
187
exit(5);
188
}
189
190
(void) strcpy(buf, "ZFS Test Suite Truncation Test");
191
if (write(fd, buf, bsize) < bsize) {
192
perror("write");
193
exit(6);
194
}
195
196
if (rflag) {
197
if (lseek64(fd, (offset + roffset), SEEK_SET) < 0) {
198
perror("lseek");
199
exit(7);
200
}
201
202
if (read(fd, rbuf, bsize) < bsize) {
203
perror("read");
204
exit(8);
205
}
206
207
if (memcmp(buf, rbuf, bsize) != 0) {
208
perror("memcmp");
209
exit(9);
210
}
211
}
212
if (vflag) {
213
(void) fprintf(stderr,
214
"Wrote to offset %" PRId64 "\n", (offset + roffset));
215
if (rflag) {
216
(void) fprintf(stderr,
217
"Read back from offset %" PRId64 "\n",
218
(offset + roffset));
219
}
220
}
221
222
(void) free(buf);
223
(void) free(rbuf);
224
}
225
226
static void
227
do_trunc(int fd)
228
{
229
off_t roffset = 0;
230
231
roffset = random() % fsize;
232
if (ftruncate64(fd, (offset + roffset)) < 0) {
233
perror("truncate");
234
exit(7);
235
}
236
237
if (vflag) {
238
(void) fprintf(stderr, "Truncated at offset %" PRId64 "\n",
239
(offset + roffset));
240
}
241
}
242
243