+static int __get_next_rand_offset_zipf(struct thread_data *td,
+ struct fio_file *f, enum fio_ddir ddir,
+ uint64_t *b)
+{
+ *b = zipf_next(&f->zipf);
+ return 0;
+}
+
+static int __get_next_rand_offset_pareto(struct thread_data *td,
+ struct fio_file *f, enum fio_ddir ddir,
+ uint64_t *b)
+{
+ *b = pareto_next(&f->zipf);
+ return 0;
+}
+
+static int flist_cmp(void *data, struct flist_head *a, struct flist_head *b)
+{
+ struct rand_off *r1 = flist_entry(a, struct rand_off, list);
+ struct rand_off *r2 = flist_entry(b, struct rand_off, list);
+
+ return r1->off - r2->off;
+}
+
+static int get_off_from_method(struct thread_data *td, struct fio_file *f,
+ enum fio_ddir ddir, uint64_t *b)
+{
+ if (td->o.random_distribution == FIO_RAND_DIST_RANDOM)
+ return __get_next_rand_offset(td, f, ddir, b);
+ else if (td->o.random_distribution == FIO_RAND_DIST_ZIPF)
+ return __get_next_rand_offset_zipf(td, f, ddir, b);
+ else if (td->o.random_distribution == FIO_RAND_DIST_PARETO)
+ return __get_next_rand_offset_pareto(td, f, ddir, b);
+
+ log_err("fio: unknown random distribution: %d\n", td->o.random_distribution);
+ return 1;
+}
+
+/*
+ * 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 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;
+}
+