Cleanup some verify bits
[fio.git] / verify.c
index 01e2542629c398e5149c1552fad681737b16cf40..66b3ef0d36583d1f7a045821b139b3961d5d03f5 100644 (file)
--- a/verify.c
+++ b/verify.c
@@ -6,6 +6,7 @@
 #include <string.h>
 #include <assert.h>
 #include <pthread.h>
+#include <libgen.h>
 
 #include "fio.h"
 #include "verify.h"
@@ -38,23 +39,38 @@ void fill_pattern(struct thread_data *td, void *p, unsigned int len, struct io_u
                        io_u->rand_seed = fill_random_buf(p, len);
                break;
        case 1:
+               /*
+                * See below write barrier comment
+                */
+#if 0
+               read_barrier();
                if (io_u->buf_filled_len >= len) {
                        dprint(FD_VERIFY, "using already filled verify pattern b=0 len=%u\n", len);
                        return;
                }
+#endif
                dprint(FD_VERIFY, "fill verify pattern b=0 len=%u\n", len);
                memset(p, td->o.verify_pattern[0], len);
+               /*
+                * We need to ensure that the pattern stores are seen before
+                * the fill length store, or we could observe headers that
+                * aren't valid to the extent notified by the fill length
+                */
+               write_barrier();
                io_u->buf_filled_len = len;
                break;
        default: {
                unsigned int i = 0, size = 0;
                unsigned char *b = p;
 
+#if 0
+               read_barrier();
                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;
                }
+#endif
                dprint(FD_VERIFY, "fill verify pattern b=%d len=%u\n",
                                        td->o.verify_pattern_bytes, len);
 
@@ -65,12 +81,24 @@ void fill_pattern(struct thread_data *td, void *p, unsigned int len, struct io_u
                        memcpy(b+i, td->o.verify_pattern, size);
                        i += size;
                }
+               write_barrier();
                io_u->buf_filled_len = len;
                break;
                }
        }
 }
 
+static unsigned int get_hdr_inc(struct thread_data *td, struct io_u *io_u)
+{
+       unsigned int hdr_inc;
+
+       hdr_inc = io_u->buflen;
+       if (td->o.verify_interval)
+               hdr_inc = td->o.verify_interval;
+
+       return hdr_inc;
+}
+
 static void fill_pattern_headers(struct thread_data *td, struct io_u *io_u,
                                 unsigned long seed, int use_seed)
 {
@@ -80,10 +108,7 @@ static void fill_pattern_headers(struct thread_data *td, struct io_u *io_u,
 
        fill_pattern(td, p, io_u->buflen, io_u, seed, use_seed);
 
-       hdr_inc = io_u->buflen;
-       if (td->o.verify_interval)
-               hdr_inc = td->o.verify_interval;
-
+       hdr_inc = get_hdr_inc(td, io_u);
        header_num = 0;
        for (; p < io_u->buf + io_u->buflen; p += hdr_inc) {
                hdr = p;
@@ -198,11 +223,11 @@ struct vcont {
 static void dump_buf(char *buf, unsigned int len, unsigned long long offset,
                     const char *type, struct fio_file *f)
 {
-       char fname[256];
+       char *ptr, fname[256];
        int ret, fd;
 
-       strcpy(fname, f->file_name);
-       basename(fname);
+       ptr = strdup(f->file_name);
+       strcpy(fname, basename(ptr));
 
        sprintf(fname + strlen(fname), ".%llu.%s", offset, type);
 
@@ -226,6 +251,7 @@ static void dump_buf(char *buf, unsigned int len, unsigned long long offset,
 
        close(fd);
        log_err("       %s data dumped as %s\n", type, fname);
+       free(ptr);
 }
 
 /*
@@ -254,6 +280,8 @@ static void dump_verify_buffers(struct verify_header *hdr, struct vcont *vc)
        buf = malloc(io_u->buflen);
        dummy = *io_u;
        dummy.buf = buf;
+       dummy.rand_seed = hdr->rand_seed;
+       dummy.buf_filled_len = 0;
 
        fill_pattern_headers(td, &dummy, hdr->rand_seed, 1);
 
@@ -521,10 +549,18 @@ static unsigned int hweight8(unsigned int w)
        return (res + (res >> 4)) & 0x0F;
 }
 
-int verify_io_u_pattern(char *pattern, unsigned long pattern_size,
-                       char *buf, unsigned int len, unsigned int mod)
+int verify_io_u_pattern(struct verify_header *hdr, struct vcont *vc)
 {
-       unsigned int i;
+       struct thread_data *td = vc->td;
+       struct io_u *io_u = vc->io_u;
+       char *buf, *pattern;
+       unsigned int hdr_size = __hdr_size(td->o.verify);
+       unsigned int len, mod, i;
+
+       pattern = td->o.verify_pattern;
+       buf = (void *) hdr + hdr_size;
+       len = get_hdr_inc(td, io_u) - hdr_size;
+       mod = hdr_size % td->o.verify_pattern_bytes;
 
        for (i = 0; i < len; i++) {
                if (buf[i] != pattern[mod]) {
@@ -534,10 +570,11 @@ int verify_io_u_pattern(char *pattern, unsigned long pattern_size,
                        log_err("fio: got pattern %x, wanted %x. Bad bits %d\n",
                                buf[i], pattern[mod], bits);
                        log_err("fio: bad pattern block offset %u\n", i);
+                       dump_verify_buffers(hdr, vc);
                        return EILSEQ;
                }
                mod++;
-               if (mod == pattern_size)
+               if (mod == td->o.verify_pattern_bytes)
                        mod = 0;
        }
 
@@ -617,9 +654,7 @@ int verify_io_u(struct thread_data *td, struct io_u *io_u)
                goto done;
        }
 
-       hdr_inc = io_u->buflen;
-       if (td->o.verify_interval)
-               hdr_inc = td->o.verify_interval;
+       hdr_inc = get_hdr_inc(td, io_u);
 
        ret = 0;
        for (p = io_u->buf; p < io_u->buf + io_u->buflen;
@@ -649,12 +684,7 @@ int verify_io_u(struct thread_data *td, struct io_u *io_u)
                if (td->o.verify_pattern_bytes) {
                        dprint(FD_VERIFY, "pattern verify io_u %p, len %u\n",
                                                                io_u, hdr->len);
-                       ret = verify_io_u_pattern(td->o.verify_pattern,
-                                 td->o.verify_pattern_bytes,
-                                 p + hdr_size,
-                                 hdr_inc - hdr_size,
-                                 hdr_size % td->o.verify_pattern_bytes);
-
+                       ret = verify_io_u_pattern(hdr, &vc);
                        if (ret) {
                                log_err("pattern: verify failed at file %s offset %llu, length %u\n",
                                        io_u->file->file_name,