Skip to content

Commit 16067e9

Browse files
committed
stress-copy-file: add --copy-file-io-bytes option
This new option specifies the copy_file_range copy size, the default is 128K, range 4K to 1MB Signed-off-by: Colin Ian King <colin.i.king@gmail.com>
1 parent 7497d56 commit 16067e9

4 files changed

Lines changed: 53 additions & 23 deletions

File tree

core-opts.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -208,6 +208,7 @@ const struct option stress_long_options[] = {
208208

209209
{ "copy-file", 1, NULL, OPT_copy_file },
210210
{ "copy-file-bytes", 1, NULL, OPT_copy_file_bytes },
211+
{ "copy-file-io-bytes", 1, NULL, OPT_copy_file_io_bytes },
211212
{ "copy-file-ops", 1, NULL, OPT_copy_file_ops },
212213

213214
{ "cpu", 1, NULL, OPT_cpu },

core-opts.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -334,6 +334,7 @@ typedef enum {
334334

335335
OPT_copy_file,
336336
OPT_copy_file_bytes,
337+
OPT_copy_file_io_bytes,
337338
OPT_copy_file_ops,
338339

339340
OPT_cpu_load_slice,

stress-copy-file.c

Lines changed: 48 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -19,29 +19,35 @@
1919
*/
2020
#include "stress-ng.h"
2121
#include "core-builtin.h"
22+
#include "core-mmap.h"
2223

23-
#define MIN_COPY_FILE_BYTES (128 * MB)
24-
#define MAX_COPY_FILE_BYTES (MAX_FILE_LIMIT)
25-
#define DEFAULT_COPY_FILE_BYTES (256 * MB)
26-
#define DEFAULT_COPY_FILE_SIZE (128 * KB)
24+
#define MIN_COPY_FILE_BYTES (128 * MB)
25+
#define MAX_COPY_FILE_BYTES (MAX_FILE_LIMIT)
26+
#define DEFAULT_COPY_FILE_BYTES (256 * MB)
27+
28+
#define MIN_COPY_FILE_IO_BYTES (4 * KB)
29+
#define MAX_COPY_FILE_IO_BYTES (1 * MB)
30+
#define DEFAULT_COPY_FILE_IO_BYTES (128 * KB)
31+
32+
#define COPY_FILE_MAX_BUF_SIZE (4096)
2733

2834
static const stress_help_t help[] = {
2935
{ NULL, "copy-file N", "start N workers that copy file data" },
3036
{ NULL, "copy-file-bytes N", "specify size of file to be copied" },
37+
{ NULL, "copy-file-io-bytes N", "specify copying I/O size" },
3138
{ NULL, "copy-file-ops N", "stop after N copy bogo operations" },
3239
{ NULL, NULL, NULL }
3340

3441
};
3542

3643
static const stress_opt_t opts[] = {
37-
{ OPT_copy_file_bytes, "copy-file-bytes", TYPE_ID_UINT64_BYTES_FS, MIN_COPY_FILE_BYTES, MAX_COPY_FILE_BYTES, NULL },
44+
{ OPT_copy_file_bytes, "copy-file-bytes", TYPE_ID_UINT64_BYTES_FS, MIN_COPY_FILE_BYTES, MAX_COPY_FILE_BYTES, NULL },
45+
{ OPT_copy_file_io_bytes, "copy-file-io-bytes", TYPE_ID_SIZE_T_BYTES, MIN_COPY_FILE_IO_BYTES, MAX_COPY_FILE_IO_BYTES, NULL },
3846
END_OPT,
3947
};
4048

4149
#if defined(HAVE_COPY_FILE_RANGE)
4250

43-
#define COPY_FILE_MAX_BUF_SIZE (4096)
44-
4551
/*
4652
* stress_copy_file_seek64()
4753
* seek with off64_t
@@ -70,19 +76,19 @@ static int stress_copy_file_fill(
7076
stress_args_t *args,
7177
const int fd,
7278
const shim_off64_t off64,
73-
const ssize_t size)
79+
char * const buf,
80+
const size_t buf_len)
7481
{
75-
char buf[COPY_FILE_MAX_BUF_SIZE];
76-
ssize_t sz = size;
77-
78-
(void)shim_memset(buf, stress_mwc8(), sizeof(buf));
82+
register ssize_t sz = buf_len;
7983

8084
if (stress_copy_file_seek64(fd, off64, SEEK_SET) < 0)
8185
return -1;
8286

87+
(void)shim_memset(buf, stress_mwc8(), buf_len);
88+
8389
while (sz > 0) {
8490
ssize_t n;
85-
const ssize_t wr_size = sz > (ssize_t)sizeof(buf) ? (ssize_t)sizeof(buf) : sz;
91+
const ssize_t wr_size = sz > (ssize_t)buf_len ? (ssize_t)buf_len : sz;
8692

8793
n = write(fd, buf, wr_size);
8894
if (n < 0)
@@ -159,12 +165,28 @@ static int stress_copy_file(stress_args_t *args)
159165
const int fd_bad = stress_fs_bad_fd_get();
160166
char filename[PATH_MAX - 5];
161167
char tmp[PATH_MAX];
168+
size_t copy_file_io_bytes = DEFAULT_COPY_FILE_IO_BYTES;
162169
uint64_t copy_file_bytes;
163170
uint64_t copy_file_bytes_total = DEFAULT_COPY_FILE_BYTES;
164171
double duration = 0.0;
165172
double bytes = 0.0;
166173
double rate;
167174
const bool verify = !!(g_opt_flags & OPT_FLAGS_VERIFY);
175+
char *buf;
176+
177+
if (!stress_setting_get("copy-file-io-bytes", &copy_file_io_bytes)) {
178+
if (g_opt_flags & OPT_FLAGS_MAXIMIZE)
179+
copy_file_io_bytes = MAX_COPY_FILE_IO_BYTES;
180+
if (g_opt_flags & OPT_FLAGS_MINIMIZE)
181+
copy_file_io_bytes = MIN_COPY_FILE_IO_BYTES;
182+
}
183+
buf = stress_mmap_populate(NULL, copy_file_io_bytes, PROT_READ | PROT_WRITE,
184+
MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
185+
if (buf == MAP_FAILED) {
186+
pr_inf_skip("%s: failed to mmap %zu bytes for I/O buffer, errno=%d (%s), skipping stressor\n",
187+
args->name, copy_file_io_bytes, errno, strerror(errno));
188+
return EXIT_NO_RESOURCE;
189+
}
168190

169191
if (!stress_setting_get("copy-file-bytes", &copy_file_bytes_total)) {
170192
if (g_opt_flags & OPT_FLAGS_MAXIMIZE)
@@ -186,8 +208,8 @@ static int stress_copy_file(stress_args_t *args)
186208
}
187209

188210
copy_file_bytes = copy_file_bytes_total / args->instances;
189-
if (copy_file_bytes < DEFAULT_COPY_FILE_SIZE) {
190-
copy_file_bytes = DEFAULT_COPY_FILE_SIZE * 2;
211+
if (copy_file_bytes < (uint64_t)copy_file_io_bytes) {
212+
copy_file_bytes = (uint64_t)copy_file_io_bytes * 2UL;
191213
copy_file_bytes_total = copy_file_bytes * args->instances;
192214
}
193215
if (copy_file_bytes < MIN_COPY_FILE_BYTES) {
@@ -256,19 +278,20 @@ static int stress_copy_file(stress_args_t *args)
256278
shim_off64_t off64_out_orig;
257279
double t;
258280

259-
off64_in_orig = (shim_loff_t)stress_mwc64modn(copy_file_bytes - DEFAULT_COPY_FILE_SIZE);
281+
/* offsets are between 0.. and end of file - copy size */
282+
off64_in_orig = (shim_loff_t)stress_mwc64modn(copy_file_bytes - (uint64_t)copy_file_io_bytes);
260283
off64_in = off64_in_orig;
261-
off64_out_orig = (shim_loff_t)stress_mwc64modn(copy_file_bytes - DEFAULT_COPY_FILE_SIZE);
284+
off64_out_orig = (shim_loff_t)stress_mwc64modn(copy_file_bytes - (uint64_t)copy_file_io_bytes);
262285
off64_out = off64_out_orig;
263286

264287
if (UNLIKELY(!stress_continue(args)))
265288
break;
266-
stress_copy_file_fill(args, fd_in, off64_in, DEFAULT_COPY_FILE_SIZE);
289+
stress_copy_file_fill(args, fd_in, off64_in, buf, copy_file_io_bytes);
267290
if (UNLIKELY(!stress_continue(args)))
268291
break;
269292
t = stress_time_now();
270293
copy_ret = shim_copy_file_range(fd_in, &off64_in, fd_out,
271-
&off64_out, DEFAULT_COPY_FILE_SIZE, 0);
294+
&off64_out, copy_file_io_bytes, 0);
272295
if (LIKELY(copy_ret >= 0)) {
273296
duration += stress_time_now() - t;
274297
bytes += (double)copy_ret;
@@ -315,17 +338,17 @@ static int stress_copy_file(stress_args_t *args)
315338
* Exercise with bad fds
316339
*/
317340
VOID_RET(ssize_t, shim_copy_file_range(fd_bad, &off64_in, fd_out,
318-
&off64_out, DEFAULT_COPY_FILE_SIZE, 0));
341+
&off64_out, copy_file_io_bytes, 0));
319342
VOID_RET(ssize_t, shim_copy_file_range(fd_in, &off64_in, fd_bad,
320-
&off64_out, DEFAULT_COPY_FILE_SIZE, 0));
343+
&off64_out, copy_file_io_bytes, 0));
321344
VOID_RET(ssize_t, shim_copy_file_range(fd_out, &off64_in, fd_in,
322-
&off64_out, DEFAULT_COPY_FILE_SIZE, 0));
345+
&off64_out, copy_file_io_bytes, 0));
323346
(void)copy_ret;
324347
/*
325348
* Exercise with bad flags
326349
*/
327350
VOID_RET(ssize_t, shim_copy_file_range(fd_in, &off64_in, fd_out,
328-
&off64_out, DEFAULT_COPY_FILE_SIZE, ~0U));
351+
&off64_out, copy_file_io_bytes, ~0U));
329352
if (UNLIKELY(!stress_continue(args)))
330353
break;
331354
(void)shim_fsync(fd_out);
@@ -347,6 +370,8 @@ static int stress_copy_file(stress_args_t *args)
347370
stress_proc_state_set(args->name, STRESS_STATE_DEINIT);
348371
(void)stress_fs_temp_dir_rm_args(args);
349372

373+
(void)munmap((void *)buf, copy_file_io_bytes);
374+
350375
return rc;
351376
}
352377

stress-ng.1

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2169,6 +2169,9 @@ copy file size, the default is 256 MB. One can specify the size as % of free
21692169
space on the file system or in units of Bytes, KBytes, MBytes and GBytes using
21702170
the suffix b, k, m or g.
21712171
.TP
2172+
.B \-\-copy\-file\-io\-bytes N
2173+
copy_file_range(2) copying I/O size, the default is 128 KB, range 4 K to 1 MB.
2174+
.TP
21722175
.B \-\-copy\-file\-ops N
21732176
stop after N copy_file_range() calls.
21742177
.RE

0 commit comments

Comments
 (0)