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_write.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
#include "file_common.h"
29
#include <libgen.h>
30
#include <string.h>
31
#include <inttypes.h>
32
#include <sys/types.h>
33
#include <unistd.h>
34
#include <stdlib.h>
35
#include <time.h>
36
#include <stdint.h>
37
38
static unsigned char bigbuffer[BIGBUFFERSIZE];
39
40
/*
41
* Writes (or appends) a given value to a file repeatedly.
42
* See header file for defaults.
43
*/
44
45
static void usage(char *);
46
47
/*
48
* pseudo-randomize the buffer
49
*/
50
static void randomize_buffer(int block_size) {
51
int i;
52
char rnd = rand() & 0xff;
53
for (i = 0; i < block_size; i++)
54
bigbuffer[i] ^= rnd;
55
}
56
57
int
58
main(int argc, char **argv)
59
{
60
int bigfd;
61
int c;
62
int oflag = 0;
63
int err = 0;
64
int k;
65
long i;
66
int64_t good_writes = 0;
67
uchar_t nxtfillchar;
68
char *prog = argv[0];
69
/*
70
* Default Parameters
71
*/
72
int write_count = BIGFILESIZE;
73
uchar_t fillchar = DATA;
74
int block_size = BLOCKSZ;
75
char *filename = NULL;
76
char *operation = NULL;
77
offset_t noffset, offset = 0;
78
int verbose = 0;
79
int rsync = 0;
80
int wsync = 0;
81
82
/*
83
* Process Arguments
84
*/
85
while ((c = getopt(argc, argv, "b:c:d:s:f:o:vwr")) != -1) {
86
switch (c) {
87
case 'b':
88
block_size = atoi(optarg);
89
break;
90
case 'c':
91
write_count = atoi(optarg);
92
break;
93
case 'd':
94
if (optarg[0] == 'R')
95
fillchar = 'R'; /* R = random data */
96
else
97
fillchar = atoi(optarg);
98
break;
99
case 's':
100
offset = atoll(optarg);
101
break;
102
case 'f':
103
filename = optarg;
104
break;
105
case 'o':
106
operation = optarg;
107
break;
108
case 'v':
109
verbose = 1;
110
break;
111
case 'w':
112
wsync = 1;
113
break;
114
case 'r':
115
rsync = 1;
116
break;
117
case '?':
118
(void) printf("unknown arg %c\n", optopt);
119
usage(prog);
120
break;
121
}
122
}
123
124
/*
125
* Validate Parameters
126
*/
127
if (!filename) {
128
(void) printf("Filename not specified (-f <file>)\n");
129
err++;
130
}
131
132
if (!operation) {
133
(void) printf("Operation not specified (-o <operation>).\n");
134
err++;
135
}
136
137
if (block_size > BIGBUFFERSIZE) {
138
(void) printf("block_size is too large max==%d.\n",
139
BIGBUFFERSIZE);
140
err++;
141
}
142
143
if (err) {
144
usage(prog); /* no return */
145
return (1);
146
}
147
148
/*
149
* Prepare the buffer and determine the requested operation
150
*/
151
nxtfillchar = fillchar;
152
k = 0;
153
154
if (fillchar == 'R')
155
srand(time(NULL));
156
157
for (i = 0; i < block_size; i++) {
158
bigbuffer[i] = nxtfillchar;
159
160
if (fillchar == 0) {
161
if ((k % DATA_RANGE) == 0) {
162
k = 0;
163
}
164
nxtfillchar = k++;
165
} else if (fillchar == 'R') {
166
nxtfillchar = rand() & 0xff;
167
}
168
}
169
170
/*
171
* using the strncmp of operation will make the operation match the
172
* first shortest match - as the operations are unique from the first
173
* character this means that we match single character operations
174
*/
175
if ((strncmp(operation, "create", strlen(operation) + 1)) == 0 ||
176
(strncmp(operation, "overwrite", strlen(operation) + 1)) == 0) {
177
oflag = (O_RDWR|O_CREAT);
178
} else if ((strncmp(operation, "append", strlen(operation) + 1)) == 0) {
179
oflag = (O_RDWR|O_APPEND);
180
} else {
181
(void) printf("valid operations are <create|append> not '%s'\n",
182
operation);
183
usage(prog);
184
}
185
186
if (rsync) {
187
oflag = oflag | O_RSYNC;
188
}
189
190
if (wsync) {
191
oflag = oflag | O_SYNC;
192
}
193
194
/*
195
* Given an operation (create/overwrite/append), open the file
196
* accordingly and perform a write of the appropriate type.
197
*/
198
if ((bigfd = open(filename, oflag, 0666)) == -1) {
199
(void) printf("open %s: failed [%s]%d. Aborting!\n", filename,
200
strerror(errno), errno);
201
exit(errno);
202
}
203
noffset = lseek64(bigfd, offset, SEEK_SET);
204
if (noffset != offset) {
205
(void) printf("llseek %s (%lld/%lld) failed [%s]%d.Aborting!\n",
206
filename, offset, noffset, strerror(errno), errno);
207
exit(errno);
208
}
209
210
if (verbose) {
211
(void) printf("%s: block_size = %d, write_count = %d, "
212
"offset = %lld, ", filename, block_size,
213
write_count, offset);
214
if (fillchar == 'R') {
215
(void) printf("data = [random]\n");
216
} else {
217
(void) printf("data = %s%d\n",
218
(fillchar == 0) ? "0->" : "",
219
(fillchar == 0) ? DATA_RANGE : fillchar);
220
}
221
}
222
223
for (i = 0; i < write_count; i++) {
224
ssize_t n;
225
if (fillchar == 'R')
226
randomize_buffer(block_size);
227
228
if ((n = write(bigfd, &bigbuffer, block_size)) == -1) {
229
(void) printf("write failed (%ld), good_writes = %"
230
PRId64 ", " "error: %s[%d]\n",
231
(long)n, good_writes,
232
strerror(errno),
233
errno);
234
exit(errno);
235
}
236
good_writes++;
237
}
238
239
if (verbose) {
240
(void) printf("Success: good_writes = %" PRId64 "(%"
241
PRId64 ")\n", good_writes, (good_writes * block_size));
242
}
243
244
return (0);
245
}
246
247
static void
248
usage(char *prog)
249
{
250
(void) printf("Usage: %s [-v] -o {create,overwrite,append} -f file_name"
251
" [-b block_size]\n"
252
"\t[-s offset] [-c write_count] [-d data]\n\n"
253
"Where [data] equal to zero causes chars "
254
"0->%d to be repeated throughout, or [data]\n"
255
"equal to 'R' for pseudorandom data.\n",
256
prog, DATA_RANGE);
257
258
exit(1);
259
}
260
261