#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
-#include <assert.h>
#include <sys/mman.h>
#include "../fio.h"
-#include "../os.h"
static int fio_mmapio_queue(struct thread_data *td, struct io_u *io_u)
{
struct fio_file *f = io_u->file;
unsigned long long real_off = io_u->offset - f->file_offset;
+ fio_ro_check(td, io_u);
+
if (io_u->ddir == DDIR_READ)
memcpy(io_u->xfer_buf, f->mmap + real_off, io_u->xfer_buflen);
else if (io_u->ddir == DDIR_WRITE)
if (ret)
return ret;
+ /*
+ * for size checkup, don't mmap anything.
+ */
+ if (!f->io_size)
+ return 0;
+
if (td_rw(td))
flags = PROT_READ | PROT_WRITE;
else if (td_write(td)) {
f->mmap = mmap(NULL, f->io_size, flags, MAP_SHARED, f->fd, f->file_offset);
if (f->mmap == MAP_FAILED) {
+ int err = errno;
+
f->mmap = NULL;
- td_verror(td, errno, "mmap");
+ td_verror(td, err, "mmap");
+ if (err == EINVAL && f->io_size > 2*1024*1024*1024UL)
+ log_err("fio: mmap size likely too large\n");
goto err;
}
return 1;
}
-static void fio_mmapio_close(struct thread_data fio_unused *td,
- struct fio_file *f)
+static int fio_mmapio_close(struct thread_data fio_unused *td,
+ struct fio_file *f)
{
+ int ret = 0, ret2;
+
if (f->mmap) {
- munmap(f->mmap, f->io_size);
+ if (munmap(f->mmap, f->io_size) < 0)
+ ret = errno;
+
f->mmap = NULL;
}
- generic_close_file(td, f);
+
+ ret2 = generic_close_file(td, f);
+ if (!ret && ret2)
+ ret = ret2;
+
+ return ret;
}
static struct ioengine_ops ioengine = {
.queue = fio_mmapio_queue,
.open_file = fio_mmapio_open,
.close_file = fio_mmapio_close,
+ .get_file_size = generic_get_file_size,
.flags = FIO_SYNCIO | FIO_NOEXTEND,
};