[PATCH] Fix stack overflow
[fio.git] / engines / mmap.c
CommitLineData
2866c82d
JA
1/*
2 * regular read/write sync io engine
3 *
4 */
5#include <stdio.h>
6#include <stdlib.h>
7#include <unistd.h>
8#include <errno.h>
9#include <assert.h>
10#include <sys/mman.h>
5f350952
JA
11
12#include "../fio.h"
13#include "../os.h"
2866c82d
JA
14
15struct mmapio_data {
16 struct io_u *last_io_u;
17};
18
19static int fio_mmapio_getevents(struct thread_data *td, int fio_unused min,
20 int max, struct timespec fio_unused *t)
21{
22 assert(max <= 1);
23
24 /*
25 * we can only have one finished io_u for sync io, since the depth
26 * is always 1
27 */
28 if (list_empty(&td->io_u_busylist))
29 return 0;
30
31 return 1;
32}
33
34static struct io_u *fio_mmapio_event(struct thread_data *td, int event)
35{
36 struct mmapio_data *sd = td->io_ops->data;
37
38 assert(event == 0);
39
40 return sd->last_io_u;
41}
42
43
44static int fio_mmapio_queue(struct thread_data *td, struct io_u *io_u)
45{
53cdc686
JA
46 struct fio_file *f = io_u->file;
47 unsigned long long real_off = io_u->offset - f->file_offset;
2866c82d
JA
48 struct mmapio_data *sd = td->io_ops->data;
49
50 if (io_u->ddir == DDIR_READ)
cec6b55d 51 memcpy(io_u->xfer_buf, f->mmap + real_off, io_u->xfer_buflen);
87dc1ab1 52 else if (io_u->ddir == DDIR_WRITE)
cec6b55d 53 memcpy(f->mmap + real_off, io_u->xfer_buf, io_u->xfer_buflen);
b907a5b5
JA
54 else if (io_u->ddir == DDIR_SYNC) {
55 if (msync(f->mmap, f->file_size, MS_SYNC))
56 io_u->error = errno;
57 }
2866c82d
JA
58
59 /*
60 * not really direct, but should drop the pages from the cache
61 */
b907a5b5 62 if (td->odirect && io_u->ddir != DDIR_SYNC) {
cec6b55d 63 if (msync(f->mmap + real_off, io_u->xfer_buflen, MS_SYNC) < 0)
2866c82d 64 io_u->error = errno;
cec6b55d 65 if (madvise(f->mmap + real_off, io_u->xfer_buflen, MADV_DONTNEED) < 0)
2866c82d
JA
66 io_u->error = errno;
67 }
68
69 if (!io_u->error)
70 sd->last_io_u = io_u;
71
72 return io_u->error;
73}
74
2866c82d
JA
75static void fio_mmapio_cleanup(struct thread_data *td)
76{
77 if (td->io_ops->data) {
78 free(td->io_ops->data);
79 td->io_ops->data = NULL;
80 }
81}
82
83static int fio_mmapio_init(struct thread_data *td)
84{
85 struct mmapio_data *sd = malloc(sizeof(*sd));
86
87 sd->last_io_u = NULL;
88 td->io_ops->data = sd;
89 return 0;
90}
91
5f350952 92static struct ioengine_ops ioengine = {
2866c82d
JA
93 .name = "mmap",
94 .version = FIO_IOOPS_VERSION,
95 .init = fio_mmapio_init,
96 .queue = fio_mmapio_queue,
97 .getevents = fio_mmapio_getevents,
98 .event = fio_mmapio_event,
99 .cleanup = fio_mmapio_cleanup,
d9257bea 100 .flags = FIO_SYNCIO | FIO_MMAPIO,
2866c82d 101};
5f350952
JA
102
103static void fio_init fio_mmapio_register(void)
104{
105 register_ioengine(&ioengine);
106}
107
108static void fio_exit fio_mmapio_unregister(void)
109{
110 unregister_ioengine(&ioengine);
111}