[PATCH] Remember to check ioops version in loaded module
[fio.git] / engines / fio-engine-sync.c
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 "fio.h"
11 #include "os.h"
12
13 struct syncio_data {
14         struct io_u *last_io_u;
15 };
16
17 static int fio_syncio_sync(struct thread_data *td)
18 {
19         return fsync(td->fd);
20 }
21
22 static int fio_syncio_getevents(struct thread_data *td, int fio_unused min,
23                                 int max, struct timespec fio_unused *t)
24 {
25         assert(max <= 1);
26
27         /*
28          * we can only have one finished io_u for sync io, since the depth
29          * is always 1
30          */
31         if (list_empty(&td->io_u_busylist))
32                 return 0;
33
34         return 1;
35 }
36
37 static struct io_u *fio_syncio_event(struct thread_data *td, int event)
38 {
39         struct syncio_data *sd = td->io_ops->data;
40
41         assert(event == 0);
42
43         return sd->last_io_u;
44 }
45
46 static int fio_syncio_prep(struct thread_data *td, struct io_u *io_u)
47 {
48         if (lseek(td->fd, io_u->offset, SEEK_SET) == -1) {
49                 td_verror(td, errno);
50                 return 1;
51         }
52
53         return 0;
54 }
55
56 static int fio_syncio_queue(struct thread_data *td, struct io_u *io_u)
57 {
58         struct syncio_data *sd = td->io_ops->data;
59         int ret;
60
61         if (io_u->ddir == DDIR_READ)
62                 ret = read(td->fd, io_u->buf, io_u->buflen);
63         else
64                 ret = write(td->fd, io_u->buf, io_u->buflen);
65
66         if ((unsigned int) ret != io_u->buflen) {
67                 if (ret > 0) {
68                         io_u->resid = io_u->buflen - ret;
69                         io_u->error = EIO;
70                 } else
71                         io_u->error = errno;
72         }
73
74         if (!io_u->error)
75                 sd->last_io_u = io_u;
76
77         return io_u->error;
78 }
79
80 static void fio_syncio_cleanup(struct thread_data *td)
81 {
82         if (td->io_ops->data) {
83                 free(td->io_ops->data);
84                 td->io_ops->data = NULL;
85         }
86 }
87
88 static int fio_syncio_init(struct thread_data *td)
89 {
90         struct syncio_data *sd = malloc(sizeof(*sd));
91
92         sd->last_io_u = NULL;
93         td->io_ops->data = sd;
94         return 0;
95 }
96
97 struct ioengine_ops ioengine = {
98         .name           = "sync",
99         .version        = FIO_IOOPS_VERSION,
100         .init           = fio_syncio_init,
101         .prep           = fio_syncio_prep,
102         .queue          = fio_syncio_queue,
103         .getevents      = fio_syncio_getevents,
104         .event          = fio_syncio_event,
105         .cleanup        = fio_syncio_cleanup,
106         .sync           = fio_syncio_sync,
107         .flags          = FIO_SYNCIO,
108 };