alternate random and zeroed data throughout the IO
buffer.
+buffer_pattern=str If set, fio will fill the io buffers with this pattern.
+ If not set, the contents of io buffers is defined by the other
+ options related to buffer contents. The setting can be any
+ pattern of bytes, and can be prefixed with 0x for hex values.
+
nrfiles=int Number of files to use for this job. Defaults to 1.
openfiles=int Number of files to keep open at the same time. Defaults to
* Fill the buffer with the pattern if we are
* going to be doing writes.
*/
- fill_pattern(td, io_u->buf, max_bs, io_u, 0, 0);
+ fill_verify_pattern(td, io_u->buf, max_bs, io_u, 0, 0);
}
}
the remaining zeroed. With this set to some chunk size smaller than the block
size, fio can alternate random and zeroed data throughout the IO buffer.
.TP
+.BI buffer_pattern \fR=\fPstr
+If set, fio will fill the io buffers with this pattern. If not set, the contents
+of io buffers is defined by the other options related to buffer contents. The
+setting can be any pattern of bytes, and can be prefixed with 0x for hex
+values.
+.TP
.BI nrfiles \fR=\fPint
Number of files to use for this job. Default: 1.
.TP
void fill_io_buffer(struct thread_data *td, void *buf, unsigned int min_write,
unsigned int max_bs)
{
- if (!td->o.zero_buffers) {
+ if (td->o.buffer_pattern_bytes)
+ fill_buffer_pattern(td, buf, max_bs);
+ else if (!td->o.zero_buffers) {
unsigned int perc = td->o.compress_percentage;
if (perc) {
return add_dir_files(td, td->o.opendir);
}
-static int str_verify_pattern_cb(void *data, const char *input)
+static int pattern_cb(char *pattern, unsigned int max_size,
+ const char *input, unsigned int *pattern_bytes)
{
- struct thread_data *td = data;
long off;
- int i = 0, j = 0, len, k, base = 10, pattern_length;
+ int i = 0, j = 0, len, k, base = 10;
+ uint32_t pattern_length;
char *loc1, *loc2;
loc1 = strstr(input, "0x");
off = strtol(input, NULL, base);
if (off != LONG_MAX || errno != ERANGE) {
while (off) {
- td->o.verify_pattern[i] = off & 0xff;
+ pattern[i] = off & 0xff;
off >>= 8;
i++;
}
j = loc2 - input + 2;
} else
return 1;
- if (len - j < MAX_PATTERN_SIZE * 2) {
+ if (len - j < max_size * 2) {
while (k >= j) {
off = converthexchartoint(input[k--]);
if (k >= j)
off += (converthexchartoint(input[k--])
* 16);
- td->o.verify_pattern[i++] = (char) off;
+ pattern[i++] = (char) off;
}
}
}
* the number of memcpy's we have to do when verifying the IO.
*/
pattern_length = i;
- while (i > 1 && i * 2 <= MAX_PATTERN_SIZE) {
- memcpy(&td->o.verify_pattern[i], &td->o.verify_pattern[0], i);
+ while (i > 1 && i * 2 <= max_size) {
+ memcpy(&pattern[i], &pattern[0], i);
i *= 2;
}
/*
* Fill remainder, if the pattern multiple ends up not being
- * MAX_PATTERN_SIZE.
+ * max_size.
*/
- while (i > 1 && i < MAX_PATTERN_SIZE) {
- unsigned int b = min(pattern_length, MAX_PATTERN_SIZE - i);
+ while (i > 1 && i < max_size) {
+ unsigned int b = min(pattern_length, max_size - i);
- memcpy(&td->o.verify_pattern[i], &td->o.verify_pattern[0], b);
+ memcpy(&pattern[i], &pattern[0], b);
i += b;
}
* The code in verify_io_u_pattern assumes a single byte pattern
* fills the whole verify pattern buffer.
*/
- memset(td->o.verify_pattern, td->o.verify_pattern[0],
- MAX_PATTERN_SIZE);
+ memset(pattern, pattern[0], max_size);
+ }
+
+ *pattern_bytes = i;
+ return 0;
+}
+
+static int str_buffer_pattern_cb(void *data, const char *input)
+{
+ struct thread_data *td = data;
+ int ret;
+
+ ret = pattern_cb(td->o.buffer_pattern, MAX_PATTERN_SIZE, input,
+ &td->o.buffer_pattern_bytes);
+
+ if (!ret) {
+ td->o.refill_buffers = 0;
+ td->o.scramble_buffers = 0;
+ td->o.zero_buffers = 0;
}
- td->o.verify_pattern_bytes = i;
+ return ret;
+}
+
+static int str_verify_pattern_cb(void *data, const char *input)
+{
+ struct thread_data *td = data;
+ int ret;
+
+ ret = pattern_cb(td->o.verify_pattern, MAX_PATTERN_SIZE, input,
+ &td->o.verify_pattern_bytes);
/*
* VERIFY_META could already be set
*/
- if (td->o.verify == VERIFY_NONE)
+ if (!ret && td->o.verify == VERIFY_NONE)
td->o.verify = VERIFY_PATTERN;
- return 0;
+ return ret;
}
static int str_gtod_reduce_cb(void *data, int *il)
.category = FIO_OPT_C_IO,
.group = FIO_OPT_G_IO_BUF,
},
+ {
+ .name = "buffer_pattern",
+ .lname = "Buffer pattern",
+ .type = FIO_OPT_STR,
+ .cb = str_buffer_pattern_cb,
+ .help = "Fill pattern for IO buffers",
+ .category = FIO_OPT_C_IO,
+ .group = FIO_OPT_G_IO_BUF,
+ },
{
.name = "buffer_compress_percentage",
.lname = "Buffer compression percentage",
unsigned int zero_buffers;
unsigned int refill_buffers;
unsigned int scramble_buffers;
+ char buffer_pattern[MAX_PATTERN_SIZE];
+ unsigned int buffer_pattern_bytes;
unsigned int compress_percentage;
unsigned int compress_chunk;
unsigned int time_based;
uint32_t zero_buffers;
uint32_t refill_buffers;
uint32_t scramble_buffers;
+ uint8_t buffer_pattern[MAX_PATTERN_SIZE];
+ uint32_t buffer_pattern_bytes;
unsigned int compress_percentage;
unsigned int compress_chunk;
uint32_t time_based;
struct verify_header *hdr, unsigned int header_num,
unsigned int header_len);
-void fill_pattern(struct thread_data *td, void *p, unsigned int len, struct io_u *io_u, unsigned long seed, int use_seed)
+static void fill_pattern(struct thread_data *td, void *p, unsigned int len,
+ char *pattern, unsigned int pattern_bytes)
{
- switch (td->o.verify_pattern_bytes) {
+ switch (pattern_bytes) {
case 0:
- dprint(FD_VERIFY, "fill random bytes len=%u\n", len);
- if (use_seed)
- __fill_random_buf(p, len, seed);
- else
- io_u->rand_seed = fill_random_buf(&td->buf_state, p, len);
+ assert(0);
break;
case 1:
- if (io_u->buf_filled_len >= len) {
- dprint(FD_VERIFY, "using already filled verify pattern b=0 len=%u\n", len);
- return;
- }
dprint(FD_VERIFY, "fill verify pattern b=0 len=%u\n", len);
- memset(p, td->o.verify_pattern[0], len);
- io_u->buf_filled_len = len;
+ memset(p, pattern[0], len);
break;
default: {
unsigned int i = 0, size = 0;
unsigned char *b = p;
- if (io_u->buf_filled_len >= len) {
- dprint(FD_VERIFY, "using already filled verify pattern b=%d len=%u\n",
- td->o.verify_pattern_bytes, len);
- return;
- }
-
dprint(FD_VERIFY, "fill verify pattern b=%d len=%u\n",
- td->o.verify_pattern_bytes, len);
+ pattern_bytes, len);
while (i < len) {
- size = td->o.verify_pattern_bytes;
+ size = pattern_bytes;
if (size > (len - i))
size = len - i;
- memcpy(b+i, td->o.verify_pattern, size);
+ memcpy(b+i, pattern, size);
i += size;
}
- io_u->buf_filled_len = len;
break;
}
}
}
+void fill_buffer_pattern(struct thread_data *td, void *p, unsigned int len)
+{
+ fill_pattern(td, p, len, td->o.buffer_pattern, td->o.buffer_pattern_bytes);
+}
+
+void fill_verify_pattern(struct thread_data *td, void *p, unsigned int len,
+ struct io_u *io_u, unsigned long seed, int use_seed)
+{
+ if (!td->o.verify_pattern_bytes) {
+ dprint(FD_VERIFY, "fill random bytes len=%u\n", len);
+
+ if (use_seed)
+ __fill_random_buf(p, len, seed);
+ else
+ io_u->rand_seed = fill_random_buf(&td->buf_state, p, len);
+ return;
+ }
+
+ if (io_u->buf_filled_len >= len) {
+ dprint(FD_VERIFY, "using already filled verify pattern b=%d len=%u\n",
+ td->o.verify_pattern_bytes, len);
+ return;
+ }
+
+ fill_pattern(td, p, len, td->o.verify_pattern, td->o.verify_pattern_bytes);
+
+ io_u->buf_filled_len = len;
+}
+
static unsigned int get_hdr_inc(struct thread_data *td, struct io_u *io_u)
{
unsigned int hdr_inc;
struct verify_header *hdr;
void *p = io_u->buf;
- fill_pattern(td, p, io_u->buflen, io_u, seed, use_seed);
+ fill_verify_pattern(td, p, io_u->buflen, io_u, seed, use_seed);
hdr_inc = get_hdr_inc(td, io_u);
header_num = 0;
extern int __must_check get_next_verify(struct thread_data *td, struct io_u *);
extern int __must_check verify_io_u(struct thread_data *, struct io_u *);
extern int verify_io_u_async(struct thread_data *, struct io_u *);
-extern void fill_pattern(struct thread_data *td, void *p, unsigned int len, struct io_u *io_u, unsigned long seed, int use_seed);
+extern void fill_verify_pattern(struct thread_data *td, void *p, unsigned int len, struct io_u *io_u, unsigned long seed, int use_seed);
+extern void fill_buffer_pattern(struct thread_data *td, void *p, unsigned int len);
extern void fio_verify_init(struct thread_data *td);
/*