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/randwritecomp.c
48674 views
1
// SPDX-License-Identifier: CDDL-1.0
2
/*
3
* This file and its contents are supplied under the terms of the
4
* Common Development and Distribution License ("CDDL"), version 1.0.
5
* You may only use this file in accordance with the terms of version
6
* 1.0 of the CDDL.
7
*
8
* A full copy of the text of the CDDL should have accompanied this
9
* source. A copy of the CDDL is also available via the Internet at
10
* http://www.illumos.org/license/CDDL.
11
*/
12
13
/*
14
* Copyright (c) 2017 by Delphix. All rights reserved.
15
*/
16
17
#include <stdint.h>
18
#include <string.h>
19
#include "file_common.h"
20
21
/*
22
* The following sample was derived from real-world data
23
* of a production Oracle database.
24
*/
25
static const uint64_t size_distribution[] = {
26
0,
27
1499018,
28
352084,
29
1503485,
30
4206227,
31
5626657,
32
5387001,
33
3733756,
34
2233094,
35
874652,
36
238635,
37
81434,
38
33357,
39
13106,
40
2009,
41
1,
42
23660,
43
};
44
45
46
static uint64_t distribution_n;
47
48
static uint8_t randbuf[BLOCKSZ];
49
50
static void
51
rwc_pwrite(int fd, const void *buf, size_t nbytes, off_t offset)
52
{
53
size_t nleft = nbytes;
54
ssize_t nwrite = 0;
55
56
nwrite = pwrite(fd, buf, nbytes, offset);
57
if (nwrite < 0) {
58
perror("pwrite");
59
exit(EXIT_FAILURE);
60
}
61
62
nleft -= nwrite;
63
if (nleft != 0) {
64
(void) fprintf(stderr, "warning: pwrite: "
65
"wrote %zu out of %zu bytes\n",
66
(nbytes - nleft), nbytes);
67
}
68
}
69
70
static void
71
fillbuf(char *buf)
72
{
73
uint64_t rv = lrand48() % distribution_n;
74
uint64_t sum = 0;
75
76
uint64_t i;
77
for (i = 0;
78
i < sizeof (size_distribution) / sizeof (size_distribution[0]);
79
i++) {
80
sum += size_distribution[i];
81
if (rv < sum)
82
break;
83
}
84
85
memcpy(buf, randbuf, BLOCKSZ);
86
if (i == 0)
87
memset(buf, 0, BLOCKSZ - 10);
88
else if (i < 16)
89
memset(buf, 0, BLOCKSZ - i * 512 + 256);
90
/*LINTED: E_BAD_PTR_CAST_ALIGN*/
91
((uint32_t *)buf)[0] = lrand48();
92
}
93
94
static void
95
exit_usage(void)
96
{
97
(void) puts("usage: randwritecomp [-s] file [nwrites]");
98
exit(EXIT_FAILURE);
99
}
100
101
static void
102
sequential_writes(int fd, char *buf, uint64_t nblocks, int64_t n)
103
{
104
for (int64_t i = 0; n == -1 || i < n; i++) {
105
fillbuf(buf);
106
107
static uint64_t j = 0;
108
if (j == 0)
109
j = lrand48() % nblocks;
110
rwc_pwrite(fd, buf, BLOCKSZ, j * BLOCKSZ);
111
j++;
112
if (j >= nblocks)
113
j = 0;
114
}
115
}
116
117
static void
118
random_writes(int fd, char *buf, uint64_t nblocks, int64_t n)
119
{
120
for (int64_t i = 0; n == -1 || i < n; i++) {
121
fillbuf(buf);
122
rwc_pwrite(fd, buf, BLOCKSZ, (lrand48() % nblocks) * BLOCKSZ);
123
}
124
}
125
126
int
127
main(int argc, char *argv[])
128
{
129
int fd, err;
130
char *filename = NULL;
131
char buf[BLOCKSZ];
132
struct stat ss;
133
uint64_t nblocks;
134
int64_t n = -1;
135
int sequential = 0;
136
137
if (argc < 2)
138
exit_usage();
139
140
argv++;
141
if (strcmp("-s", argv[0]) == 0) {
142
sequential = 1;
143
argv++;
144
}
145
146
if (argv[0] == NULL)
147
exit_usage();
148
else
149
filename = argv[0];
150
151
argv++;
152
if (argv[0] != NULL)
153
n = strtoull(argv[0], NULL, 0);
154
155
fd = open(filename, O_RDWR|O_CREAT, 0666);
156
if (fd == -1) {
157
(void) fprintf(stderr, "open(%s) failed: %s\n", filename,
158
strerror(errno));
159
exit(EXIT_FAILURE);
160
}
161
err = fstat(fd, &ss);
162
if (err != 0) {
163
(void) fprintf(stderr,
164
"error: fstat returned error code %d\n", err);
165
exit(EXIT_FAILURE);
166
}
167
168
nblocks = ss.st_size / BLOCKSZ;
169
if (nblocks == 0) {
170
(void) fprintf(stderr, "error: "
171
"file is too small (min allowed size is %d bytes)\n",
172
BLOCKSZ);
173
exit(EXIT_FAILURE);
174
}
175
176
srand48(getpid());
177
for (int i = 0; i < BLOCKSZ; i++)
178
randbuf[i] = lrand48();
179
180
distribution_n = 0;
181
for (uint64_t i = 0;
182
i < sizeof (size_distribution) / sizeof (size_distribution[0]);
183
i++) {
184
distribution_n += size_distribution[i];
185
}
186
187
if (sequential)
188
sequential_writes(fd, buf, nblocks, n);
189
else
190
random_writes(fd, buf, nblocks, n);
191
192
return (0);
193
}
194
195