+static int pre_read_file(struct thread_data *td, struct fio_file *f)
+{
+ int r, did_open = 0, old_runstate;
+ unsigned long long left;
+ unsigned int bs;
+ char *b;
+
+ if (td->io_ops->flags & FIO_PIPEIO)
+ return 0;
+
+ if (!fio_file_open(f)) {
+ if (td->io_ops->open_file(td, f)) {
+ log_err("fio: cannot pre-read, failed to open file\n");
+ return 1;
+ }
+ did_open = 1;
+ }
+
+ old_runstate = td->runstate;
+ td_set_runstate(td, TD_PRE_READING);
+
+ bs = td->o.max_bs[DDIR_READ];
+ b = malloc(bs);
+ memset(b, 0, bs);
+
+ lseek(f->fd, f->file_offset, SEEK_SET);
+ left = f->io_size;
+
+ while (left && !td->terminate) {
+ if (bs > left)
+ bs = left;
+
+ r = read(f->fd, b, bs);
+
+ if (r == (int) bs) {
+ left -= bs;
+ continue;
+ } else {
+ td_verror(td, EIO, "pre_read");
+ break;
+ }
+ }
+
+ td_set_runstate(td, old_runstate);
+
+ if (did_open)
+ td->io_ops->close_file(td, f);
+ free(b);
+ return 0;
+}
+