ioengine.h revision ca7e0ddb08fece35c95e9056ca877e0806f1e6ef
1#ifndef FIO_IOENGINE_H
2#define FIO_IOENGINE_H
3
4#define FIO_IOOPS_VERSION	12
5
6enum {
7	IO_U_F_FREE		= 1 << 0,
8	IO_U_F_FLIGHT		= 1 << 1,
9	IO_U_F_FREE_DEF		= 1 << 2,
10	IO_U_F_IN_CUR_DEPTH	= 1 << 3,
11	IO_U_F_BUSY_OK		= 1 << 4,
12	IO_U_F_TRIMMED		= 1 << 5,
13	IO_U_F_BARRIER		= 1 << 6,
14};
15
16/*
17 * The io unit
18 */
19struct io_u {
20	union {
21#ifdef FIO_HAVE_LIBAIO
22		struct iocb iocb;
23#endif
24#ifdef FIO_HAVE_POSIXAIO
25		struct aiocb aiocb;
26#endif
27#ifdef FIO_HAVE_SGIO
28		struct sg_io_hdr hdr;
29#endif
30#ifdef FIO_HAVE_GUASI
31		guasi_req_t greq;
32#endif
33#ifdef FIO_HAVE_SOLARISAIO
34		aio_result_t resultp;
35#endif
36#ifdef FIO_HAVE_BINJECT
37		struct b_user_cmd buc;
38#endif
39		void *mmap_data;
40	};
41	struct timeval start_time;
42	struct timeval issue_time;
43
44	/*
45	 * Allocated/set buffer and length
46	 */
47	void *buf;
48	unsigned long buflen;
49	unsigned long long offset;
50
51	/*
52	 * IO engine state, may be different from above when we get
53	 * partial transfers / residual data counts
54	 */
55	void *xfer_buf;
56	unsigned long xfer_buflen;
57
58	/*
59	 * Parameter related to pre-filled buffers and
60	 * their size to handle variable block sizes.
61	 */
62	unsigned long buf_filled_len;
63
64	unsigned int resid;
65	unsigned int error;
66
67	enum fio_ddir ddir;
68
69	/*
70	 * io engine private data
71	 */
72	union {
73		unsigned int index;
74		unsigned int seen;
75		void *engine_data;
76	};
77
78	unsigned int flags;
79
80	struct fio_file *file;
81
82	struct flist_head list;
83
84	/*
85	 * Callback for io completion
86	 */
87	int (*end_io)(struct thread_data *, struct io_u *);
88};
89
90/*
91 * io_ops->queue() return values
92 */
93enum {
94	FIO_Q_COMPLETED	= 0,		/* completed sync */
95	FIO_Q_QUEUED	= 1,		/* queued, will complete async */
96	FIO_Q_BUSY	= 2,		/* no more room, call ->commit() */
97};
98
99struct ioengine_ops {
100	struct flist_head list;
101	char name[16];
102	int version;
103	int flags;
104	int (*setup)(struct thread_data *);
105	int (*init)(struct thread_data *);
106	int (*prep)(struct thread_data *, struct io_u *);
107	int (*queue)(struct thread_data *, struct io_u *);
108	int (*commit)(struct thread_data *);
109	int (*getevents)(struct thread_data *, unsigned int, unsigned int, struct timespec *);
110	struct io_u *(*event)(struct thread_data *, int);
111	int (*cancel)(struct thread_data *, struct io_u *);
112	void (*cleanup)(struct thread_data *);
113	int (*open_file)(struct thread_data *, struct fio_file *);
114	int (*close_file)(struct thread_data *, struct fio_file *);
115	int (*get_file_size)(struct thread_data *, struct fio_file *);
116	void *data;
117	void *dlhandle;
118};
119
120enum fio_ioengine_flags {
121	FIO_SYNCIO	= 1 << 0,	/* io engine has synchronous ->queue */
122	FIO_RAWIO	= 1 << 1,	/* some sort of direct/raw io */
123	FIO_DISKLESSIO	= 1 << 2,	/* no disk involved */
124	FIO_NOEXTEND	= 1 << 3,	/* engine can't extend file */
125	FIO_NODISKUTIL  = 1 << 4,       /* diskutil can't handle filename */
126	FIO_UNIDIR	= 1 << 5,	/* engine is uni-directional */
127	FIO_NOIO	= 1 << 6,	/* thread does only pseudo IO */
128	FIO_SIGQUIT	= 1 << 7,	/* needs SIGQUIT to exit */
129	FIO_PIPEIO	= 1 << 8,	/* input/output no seekable */
130	FIO_BARRIER	= 1 << 9,	/* engine supports barriers */
131	FIO_MEMALIGN	= 1 << 10,	/* engine wants aligned memory */
132};
133
134/*
135 * io engine entry points
136 */
137extern int __must_check td_io_init(struct thread_data *);
138extern int __must_check td_io_prep(struct thread_data *, struct io_u *);
139extern int __must_check td_io_queue(struct thread_data *, struct io_u *);
140extern int __must_check td_io_sync(struct thread_data *, struct fio_file *);
141extern int __must_check td_io_getevents(struct thread_data *, unsigned int, unsigned int, struct timespec *);
142extern int __must_check td_io_commit(struct thread_data *);
143extern int __must_check td_io_open_file(struct thread_data *, struct fio_file *);
144extern int td_io_close_file(struct thread_data *, struct fio_file *);
145extern int __must_check td_io_get_file_size(struct thread_data *, struct fio_file *);
146
147extern struct ioengine_ops *load_ioengine(struct thread_data *, const char *);
148extern void register_ioengine(struct ioengine_ops *);
149extern void unregister_ioengine(struct ioengine_ops *);
150extern void close_ioengine(struct thread_data *);
151
152/*
153 * io unit handling
154 */
155#define queue_full(td)	flist_empty(&(td)->io_u_freelist)
156extern struct io_u *__get_io_u(struct thread_data *);
157extern struct io_u *get_io_u(struct thread_data *);
158extern void put_io_u(struct thread_data *, struct io_u *);
159extern void clear_io_u(struct thread_data *, struct io_u *);
160extern void requeue_io_u(struct thread_data *, struct io_u **);
161extern int __must_check io_u_sync_complete(struct thread_data *, struct io_u *, unsigned long *);
162extern int __must_check io_u_queued_complete(struct thread_data *, int, unsigned long *);
163extern void io_u_queued(struct thread_data *, struct io_u *);
164extern void io_u_log_error(struct thread_data *, struct io_u *);
165extern void io_u_mark_depth(struct thread_data *, unsigned int);
166extern void io_u_fill_buffer(struct thread_data *td, struct io_u *, unsigned int);
167void io_u_mark_complete(struct thread_data *, unsigned int);
168void io_u_mark_submit(struct thread_data *, unsigned int);
169
170int do_io_u_sync(struct thread_data *, struct io_u *);
171int do_io_u_trim(struct thread_data *, struct io_u *);
172
173#ifdef FIO_INC_DEBUG
174static inline void dprint_io_u(struct io_u *io_u, const char *p)
175{
176	struct fio_file *f = io_u->file;
177
178	dprint(FD_IO, "%s: io_u %p: off=%llu/len=%lu/ddir=%d", p, io_u,
179					(unsigned long long) io_u->offset,
180					io_u->buflen, io_u->ddir);
181	if (fio_debug & (1 << FD_IO)) {
182		if (f)
183			log_info("/%s", f->file_name);
184
185		log_info("\n");
186	}
187}
188#else
189#define dprint_io_u(io_u, p)
190#endif
191
192#endif
193