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