X-Git-Url: https://git.kernel.dk/?a=blobdiff_plain;f=verify.c;h=f833e85b23539e6bafda0876adf13ef0576f0ff7;hb=2af0ad5e22f7c3a8c572d1205a63e861d4797120;hp=2ae03f85fbea88f4e0f24ff33a4480d124d27e26;hpb=b2a9e6496494373f97f78dcdb3663fbb7b7a4ddb;p=fio.git diff --git a/verify.c b/verify.c index 2ae03f85..f833e85b 100644 --- a/verify.c +++ b/verify.c @@ -28,6 +28,10 @@ static void populate_hdr(struct thread_data *td, struct io_u *io_u, struct verify_header *hdr, unsigned int header_num, unsigned int header_len); +static void fill_hdr(struct verify_header *hdr, int verify_type, uint32_t len, + uint64_t rand_seed); +static void __fill_hdr(struct verify_header *hdr, int verify_type, uint32_t len, + uint64_t rand_seed); void fill_buffer_pattern(struct thread_data *td, void *p, unsigned int len) { @@ -133,6 +137,7 @@ static inline unsigned int __hdr_size(int verify_type) switch (verify_type) { case VERIFY_NONE: case VERIFY_NULL: + case VERIFY_PATTERN: len = 0; break; case VERIFY_MD5: @@ -167,9 +172,8 @@ static inline unsigned int __hdr_size(int verify_type) case VERIFY_SHA1: len = sizeof(struct vhdr_sha1); break; - case VERIFY_PATTERN: - len = 0; - break; + case VERIFY_PATTERN_NO_HDR: + return 0; default: log_err("fio: unknown verify header!\n"); assert(0); @@ -178,8 +182,12 @@ static inline unsigned int __hdr_size(int verify_type) return len + sizeof(struct verify_header); } -static inline unsigned int hdr_size(struct verify_header *hdr) +static inline unsigned int hdr_size(struct thread_data *td, + struct verify_header *hdr) { + if (td->o.verify == VERIFY_PATTERN_NO_HDR) + return 0; + return __hdr_size(hdr->verify_type); } @@ -265,7 +273,7 @@ static void dump_buf(char *buf, unsigned int len, unsigned long long offset, * Dump the contents of the read block and re-generate the correct data * and dump that too. */ -static void dump_verify_buffers(struct verify_header *hdr, struct vcont *vc) +static void __dump_verify_buffers(struct verify_header *hdr, struct vcont *vc) { struct thread_data *td = vc->td; struct io_u *io_u = vc->io_u; @@ -301,6 +309,19 @@ static void dump_verify_buffers(struct verify_header *hdr, struct vcont *vc) free(buf); } +static void dump_verify_buffers(struct verify_header *hdr, struct vcont *vc) +{ + struct thread_data *td = vc->td; + struct verify_header shdr; + + if (td->o.verify == VERIFY_PATTERN_NO_HDR) { + __fill_hdr(&shdr, td->o.verify, vc->io_u->buflen, 0); + hdr = &shdr; + } + + __dump_verify_buffers(hdr, vc); +} + static void log_verify_failure(struct verify_header *hdr, struct vcont *vc) { unsigned long long offset; @@ -325,7 +346,7 @@ static void log_verify_failure(struct verify_header *hdr, struct vcont *vc) */ static inline void *io_u_verify_off(struct verify_header *hdr, struct vcont *vc) { - return vc->io_u->buf + vc->hdr_num * hdr->len + hdr_size(hdr); + return vc->io_u->buf + vc->hdr_num * hdr->len + hdr_size(vc->td, hdr); } static int verify_io_u_pattern(struct verify_header *hdr, struct vcont *vc) @@ -420,7 +441,7 @@ static int verify_io_u_xxhash(struct verify_header *hdr, struct vcont *vc) dprint(FD_VERIFY, "xxhash verify io_u %p, len %u\n", vc->io_u, hdr->len); state = XXH32_init(1); - XXH32_update(state, p, hdr->len - hdr_size(hdr)); + XXH32_update(state, p, hdr->len - hdr_size(vc->td, hdr)); hash = XXH32_digest(state); if (vh->hash == hash) @@ -446,7 +467,7 @@ static int verify_io_u_sha512(struct verify_header *hdr, struct vcont *vc) dprint(FD_VERIFY, "sha512 verify io_u %p, len %u\n", vc->io_u, hdr->len); fio_sha512_init(&sha512_ctx); - fio_sha512_update(&sha512_ctx, p, hdr->len - hdr_size(hdr)); + fio_sha512_update(&sha512_ctx, p, hdr->len - hdr_size(vc->td, hdr)); if (!memcmp(vh->sha512, sha512_ctx.buf, sizeof(sha512))) return 0; @@ -471,7 +492,8 @@ static int verify_io_u_sha256(struct verify_header *hdr, struct vcont *vc) dprint(FD_VERIFY, "sha256 verify io_u %p, len %u\n", vc->io_u, hdr->len); fio_sha256_init(&sha256_ctx); - fio_sha256_update(&sha256_ctx, p, hdr->len - hdr_size(hdr)); + fio_sha256_update(&sha256_ctx, p, hdr->len - hdr_size(vc->td, hdr)); + fio_sha256_final(&sha256_ctx); if (!memcmp(vh->sha256, sha256_ctx.buf, sizeof(sha256))) return 0; @@ -496,7 +518,8 @@ static int verify_io_u_sha1(struct verify_header *hdr, struct vcont *vc) dprint(FD_VERIFY, "sha1 verify io_u %p, len %u\n", vc->io_u, hdr->len); fio_sha1_init(&sha1_ctx); - fio_sha1_update(&sha1_ctx, p, hdr->len - hdr_size(hdr)); + fio_sha1_update(&sha1_ctx, p, hdr->len - hdr_size(vc->td, hdr)); + fio_sha1_final(&sha1_ctx); if (!memcmp(vh->sha1, sha1_ctx.H, sizeof(sha1))) return 0; @@ -517,7 +540,7 @@ static int verify_io_u_crc7(struct verify_header *hdr, struct vcont *vc) dprint(FD_VERIFY, "crc7 verify io_u %p, len %u\n", vc->io_u, hdr->len); - c = fio_crc7(p, hdr->len - hdr_size(hdr)); + c = fio_crc7(p, hdr->len - hdr_size(vc->td, hdr)); if (c == vh->crc7) return 0; @@ -538,7 +561,7 @@ static int verify_io_u_crc16(struct verify_header *hdr, struct vcont *vc) dprint(FD_VERIFY, "crc16 verify io_u %p, len %u\n", vc->io_u, hdr->len); - c = fio_crc16(p, hdr->len - hdr_size(hdr)); + c = fio_crc16(p, hdr->len - hdr_size(vc->td, hdr)); if (c == vh->crc16) return 0; @@ -559,7 +582,7 @@ static int verify_io_u_crc64(struct verify_header *hdr, struct vcont *vc) dprint(FD_VERIFY, "crc64 verify io_u %p, len %u\n", vc->io_u, hdr->len); - c = fio_crc64(p, hdr->len - hdr_size(hdr)); + c = fio_crc64(p, hdr->len - hdr_size(vc->td, hdr)); if (c == vh->crc64) return 0; @@ -580,7 +603,7 @@ static int verify_io_u_crc32(struct verify_header *hdr, struct vcont *vc) dprint(FD_VERIFY, "crc32 verify io_u %p, len %u\n", vc->io_u, hdr->len); - c = fio_crc32(p, hdr->len - hdr_size(hdr)); + c = fio_crc32(p, hdr->len - hdr_size(vc->td, hdr)); if (c == vh->crc32) return 0; @@ -601,7 +624,7 @@ static int verify_io_u_crc32c(struct verify_header *hdr, struct vcont *vc) dprint(FD_VERIFY, "crc32c verify io_u %p, len %u\n", vc->io_u, hdr->len); - c = fio_crc32c(p, hdr->len - hdr_size(hdr)); + c = fio_crc32c(p, hdr->len - hdr_size(vc->td, hdr)); if (c == vh->crc32) return 0; @@ -626,7 +649,8 @@ static int verify_io_u_md5(struct verify_header *hdr, struct vcont *vc) dprint(FD_VERIFY, "md5 verify io_u %p, len %u\n", vc->io_u, hdr->len); fio_md5_init(&md5_ctx); - fio_md5_update(&md5_ctx, p, hdr->len - hdr_size(hdr)); + fio_md5_update(&md5_ctx, p, hdr->len - hdr_size(vc->td, hdr)); + fio_md5_final(&md5_ctx); if (!memcmp(vh->md5_digest, md5_ctx.hash, sizeof(hash))) return 0; @@ -653,7 +677,7 @@ int verify_io_u_async(struct thread_data *td, struct io_u **io_u_ptr) if (io_u->flags & IO_U_F_IN_CUR_DEPTH) { td->cur_depth--; - io_u->flags &= ~IO_U_F_IN_CUR_DEPTH; + io_u_clear(io_u, IO_U_F_IN_CUR_DEPTH); } flist_add_tail(&io_u->verify_list, &td->verify_list); *io_u_ptr = NULL; @@ -784,9 +808,11 @@ int verify_io_u(struct thread_data *td, struct io_u **io_u_ptr) if (td->o.verifysort || (td->flags & TD_F_VER_BACKLOG)) io_u->rand_seed = hdr->rand_seed; - ret = verify_header(io_u, hdr, hdr_num, hdr_inc); - if (ret) - return ret; + if (td->o.verify != VERIFY_PATTERN_NO_HDR) { + ret = verify_header(io_u, hdr, hdr_num, hdr_inc); + if (ret) + return ret; + } if (td->o.verify != VERIFY_NONE) verify_type = td->o.verify; @@ -829,6 +855,7 @@ int verify_io_u(struct thread_data *td, struct io_u **io_u_ptr) ret = verify_io_u_sha1(hdr, &vc); break; case VERIFY_PATTERN: + case VERIFY_PATTERN_NO_HDR: ret = verify_io_u_pattern(hdr, &vc); break; default: @@ -893,6 +920,7 @@ static void fill_sha256(struct verify_header *hdr, void *p, unsigned int len) fio_sha256_init(&sha256_ctx); fio_sha256_update(&sha256_ctx, p, len); + fio_sha256_final(&sha256_ctx); } static void fill_sha1(struct verify_header *hdr, void *p, unsigned int len) @@ -904,6 +932,7 @@ static void fill_sha1(struct verify_header *hdr, void *p, unsigned int len) fio_sha1_init(&sha1_ctx); fio_sha1_update(&sha1_ctx, p, len); + fio_sha1_final(&sha1_ctx); } static void fill_crc7(struct verify_header *hdr, void *p, unsigned int len) @@ -950,6 +979,27 @@ static void fill_md5(struct verify_header *hdr, void *p, unsigned int len) fio_md5_init(&md5_ctx); fio_md5_update(&md5_ctx, p, len); + fio_md5_final(&md5_ctx); +} + +static void __fill_hdr(struct verify_header *hdr, int verify_type, + uint32_t len, uint64_t rand_seed) +{ + void *p = hdr; + + hdr->magic = FIO_HDR_MAGIC; + hdr->verify_type = verify_type; + hdr->len = len; + hdr->rand_seed = rand_seed; + hdr->crc32 = fio_crc32c(p, offsetof(struct verify_header, crc32)); +} + + +static void fill_hdr(struct verify_header *hdr, int verify_type, uint32_t len, + uint64_t rand_seed) +{ + if (verify_type != VERIFY_PATTERN_NO_HDR) + __fill_hdr(hdr, verify_type, len, rand_seed); } static void populate_hdr(struct thread_data *td, struct io_u *io_u, @@ -961,15 +1011,11 @@ static void populate_hdr(struct thread_data *td, struct io_u *io_u, p = (void *) hdr; - hdr->magic = FIO_HDR_MAGIC; - hdr->verify_type = td->o.verify; - hdr->len = header_len; - hdr->rand_seed = io_u->rand_seed; - hdr->crc32 = fio_crc32c(p, offsetof(struct verify_header, crc32)); + fill_hdr(hdr, td->o.verify, header_len, io_u->rand_seed); - data_len = header_len - hdr_size(hdr); + data_len = header_len - hdr_size(td, hdr); - data = p + hdr_size(hdr); + data = p + hdr_size(td, hdr); switch (td->o.verify) { case VERIFY_MD5: dprint(FD_VERIFY, "fill md5 io_u %p, len %u\n", @@ -1028,14 +1074,16 @@ static void populate_hdr(struct thread_data *td, struct io_u *io_u, fill_sha1(hdr, data, data_len); break; case VERIFY_PATTERN: + case VERIFY_PATTERN_NO_HDR: /* nothing to do here */ break; default: log_err("fio: bad verify type: %d\n", td->o.verify); assert(0); } - if (td->o.verify_offset) - memswp(p, p + td->o.verify_offset, hdr_size(hdr)); + + if (td->o.verify_offset && hdr_size(td, hdr)) + memswp(p, p + td->o.verify_offset, hdr_size(td, hdr)); } /* @@ -1099,10 +1147,10 @@ int get_next_verify(struct thread_data *td, struct io_u *io_u) io_u->buflen = ipo->len; io_u->numberio = ipo->numberio; io_u->file = ipo->file; - io_u->flags |= IO_U_F_VER_LIST; + io_u_set(io_u, IO_U_F_VER_LIST); if (ipo->flags & IP_F_TRIMMED) - io_u->flags |= IO_U_F_TRIMMED; + io_u_set(io_u, IO_U_F_TRIMMED); if (!fio_file_open(io_u->file)) { int r = td_io_open_file(td, io_u->file); @@ -1186,7 +1234,7 @@ static void *verify_async_thread(void *data) io_u = flist_first_entry(&list, struct io_u, verify_list); flist_del_init(&io_u->verify_list); - io_u->flags |= IO_U_F_NO_FILE_PUT; + io_u_set(io_u, IO_U_F_NO_FILE_PUT); ret = verify_io_u(td, &io_u); put_io_u(td, io_u); @@ -1337,11 +1385,23 @@ struct all_io_list *get_all_io_list(int save_mask, size_t *sz) s->depth = cpu_to_le64((uint64_t) td->o.iodepth); s->numberio = cpu_to_le64((uint64_t) td->io_issues[DDIR_WRITE]); s->index = cpu_to_le64((uint64_t) i); - s->rand.s[0] = cpu_to_le32(td->random_state.s1); - s->rand.s[1] = cpu_to_le32(td->random_state.s2); - s->rand.s[2] = cpu_to_le32(td->random_state.s3); - s->rand.s[3] = 0; - strncpy((char *) s->name, td->o.name, sizeof(s->name)); + if (td->random_state.use64) { + s->rand.state64.s[0] = cpu_to_le64(td->random_state.state64.s1); + s->rand.state64.s[1] = cpu_to_le64(td->random_state.state64.s2); + s->rand.state64.s[2] = cpu_to_le64(td->random_state.state64.s3); + s->rand.state64.s[3] = cpu_to_le64(td->random_state.state64.s4); + s->rand.state64.s[4] = cpu_to_le64(td->random_state.state64.s5); + s->rand.state64.s[5] = 0; + s->rand.use64 = cpu_to_le64((uint64_t)1); + } else { + s->rand.state32.s[0] = cpu_to_le32(td->random_state.state32.s1); + s->rand.state32.s[1] = cpu_to_le32(td->random_state.state32.s2); + s->rand.state32.s[2] = cpu_to_le32(td->random_state.state32.s3); + s->rand.state32.s[3] = 0; + s->rand.use64 = 0; + } + s->name[sizeof(s->name) - 1] = '\0'; + strncpy((char *) s->name, td->o.name, sizeof(s->name) - 1); next = io_list_next(s); } @@ -1435,23 +1495,72 @@ void verify_free_state(struct thread_data *td) free(td->vstate); } -void verify_convert_assign_state(struct thread_data *td, - struct thread_io_list *s) +static struct thread_io_list *convert_v1_list(struct thread_io_list_v1 *s) { + struct thread_io_list *til; int i; - s->no_comps = le64_to_cpu(s->no_comps); - s->depth = le64_to_cpu(s->depth); - s->numberio = le64_to_cpu(s->numberio); + til = malloc(__thread_io_list_sz(s->no_comps)); + til->no_comps = s->no_comps; + til->depth = s->depth; + til->numberio = s->numberio; + til->index = s->index; + memcpy(til->name, s->name, sizeof(til->name)); + + til->rand.use64 = 0; for (i = 0; i < 4; i++) - s->rand.s[i] = le32_to_cpu(s->rand.s[i]); + til->rand.state32.s[i] = s->rand.s[i]; + for (i = 0; i < s->no_comps; i++) - s->offsets[i] = le64_to_cpu(s->offsets[i]); + til->offsets[i] = s->offsets[i]; + + return til; +} + +void verify_convert_assign_state(struct thread_data *td, void *p, int version) +{ + struct thread_io_list *til; + int i; + + if (version == 1) { + struct thread_io_list_v1 *s = p; + + s->no_comps = le64_to_cpu(s->no_comps); + s->depth = le64_to_cpu(s->depth); + s->numberio = le64_to_cpu(s->numberio); + for (i = 0; i < 4; i++) + s->rand.s[i] = le32_to_cpu(s->rand.s[i]); + for (i = 0; i < s->no_comps; i++) + s->offsets[i] = le64_to_cpu(s->offsets[i]); + + til = convert_v1_list(s); + free(s); + } else { + struct thread_io_list *s = p; + + s->no_comps = le64_to_cpu(s->no_comps); + s->depth = le64_to_cpu(s->depth); + s->numberio = le64_to_cpu(s->numberio); + s->rand.use64 = le64_to_cpu(s->rand.use64); + + if (s->rand.use64) { + for (i = 0; i < 6; i++) + s->rand.state64.s[i] = le64_to_cpu(s->rand.state64.s[i]); + } else { + for (i = 0; i < 4; i++) + s->rand.state32.s[i] = le32_to_cpu(s->rand.state32.s[i]); + } + for (i = 0; i < s->no_comps; i++) + s->offsets[i] = le64_to_cpu(s->offsets[i]); + + til = p; + } - td->vstate = s; + td->vstate = til; } -int verify_state_hdr(struct verify_state_hdr *hdr, struct thread_io_list *s) +int verify_state_hdr(struct verify_state_hdr *hdr, struct thread_io_list *s, + int *version) { uint64_t crc; @@ -1459,20 +1568,22 @@ int verify_state_hdr(struct verify_state_hdr *hdr, struct thread_io_list *s) hdr->size = le64_to_cpu(hdr->size); hdr->crc = le64_to_cpu(hdr->crc); - if (hdr->version != VSTATE_HDR_VERSION) + if (hdr->version != VSTATE_HDR_VERSION || + hdr->version != VSTATE_HDR_VERSION_V1) return 1; crc = fio_crc32c((void *)s, hdr->size); if (crc != hdr->crc) return 1; + *version = hdr->version; return 0; } int verify_load_state(struct thread_data *td, const char *prefix) { - struct thread_io_list *s = NULL; struct verify_state_hdr hdr; + void *s = NULL; uint64_t crc; ssize_t ret; int fd; @@ -1496,7 +1607,8 @@ int verify_load_state(struct thread_data *td, const char *prefix) hdr.size = le64_to_cpu(hdr.size); hdr.crc = le64_to_cpu(hdr.crc); - if (hdr.version != VSTATE_HDR_VERSION) { + if (hdr.version != VSTATE_HDR_VERSION && + hdr.version != VSTATE_HDR_VERSION_V1) { log_err("fio: bad version in verify state header\n"); goto err; } @@ -1510,7 +1622,7 @@ int verify_load_state(struct thread_data *td, const char *prefix) goto err; } - crc = fio_crc32c((void *)s, hdr.size); + crc = fio_crc32c(s, hdr.size); if (crc != hdr.crc) { log_err("fio: verify state is corrupt\n"); goto err; @@ -1518,7 +1630,7 @@ int verify_load_state(struct thread_data *td, const char *prefix) close(fd); - verify_convert_assign_state(td, s); + verify_convert_assign_state(td, s, hdr.version); return 0; err: if (s) @@ -1539,10 +1651,12 @@ int verify_state_should_stop(struct thread_data *td, struct io_u *io_u) return 0; /* - * If we're not into the window of issues - depth yet, continue + * If we're not into the window of issues - depth yet, continue. If + * issue is shorter than depth, do check. */ - if (td->io_blocks[DDIR_READ] < s->depth || - s->numberio - td->io_blocks[DDIR_READ] > s->depth) + if ((td->io_blocks[DDIR_READ] < s->depth || + s->numberio - td->io_blocks[DDIR_READ] > s->depth) && + s->numberio > s->depth) return 0; /*