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);
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)
{
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;
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);
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]) {
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;
}
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;
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,