From: Shawn Lewis Date: Sat, 28 Jul 2007 19:11:37 +0000 (+0200) Subject: [PATCH] Offset verification header by a user-specified distance X-Git-Tag: fio-1.17~32 X-Git-Url: https://git.kernel.dk/?p=fio.git;a=commitdiff_plain;h=546a9142511875524850ac92776184fd9fb7196e;hp=3f9f4e2631c4f5d33f125dd71db20c1773d22c91 [PATCH] Offset verification header by a user-specified distance Offset verification header by user specified distance. - Implementation is somewhat simple and probably not ideal but it works. The header is just swapped with the bytes at offset after the chunk has been filled during populate. Everything is swapped back before verify. - Also fixes a bug where we were relying on a moving pointer for increment size in populate_verify_io_u (which was working until this patch). - Also cleans up a couple smalls things from the header_interval patch. Signed-off-by: Jens Axboe --- diff --git a/HOWTO b/HOWTO index 2797a58c..8cb849c7 100644 --- a/HOWTO +++ b/HOWTO @@ -603,6 +603,10 @@ verifysort=bool If set, fio will sort written verify blocks when it deems fast IO where the red-black tree sorting CPU time becomes significant. +header_offset=siint Swap the verification header with data somewhere else + in the block before writing. Its swapped back before + verifying. + header_interval=siint Write the verification header at a finer granularity than the blocksize. It will be written for chunks the size of header_interval. blocksize should divide this diff --git a/fio.h b/fio.h index 653f5022..e97caf18 100644 --- a/fio.h +++ b/fio.h @@ -396,6 +396,7 @@ struct thread_options { unsigned int verify; unsigned int verifysort; unsigned int header_interval; + unsigned int header_offset; unsigned int use_thread; unsigned int unlink; unsigned int do_disk_util; diff --git a/options.c b/options.c index 829b808c..130dc8c7 100644 --- a/options.c +++ b/options.c @@ -203,6 +203,17 @@ static int str_opendir_cb(void *data, const char fio_unused *str) return add_dir_files(td, td->o.opendir); } +static int str_header_offset_cb(void *data, unsigned int *off) +{ + struct thread_data *td = data; + if (*off && *off < sizeof(struct verify_header)) { + log_err("fio: header_offset too small\n"); + return 1; + } + td->o.header_offset = *off; + return 0; +} + #define __stringify_1(x) #x #define __stringify(x) __stringify_1(x) @@ -610,6 +621,13 @@ static struct fio_option options[] = { .help = "Store buffer header every N bytes", .def = "0", }, + { + .name = "header_offset", + .type = FIO_OPT_STR_VAL_INT, + .help = "Offset header location by N bytes", + .def = "0", + .cb = str_header_offset_cb, + }, { .name = "write_iolog", .type = FIO_OPT_STR_STORE, diff --git a/verify.c b/verify.c index a362933d..8bc34571 100644 --- a/verify.c +++ b/verify.c @@ -32,6 +32,14 @@ static void fill_random_bytes(struct thread_data *td, } } +void memswp(void* buf1, void* buf2, unsigned int len) +{ + struct verify_header swap; + memcpy(&swap, buf1, len); + memcpy(buf1, buf2, len); + memcpy(buf2, &swap, len); +} + static void hexdump(void *buffer, int len) { unsigned char *p = buffer; @@ -161,6 +169,9 @@ int verify_io_u(struct thread_data *td, struct io_u *io_u) hdr_inc = td->o.header_interval; for (; p < (unsigned char*) io_u->buf + io_u->buflen; p += hdr_inc) { + if (td->o.header_offset) + memswp(p, &p[td->o.header_offset], sizeof(*hdr)); + hdr = (struct verify_header*) p; if (hdr->fio_magic != FIO_HDR_MAGIC) { @@ -229,27 +240,28 @@ static void fill_md5(struct verify_header *hdr, void *p, unsigned int len) */ void populate_verify_io_u(struct thread_data *td, struct io_u *io_u) { - const unsigned int len = io_u->buflen - sizeof(struct verify_header); struct verify_header *hdr; unsigned char *p = io_u->buf, *data; - unsigned int data_len; + unsigned int hdr_inc, data_len; if (td->o.verify == VERIFY_NULL) return; - fill_random_bytes(td, p, len); + fill_random_bytes(td, p, io_u->buflen); + + hdr_inc = io_u->buflen; + if (td->o.header_interval) + hdr_inc = td->o.header_interval; + data_len = hdr_inc - sizeof(*hdr); - for (;p < (unsigned char*) io_u->buf + io_u->buflen; p += hdr->len) { + for (;p < (unsigned char*) io_u->buf + io_u->buflen; p += hdr_inc) { hdr = (struct verify_header*) p; hdr->fio_magic = FIO_HDR_MAGIC; hdr->verify_type = td->o.verify; - hdr->len = io_u->buflen; - if (td->o.header_interval) - hdr->len = td->o.header_interval; + hdr->len = hdr_inc; data = p + sizeof(*hdr); - data_len = hdr->len - sizeof(*hdr); switch (td->o.verify) { case VERIFY_MD5: fill_md5(hdr, data, data_len); @@ -270,6 +282,8 @@ void populate_verify_io_u(struct thread_data *td, struct io_u *io_u) log_err("fio: bad verify type: %d\n", td->o.verify); assert(0); } + if (td->o.header_offset) + memswp(p, &p[td->o.header_offset], sizeof(*hdr)); } }