X-Git-Url: https://git.kernel.dk/?a=blobdiff_plain;f=verify.c;h=ea1a911555558f503d706f100989f5b0da848439;hb=cda99fa0fcca41fc0d54ecaa2fd600162a8de5d3;hp=42ea462f0cf656d18a47e404e8d13a13a8dbd0ab;hpb=10e8a7b30ce2917df9f839d42596c7e3af9a904f;p=fio.git diff --git a/verify.c b/verify.c index 42ea462f..ea1a9115 100644 --- a/verify.c +++ b/verify.c @@ -10,6 +10,7 @@ #include "fio.h" #include "verify.h" #include "smalloc.h" +#include "trim.h" #include "lib/rand.h" #include "crc/md5.h" @@ -470,6 +471,40 @@ int verify_io_u_async(struct thread_data *td, struct io_u *io_u) return 0; } +static int verify_trimmed_io_u(struct thread_data *td, struct io_u *io_u) +{ + static char zero_buf[1024]; + unsigned int this_len, len; + int ret = 0; + void *p; + + if (!td->o.trim_zero) + return 0; + + len = io_u->buflen; + p = io_u->buf; + do { + this_len = sizeof(zero_buf); + if (this_len > len) + this_len = len; + if (memcmp(p, zero_buf, this_len)) { + ret = EILSEQ; + break; + } + len -= this_len; + p += this_len; + } while (len); + + if (!ret) + return 0; + + log_err("trim: verify failed at file %s offset %llu, length %lu" + ", block offset %lu\n", + io_u->file->file_name, io_u->offset, io_u->buflen, + (unsigned long) (p - io_u->buf)); + return ret; +} + int verify_io_u(struct thread_data *td, struct io_u *io_u) { struct verify_header *hdr; @@ -479,6 +514,10 @@ int verify_io_u(struct thread_data *td, struct io_u *io_u) if (td->o.verify == VERIFY_NULL || io_u->ddir != DDIR_READ) return 0; + if (io_u->flags & IO_U_F_TRIMMED) { + ret = verify_trimmed_io_u(td, io_u); + goto done; + } hdr_inc = io_u->buflen; if (td->o.verify_interval) @@ -570,6 +609,7 @@ int verify_io_u(struct thread_data *td, struct io_u *io_u) } } +done: if (ret && td->o.verify_fatal) td->terminate = 1; @@ -778,18 +818,25 @@ int get_next_verify(struct thread_data *td, struct io_u *io_u) ipo = rb_entry(n, struct io_piece, rb_node); rb_erase(n, &td->io_hist_tree); - td->io_hist_len--; + assert(ipo->flags & IP_F_ONRB); + ipo->flags &= ~IP_F_ONRB; } else if (!flist_empty(&td->io_hist_list)) { ipo = flist_entry(td->io_hist_list.next, struct io_piece, list); - td->io_hist_len--; flist_del(&ipo->list); + assert(ipo->flags & IP_F_ONLIST); + ipo->flags &= ~IP_F_ONLIST; } if (ipo) { + td->io_hist_len--; + io_u->offset = ipo->offset; io_u->buflen = ipo->len; io_u->file = ipo->file; + if (ipo->flags & IP_F_TRIMMED) + io_u->flags |= IO_U_F_TRIMMED; + if (!fio_file_open(io_u->file)) { int r = td_io_open_file(td, io_u->file); @@ -805,6 +852,8 @@ int get_next_verify(struct thread_data *td, struct io_u *io_u) io_u->ddir = DDIR_READ; io_u->xfer_buf = io_u->buf; io_u->xfer_buflen = io_u->buflen; + + remove_trim_entry(td, ipo); free(ipo); dprint(FD_VERIFY, "get_next_verify: ret io_u %p\n", io_u); return 0; @@ -886,12 +935,16 @@ done: int verify_async_init(struct thread_data *td) { int i, ret; + pthread_attr_t attr; + + pthread_attr_init(&attr); + pthread_attr_setstacksize(&attr, PTHREAD_STACK_MIN); td->verify_thread_exit = 0; td->verify_threads = malloc(sizeof(pthread_t) * td->o.verify_async); for (i = 0; i < td->o.verify_async; i++) { - ret = pthread_create(&td->verify_threads[i], NULL, + ret = pthread_create(&td->verify_threads[i], &attr, verify_async_thread, td); if (ret) { log_err("fio: async verify creation failed: %s\n", @@ -907,6 +960,8 @@ int verify_async_init(struct thread_data *td) td->nr_verify_threads++; } + pthread_attr_destroy(&attr); + if (i != td->o.verify_async) { log_err("fio: only %d verify threads started, exiting\n", i); td->verify_thread_exit = 1;