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