[PATCH] Offset verification header by a user-specified distance
authorShawn Lewis <shawnlewis@google.com>
Sat, 28 Jul 2007 19:11:37 +0000 (21:11 +0200)
committerJens Axboe <jens.axboe@oracle.com>
Sat, 28 Jul 2007 19:11:37 +0000 (21:11 +0200)
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 <jens.axboe@oracle.com>
HOWTO
fio.h
options.c
verify.c

diff --git a/HOWTO b/HOWTO
index 2797a58c3da2bbe6c240f039753ff52b0bb76265..8cb849c7c6edad0ddf70294d98f3084cd2894a5a 100644 (file)
--- 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.
 
                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
 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 653f50226cef38dfca21eb25d622d1538c56a944..e97caf18bc1bdbea46751be177639bd66cd44919 100644 (file)
--- 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 verify;
        unsigned int verifysort;
        unsigned int header_interval;
+       unsigned int header_offset;
        unsigned int use_thread;
        unsigned int unlink;
        unsigned int do_disk_util;
        unsigned int use_thread;
        unsigned int unlink;
        unsigned int do_disk_util;
index 829b808ce5be554f1f9092dbfdf9c7c022095dfb..130dc8c784b5f6f0ae67fd60550cd944073f91ea 100644 (file)
--- 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);
 }
 
        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)
 
 #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",
        },
                .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,
        {
                .name   = "write_iolog",
                .type   = FIO_OPT_STR_STORE,
index a362933d3115e9f340fe351cd8db2bdffdf8a0a8..8bc34571076d403475e764a4ec41df6554234431 100644 (file)
--- 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;
 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) {
                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) {
                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)
 {
  */
 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;
        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;
 
 
        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 = (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 = p + sizeof(*hdr);
-               data_len = hdr->len - sizeof(*hdr);
                switch (td->o.verify) {
                case VERIFY_MD5:
                        fill_md5(hdr, data, data_len);
                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);
                }
                        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));
        }
 }
 
        }
 }