Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/tests/sys/cddl/zfs/bin/file_write.c
39536 views
1
/*
2
* CDDL HEADER START
3
*
4
* The contents of this file are subject to the terms of the
5
* Common Development and Distribution License (the "License").
6
* You may not use this file except in compliance with the License.
7
*
8
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9
* or http://www.opensolaris.org/os/licensing.
10
* See the License for the specific language governing permissions
11
* and limitations under the License.
12
*
13
* When distributing Covered Code, include this CDDL HEADER in each
14
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15
* If applicable, add the following below this CDDL HEADER, with the
16
* fields enclosed by brackets "[]" replaced with your own identifying
17
* information: Portions Copyright [yyyy] [name of copyright owner]
18
*
19
* CDDL HEADER END
20
*/
21
22
/*
23
* Copyright 2007 Sun Microsystems, Inc. All rights reserved.
24
* Use is subject to license terms.
25
*/
26
27
28
#include "file_common.h"
29
#include <inttypes.h>
30
#include <libgen.h>
31
32
static unsigned char bigbuffer[BIGBUFFERSIZE];
33
34
/*
35
* Writes (or appends) a given value to a file repeatedly.
36
* See header file for defaults.
37
*/
38
39
static void usage(void) __dead2;
40
static char *execname;
41
42
int
43
main(int argc, char **argv)
44
{
45
int bigfd;
46
int c;
47
int oflag = 0;
48
int err = 0;
49
int k;
50
long i;
51
int64_t good_writes = 0;
52
uint8_t nxtfillchar;
53
/*
54
* Default Parameters
55
*/
56
int write_count = BIGFILESIZE;
57
uint8_t fillchar = DATA;
58
int block_size = BLOCKSZ;
59
char *filename = NULL;
60
char *operation = NULL;
61
off_t noffset, offset = 0;
62
int verbose = 0;
63
int rsync = 0;
64
int wsync = 0;
65
66
execname = argv[0];
67
68
/*
69
* Process Arguments
70
*/
71
while ((c = getopt(argc, argv, "b:c:d:s:f:o:vwr")) != -1) {
72
switch (c) {
73
case 'b':
74
block_size = atoi(optarg);
75
break;
76
case 'c':
77
write_count = atoi(optarg);
78
break;
79
case 'd':
80
fillchar = atoi(optarg);
81
break;
82
case 's':
83
offset = atoll(optarg);
84
break;
85
case 'f':
86
filename = optarg;
87
break;
88
case 'o':
89
operation = optarg;
90
break;
91
case 'v':
92
verbose = 1;
93
break;
94
case 'w':
95
wsync = 1;
96
break;
97
case 'r':
98
rsync = 1;
99
break;
100
case '?':
101
(void) printf("unknown arg %c\n", optopt);
102
usage();
103
break;
104
}
105
}
106
107
/*
108
* Validate Parameters
109
*/
110
if (!filename) {
111
(void) printf("Filename not specified (-f <file>)\n");
112
err++;
113
}
114
115
if (!operation) {
116
(void) printf("Operation not specified (-o <operation>).\n");
117
err++;
118
}
119
120
if (block_size > BIGBUFFERSIZE) {
121
(void) printf("block_size is too large max==%d.\n",
122
BIGBUFFERSIZE);
123
err++;
124
}
125
126
if (err) usage();
127
128
/*
129
* Prepare the buffer and determine the requested operation
130
*/
131
nxtfillchar = fillchar;
132
k = 0;
133
134
for (i = 0; i < block_size; i++) {
135
bigbuffer[i] = nxtfillchar;
136
137
if (fillchar == 0) {
138
if ((k % DATA_RANGE) == 0) {
139
k = 0;
140
}
141
nxtfillchar = k++;
142
}
143
}
144
145
/*
146
* using the strncmp of operation will make the operation match the
147
* first shortest match - as the operations are unique from the first
148
* character this means that we match single character operations
149
*/
150
if ((strncmp(operation, "create", strlen(operation) + 1)) == 0 ||
151
(strncmp(operation, "overwrite", strlen(operation) + 1)) == 0) {
152
oflag = (O_RDWR|O_CREAT);
153
} else if ((strncmp(operation, "append", strlen(operation) + 1)) == 0) {
154
oflag = (O_RDWR|O_APPEND);
155
} else {
156
(void) printf("valid operations are <create|append> not '%s'\n",
157
operation);
158
usage();
159
}
160
161
#ifdef UNSUPPORTED
162
if (rsync) {
163
oflag = oflag | O_RSYNC;
164
}
165
#endif
166
167
if (wsync) {
168
oflag = oflag | O_SYNC;
169
}
170
171
/*
172
* Given an operation (create/overwrite/append), open the file
173
* accordingly and perform a write of the appropriate type.
174
*/
175
if ((bigfd = open(filename, oflag, 0666)) == -1) {
176
(void) printf("open %s: failed [%s]%d. Aborting!\n", filename,
177
strerror(errno), errno);
178
exit(errno);
179
}
180
noffset = lseek(bigfd, offset, SEEK_SET);
181
if (noffset != offset) {
182
(void) printf("lseek %s (%"PRId64"/%"PRId64") "
183
"failed [%s]%d. Aborting!\n",
184
filename, offset, noffset, strerror(errno), errno);
185
exit(errno);
186
}
187
188
if (verbose) {
189
(void) printf("%s: block_size = %d, write_count = %d, "
190
"offset = %"PRId64", data = %s%d\n", filename, block_size,
191
write_count, offset,
192
(fillchar == 0) ? "0->" : "",
193
(fillchar == 0) ? DATA_RANGE : fillchar);
194
}
195
196
for (i = 0; i < write_count; i++) {
197
ssize_t n;
198
199
if ((n = write(bigfd, &bigbuffer, block_size)) == -1) {
200
(void) printf("write failed (%ld), "
201
"good_writes = %"PRId64", "
202
"error: %s[%d]\n", (long)n, good_writes,
203
strerror(errno), errno);
204
exit(errno);
205
}
206
good_writes++;
207
}
208
209
if (verbose) {
210
(void) printf("Success: good_writes = %"PRId64" (%"PRId64")\n",
211
good_writes, (good_writes * block_size));
212
}
213
214
return (0);
215
}
216
217
static void
218
usage(void)
219
{
220
char *base = (char *)"file_write";
221
char *exec = (char *)execname;
222
223
if (exec != NULL)
224
exec = strdup(exec);
225
if (exec != NULL)
226
base = basename(exec);
227
228
(void) printf("Usage: %s [-v] -o {create,overwrite,append} -f file_name"
229
" [-b block_size]\n"
230
"\t[-s offset] [-c write_count] [-d data]\n"
231
"\twhere [data] equal to zero causes chars "
232
"0->%d to be repeated throughout\n", base, DATA_RANGE);
233
234
if (exec) {
235
free(exec);
236
}
237
238
exit(1);
239
}
240
241