Improve depth marking
[fio.git] / engines / sync.c
1 /*
2  * sync/psync engine
3  *
4  * IO engine that does regular read(2)/write(2) with lseek(2) to transfer
5  * data and IO engine that does regular pread(2)/pwrite(2) to transfer data.
6  *
7  */
8 #include <stdio.h>
9 #include <stdlib.h>
10 #include <unistd.h>
11 #include <errno.h>
12 #include <assert.h>
13
14 #include "../fio.h"
15
16 static int fio_syncio_prep(struct thread_data *td, struct io_u *io_u)
17 {
18         struct fio_file *f = io_u->file;
19
20         if (io_u->ddir == DDIR_SYNC)
21                 return 0;
22         if (io_u->offset == f->last_completed_pos)
23                 return 0;
24
25         if (lseek(f->fd, io_u->offset, SEEK_SET) == -1) {
26                 td_verror(td, errno, "lseek");
27                 return 1;
28         }
29
30         return 0;
31 }
32
33 static int fio_io_end(struct thread_data *td, struct io_u *io_u, int ret)
34 {
35         if (ret != (int) io_u->xfer_buflen) {
36                 if (ret >= 0) {
37                         io_u->resid = io_u->xfer_buflen - ret;
38                         io_u->error = 0;
39                         return FIO_Q_COMPLETED;
40                 } else
41                         io_u->error = errno;
42         }
43
44         if (io_u->error)
45                 td_verror(td, io_u->error, "xfer");
46
47         return FIO_Q_COMPLETED;
48 }
49
50 static int fio_psyncio_queue(struct thread_data *td, struct io_u *io_u)
51 {
52         struct fio_file *f = io_u->file;
53         int ret;
54
55         fio_ro_check(td, io_u);
56
57         if (io_u->ddir == DDIR_READ)
58                 ret = pread(f->fd, io_u->xfer_buf, io_u->xfer_buflen, io_u->offset);
59         else if (io_u->ddir == DDIR_WRITE)
60                 ret = pwrite(f->fd, io_u->xfer_buf, io_u->xfer_buflen, io_u->offset);
61         else
62                 ret = fsync(f->fd);
63
64         return fio_io_end(td, io_u, ret);
65 }
66
67 static int fio_syncio_queue(struct thread_data *td, struct io_u *io_u)
68 {
69         struct fio_file *f = io_u->file;
70         int ret;
71
72         fio_ro_check(td, io_u);
73
74         if (io_u->ddir == DDIR_READ)
75                 ret = read(f->fd, io_u->xfer_buf, io_u->xfer_buflen);
76         else if (io_u->ddir == DDIR_WRITE)
77                 ret = write(f->fd, io_u->xfer_buf, io_u->xfer_buflen);
78         else
79                 ret = fsync(f->fd);
80
81         return fio_io_end(td, io_u, ret);
82 }
83
84 static struct ioengine_ops ioengine_rw = {
85         .name           = "sync",
86         .version        = FIO_IOOPS_VERSION,
87         .prep           = fio_syncio_prep,
88         .queue          = fio_syncio_queue,
89         .open_file      = generic_open_file,
90         .close_file     = generic_close_file,
91         .flags          = FIO_SYNCIO,
92 };
93
94 static struct ioengine_ops ioengine_prw = {
95         .name           = "psync",
96         .version        = FIO_IOOPS_VERSION,
97         .queue          = fio_psyncio_queue,
98         .open_file      = generic_open_file,
99         .close_file     = generic_close_file,
100         .flags          = FIO_SYNCIO,
101 };
102
103 static void fio_init fio_syncio_register(void)
104 {
105         register_ioengine(&ioengine_rw);
106         register_ioengine(&ioengine_prw);
107 }
108
109 static void fio_exit fio_syncio_unregister(void)
110 {
111         unregister_ioengine(&ioengine_rw);
112         unregister_ioengine(&ioengine_prw);
113 }