io_u->rand_seed = fill_random_buf(&td->buf_state, 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;
}
struct io_u *io_u = vc->io_u;
char *buf, *pattern;
unsigned int header_size = __hdr_size(td->o.verify);
- unsigned int len, mod, i;
+ unsigned int len, mod, i, size, pattern_size;
pattern = td->o.verify_pattern;
+ pattern_size = td->o.verify_pattern_bytes;
+ if (pattern_size <= 1)
+ pattern_size = MAX_PATTERN_SIZE;
buf = (void *) hdr + header_size;
len = get_hdr_inc(td, io_u) - header_size;
- mod = header_size % td->o.verify_pattern_bytes;
+ mod = header_size % pattern_size;
+
+ for (i = 0; i < len; i += size) {
+ size = pattern_size - mod;
+ if (size > (len - i))
+ size = len - i;
+ if (memcmp(buf + i, pattern + mod, size))
+ // Let the slow compare find the first mismatch byte.
+ break;
+ mod = 0;
+ }
- for (i = 0; i < len; i++) {
+ for (; i < len; i++) {
if (buf[i] != pattern[mod]) {
unsigned int bits;
if (io_u->file)
put_file_log(td, io_u->file);
- io_u->file = NULL;
-
pthread_mutex_lock(&td->io_u_lock);
-
+
if (io_u->flags & IO_U_F_IN_CUR_DEPTH) {
td->cur_depth--;
io_u->flags &= ~IO_U_F_IN_CUR_DEPTH;
return ret;
}
+static int verify_hdr_crc(struct verify_header *hdr)
+{
+ void *p = hdr;
+ uint32_t crc;
+
+ crc = crc32(p, sizeof(*hdr) - sizeof(hdr->crc32));
+ if (crc == hdr->crc32)
+ return 1;
+
+ log_err("fio: verify header crc %x, calculated %x\n", hdr->crc32, crc);
+ return 0;
+}
+
int verify_io_u(struct thread_data *td, struct io_u *io_u)
{
struct verify_header *hdr;
memswp(p, p + td->o.verify_offset, header_size);
hdr = p;
- if (hdr->fio_magic != FIO_HDR_MAGIC) {
+ if (hdr->fio_magic == FIO_HDR_MAGIC2) {
+ if (!verify_hdr_crc(hdr)) {
+ log_err("fio: bad crc on verify header.\n");
+ return EILSEQ;
+ }
+ } else if (hdr->fio_magic == FIO_HDR_MAGIC) {
+ log_err("fio: v1 headers no longer supported.\n");
+ log_err("fio: re-run the write workload.\n");
+ return EILSEQ;
+ } else {
log_err("verify: bad magic header %x, wanted %x at file %s offset %llu, length %u\n",
- hdr->fio_magic, FIO_HDR_MAGIC,
+ hdr->fio_magic, FIO_HDR_MAGIC2,
io_u->file->file_name,
io_u->offset + hdr_num * hdr->len, hdr->len);
return EILSEQ;
p = (void *) hdr;
- hdr->fio_magic = FIO_HDR_MAGIC;
+ hdr->fio_magic = FIO_HDR_MAGIC2;
hdr->len = header_len;
hdr->verify_type = td->o.verify;
+ hdr->pad1 = 0;
hdr->rand_seed = io_u->rand_seed;
+ hdr->pad2 = 0;
+ hdr->crc32 = crc32(p, sizeof(*hdr) - sizeof(hdr->crc32));
+
data_len = header_len - hdr_size(hdr);
data = p + hdr_size(hdr);
put_io_u(td, io_u);
if (!ret)
continue;
- if (td->o.continue_on_error &&
+ if (td->o.continue_on_error & ERROR_TYPE_VERIFY &&
td_non_fatal_error(ret)) {
update_error_count(td, ret);
td_clear_error(td);