+/*
+ * Sort the reads for a verify phase in batches of verifysort_nr, if
+ * specified.
+ */
+static inline int should_sort_io(struct thread_data *td)
+{
+ if (!td->o.verifysort_nr || !td->o.do_verify)
+ return 0;
+ if (!td_random(td))
+ return 0;
+ if (td->runstate != TD_VERIFYING)
+ return 0;
+ if (td->o.random_generator == FIO_RAND_GEN_TAUSWORTHE)
+ return 0;
+
+ return 1;
+}
+
+static int should_do_random(struct thread_data *td, enum fio_ddir ddir)
+{
+ unsigned int v;
+ unsigned long r;
+
+ if (td->o.perc_rand[ddir] == 100)
+ return 1;
+
+ if (td->o.use_os_rand) {
+ r = os_random_long(&td->seq_rand_state[ddir]);
+ v = 1 + (int) (100.0 * (r / (OS_RAND_MAX + 1.0)));
+ } else {
+ r = __rand(&td->__seq_rand_state[ddir]);
+ v = 1 + (int) (100.0 * (r / (FRAND_MAX + 1.0)));
+ }
+
+ return v <= td->o.perc_rand[ddir];
+}
+
+static int get_next_rand_offset(struct thread_data *td, struct fio_file *f,
+ enum fio_ddir ddir, uint64_t *b)
+{
+ struct rand_off *r;
+ int i, ret = 1;
+
+ if (!should_sort_io(td))
+ return get_off_from_method(td, f, ddir, b);
+
+ if (!flist_empty(&td->next_rand_list)) {
+ struct rand_off *r;
+fetch:
+ r = flist_entry(td->next_rand_list.next, struct rand_off, list);
+ flist_del(&r->list);
+ *b = r->off;
+ free(r);
+ return 0;
+ }
+
+ for (i = 0; i < td->o.verifysort_nr; i++) {
+ r = malloc(sizeof(*r));
+
+ ret = get_off_from_method(td, f, ddir, &r->off);
+ if (ret) {
+ free(r);
+ break;
+ }
+
+ flist_add(&r->list, &td->next_rand_list);
+ }
+
+ if (ret && !i)
+ return ret;
+
+ assert(!flist_empty(&td->next_rand_list));
+ flist_sort(NULL, &td->next_rand_list, flist_cmp);
+ goto fetch;
+}
+