+ret_good:
+ f->failed_rands = 0;
+ret:
+ return 0;
+}
+
+static int get_next_rand_block(struct thread_data *td, struct fio_file *f,
+ enum fio_ddir ddir, unsigned long long *b)
+{
+ if (get_next_rand_offset(td, f, ddir, b)) {
+ dprint(FD_IO, "%s: rand offset failed, last=%llu, size=%llu\n",
+ f->file_name, f->last_pos, f->real_file_size);
+ return 1;
+ }
+
+ return 0;
+}
+
+static int get_next_seq_block(struct thread_data *td, struct fio_file *f,
+ enum fio_ddir ddir, unsigned long long *b)
+{
+ assert(ddir_rw(ddir));
+
+ if (f->last_pos < f->real_file_size) {
+ *b = (f->last_pos - f->file_offset) / td->o.min_bs[ddir];
+ return 0;
+ }
+
+ return 1;
+}
+
+static int get_next_block(struct thread_data *td, struct io_u *io_u,
+ enum fio_ddir ddir, int rw_seq, unsigned long long *b)
+{
+ struct fio_file *f = io_u->file;
+ int ret;
+
+ assert(ddir_rw(ddir));
+
+ if (rw_seq) {
+ if (td_random(td))
+ ret = get_next_rand_block(td, f, ddir, b);
+ else
+ ret = get_next_seq_block(td, f, ddir, b);
+ } else {
+ io_u->flags |= IO_U_F_BUSY_OK;
+
+ if (td->o.rw_seq == RW_SEQ_SEQ) {
+ ret = get_next_seq_block(td, f, ddir, b);
+ if (ret)
+ ret = get_next_rand_block(td, f, ddir, b);
+ } else if (td->o.rw_seq == RW_SEQ_IDENT) {
+ if (f->last_start != -1ULL)
+ *b = (f->last_start - f->file_offset)
+ / td->o.min_bs[ddir];
+ else
+ *b = 0;
+ ret = 0;
+ } else {
+ log_err("fio: unknown rw_seq=%d\n", td->o.rw_seq);
+ ret = 1;
+ }
+ }
+
+ return ret;