[PATCH] Offset verification header by a user-specified distance

From: Shawn Lewis <shawnlewis_at_google.com>
Date: Fri, 27 Jul 2007 14:12:20 -0700 (PDT)

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.

diff --git a/HOWTO b/HOWTO
index 2797a58..8cb849c 100644
--- a/HOWTO
+++ b/HOWTO
@@ -603,6 +603,10 @@ verifysort=bool If set, fio will sort wr
                 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 653f502..e97caf1 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 829b808..130dc8c 100644
--- a/options.c
+++ b/options.c
@@ -203,6 +203,17 @@ static int str_opendir_cb(void *data, co
         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)
@@ -611,6 +622,13 @@ #endif
                 .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,
                 .off1 = td_var_offset(write_iolog_file),
diff --git a/verify.c b/verify.c
index a362933..8bc3457 100644
--- a/verify.c
+++ b/verify.c
@@ -32,6 +32,14 @@ static void fill_random_bytes(struct thr
         }
 }
 
+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,
                 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_heade
  */
 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_
                         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));
         }
 }
 
Received on Fri Jul 27 2007 - 23:12:20 CEST

This archive was generated by hypermail 2.2.0 : Fri Jul 27 2007 - 23:30:01 CEST