+static int fio_mmapio_open(struct thread_data *td, struct fio_file *f)
+{
+ int ret, flags;
+
+ ret = generic_open_file(td, f);
+ if (ret)
+ return ret;
+
+ if (td_rw(td))
+ flags = PROT_READ | PROT_WRITE;
+ else if (td_write(td)) {
+ flags = PROT_WRITE;
+
+ if (td->o.verify != VERIFY_NONE)
+ flags |= PROT_READ;
+ } else
+ flags = PROT_READ;
+
+ f->mmap = mmap(NULL, f->io_size, flags, MAP_SHARED, f->fd, f->file_offset);
+ if (f->mmap == MAP_FAILED) {
+ f->mmap = NULL;
+ td_verror(td, errno, "mmap");
+ goto err;
+ }
+
+ if (file_invalidate_cache(td, f))
+ goto err;
+
+ if (!td_random(td)) {
+ if (madvise(f->mmap, f->io_size, MADV_SEQUENTIAL) < 0) {
+ td_verror(td, errno, "madvise");
+ goto err;
+ }
+ } else {
+ if (madvise(f->mmap, f->io_size, MADV_RANDOM) < 0) {
+ td_verror(td, errno, "madvise");
+ goto err;
+ }
+ }
+
+ return 0;
+
+err:
+ td->io_ops->close_file(td, f);
+ return 1;
+}
+
+static void fio_mmapio_close(struct thread_data fio_unused *td,
+ struct fio_file *f)
+{
+ if (f->mmap) {
+ munmap(f->mmap, f->io_size);
+ f->mmap = NULL;
+ }
+ generic_close_file(td, f);
+}
+