verify: add new experimental mode that requires no meta data

Should work fine, but we need to account and track trims to know
which blocks NOT to verify (or verify as zero).

Signed-off-by: Jens Axboe <axboe@kernel.dk>
diff --git a/backend.c b/backend.c
index 7cebf4d..507faa9 100644
--- a/backend.c
+++ b/backend.c
@@ -393,11 +393,12 @@
  * The main verify engine. Runs over the writes we previously submitted,
  * reads the blocks back in, and checks the crc/md5 of the data.
  */
-static void do_verify(struct thread_data *td)
+static void do_verify(struct thread_data *td, uint64_t verify_bytes)
 {
 	struct fio_file *f;
 	struct io_u *io_u;
 	int ret, min_events;
+	uint64_t io_bytes;
 	unsigned int i;
 
 	dprint(FD_VERIFY, "starting loop\n");
@@ -421,6 +422,7 @@
 	td_set_runstate(td, TD_VERIFYING);
 
 	io_u = NULL;
+	io_bytes = 0;
 	while (!td->terminate) {
 		enum fio_ddir ddir;
 		int ret2, full;
@@ -438,18 +440,27 @@
 		if (flow_threshold_exceeded(td))
 			continue;
 
-		io_u = __get_io_u(td);
-		if (!io_u)
-			break;
+		if (!td->o.experimental_verify) {
+			io_u = __get_io_u(td);
+			if (!io_u)
+				break;
 
-		if (get_next_verify(td, io_u)) {
-			put_io_u(td, io_u);
-			break;
-		}
+			if (get_next_verify(td, io_u)) {
+				put_io_u(td, io_u);
+				break;
+			}
 
-		if (td_io_prep(td, io_u)) {
-			put_io_u(td, io_u);
-			break;
+			if (td_io_prep(td, io_u)) {
+				put_io_u(td, io_u);
+				break;
+			}
+		} else {
+			io_u = get_io_u(td);
+			if (!io_u)
+				break;
+
+			if (io_u->buflen + io_bytes > verify_bytes)
+				break;
 		}
 
 		if (td->o.verify_async)
@@ -480,6 +491,7 @@
 				io_u->xfer_buflen = io_u->resid;
 				io_u->xfer_buf += bytes;
 				io_u->offset += bytes;
+				io_bytes += bytes;
 
 				if (ddir_rw(io_u->ddir))
 					td->ts.short_io_u[io_u->ddir]++;
@@ -495,6 +507,7 @@
 				if (ret < 0)
 					break;
 			}
+			io_bytes += io_u->xfer_buflen;
 			continue;
 		case FIO_Q_QUEUED:
 			break;
@@ -529,15 +542,18 @@
 				min_events = 1;
 
 			do {
+				unsigned long bytes = 0;
+
 				/*
 				 * Reap required number of io units, if any,
 				 * and do the verification on them through
 				 * the callback handler
 				 */
-				if (io_u_queued_complete(td, min_events, NULL) < 0) {
+				if (io_u_queued_complete(td, min_events, &bytes) < 0) {
 					ret = -1;
 					break;
 				}
+				io_bytes += bytes;
 			} while (full && (td->cur_depth > td->o.iodepth_low));
 		}
 		if (ret < 0)
@@ -1174,6 +1190,8 @@
 
 	clear_state = 0;
 	while (keep_running(td)) {
+		uint64_t write_bytes;
+
 		fio_gettime(&td->start, NULL);
 		memcpy(&td->bw_sample_time, &td->start, sizeof(td->start));
 		memcpy(&td->iops_sample_time, &td->start, sizeof(td->start));
@@ -1194,7 +1212,9 @@
 
 		prune_io_piece_log(td);
 
+		write_bytes = td->io_bytes[DDIR_WRITE];
 		do_io(td);
+		write_bytes = td->io_bytes[DDIR_WRITE] - write_bytes;
 
 		clear_state = 1;
 
@@ -1223,7 +1243,7 @@
 
 		fio_gettime(&td->start, NULL);
 
-		do_verify(td);
+		do_verify(td, write_bytes);
 
 		td->ts.runtime[DDIR_READ] += utime_since_now(&td->start);
 
diff --git a/fio.h b/fio.h
index c5e2bf1..ed793ae 100644
--- a/fio.h
+++ b/fio.h
@@ -159,6 +159,7 @@
 	unsigned int verify_async;
 	unsigned long long verify_backlog;
 	unsigned int verify_batch;
+	unsigned int experimental_verify;
 	unsigned int use_thread;
 	unsigned int unlink;
 	unsigned int do_disk_util;
diff --git a/io_u.c b/io_u.c
index 1658fb2..f020cac 100644
--- a/io_u.c
+++ b/io_u.c
@@ -183,7 +183,8 @@
 	 * any stored write metadata, just return a random offset
 	 */
 	if (!td->o.verifysort_nr || !(ddir == DDIR_READ && td->o.do_verify &&
-	    td->o.verify != VERIFY_NONE && td_random(td)))
+	    td->o.verify != VERIFY_NONE && td_random(td)) ||
+	    td->o.random_generator == FIO_RAND_GEN_TAUSWORTHE)
 		return get_off_from_method(td, f, ddir, b);
 
 	if (!flist_empty(&td->next_rand_list)) {
@@ -545,6 +546,12 @@
 	enum fio_ddir ddir;
 
 	/*
+	 * If verify phase started, it's always a READ
+	 */
+	if (td->runstate == TD_VERIFYING)
+		return DDIR_READ;
+
+	/*
 	 * see if it's time to fsync
 	 */
 	if (td->o.fsync_blocks &&
@@ -1418,7 +1425,8 @@
 
 		if (td_write(td) && idx == DDIR_WRITE &&
 		    td->o.do_verify &&
-		    td->o.verify != VERIFY_NONE)
+		    td->o.verify != VERIFY_NONE &&
+		    !td->o.experimental_verify)
 			log_io_piece(td, io_u);
 
 		icd->bytes_done[idx] += bytes;
diff --git a/libfio.c b/libfio.c
index 96ae814..8255072 100644
--- a/libfio.c
+++ b/libfio.c
@@ -82,7 +82,7 @@
 	/*
 	 * reset file done count if we are to start over
 	 */
-	if (td->o.time_based || td->o.loops)
+	if (td->o.time_based || td->o.loops || td->o.do_verify)
 		td->nr_done_files = 0;
 }