1/* /usr/include/libaio.h
2 *
3 * Copyright 2000,2001,2002 Red Hat, Inc.
4 *
5 * Written by Benjamin LaHaise <bcrl@redhat.com>
6 *
7 * libaio Linux async I/O interface
8 *
9 * This library is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Lesser General Public
11 * License as published by the Free Software Foundation; either
12 * version 2 of the License, or (at your option) any later version.
13 *
14 * This library is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Lesser General Public License for more details.
18 *
19 * You should have received a copy of the GNU Lesser General Public
20 * License along with this library; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 */
23#ifndef __LIBAIO_H
24#define __LIBAIO_H
25
26#ifdef __cplusplus
27extern "C" {
28#endif
29
30#include <sys/types.h>
31#include <string.h>
32
33struct timespec;
34struct sockaddr;
35struct iovec;
36
37typedef struct io_context *io_context_t;
38
39typedef enum io_iocb_cmd {
40 IO_CMD_PREAD = 0,
41 IO_CMD_PWRITE = 1,
42
43 IO_CMD_FSYNC = 2,
44 IO_CMD_FDSYNC = 3,
45
46 IO_CMD_POLL = 5, /* Never implemented in mainline, see io_prep_poll */
47 IO_CMD_NOOP = 6,
48 IO_CMD_PREADV = 7,
49 IO_CMD_PWRITEV = 8,
50} io_iocb_cmd_t;
51
52#if defined(__i386__) /* little endian, 32 bits */
53#define PADDED(x, y) x; unsigned y
54#define PADDEDptr(x, y) x; unsigned y
55#define PADDEDul(x, y) unsigned long x; unsigned y
56#elif defined(__ia64__) || defined(__x86_64__) || defined(__alpha__)
57#define PADDED(x, y) x, y
58#define PADDEDptr(x, y) x
59#define PADDEDul(x, y) unsigned long x
60#elif defined(__powerpc64__) || \
61 (defined(__sparc__) && defined(__arch64__)) /* big endian, 64 bits */
62#define PADDED(x, y) unsigned y; x
63#define PADDEDptr(x,y) x
64#define PADDEDul(x, y) unsigned long x
65#elif defined(__PPC__) /* big endian, 32 bits */
66#define PADDED(x, y) unsigned y; x
67#define PADDEDptr(x, y) unsigned y; x
68#define PADDEDul(x, y) unsigned y; unsigned long x
69#elif defined(__s390x__) /* big endian, 64 bits */
70#define PADDED(x, y) unsigned y; x
71#define PADDEDptr(x,y) x
72#define PADDEDul(x, y) unsigned long x
73#elif defined(__s390__) /* big endian, 32 bits */
74#define PADDED(x, y) unsigned y; x
75#define PADDEDptr(x, y) unsigned y; x
76#define PADDEDul(x, y) unsigned y; unsigned long x
77#elif defined(__arm__)
78# if defined (__ARMEB__) /* big endian, 32 bits */
79#define PADDED(x, y) unsigned y; x
80#define PADDEDptr(x, y) unsigned y; x
81#define PADDEDul(x, y) unsigned y; unsigned long x
82# else /* little endian, 32 bits */
83#define PADDED(x, y) x; unsigned y
84#define PADDEDptr(x, y) x; unsigned y
85#define PADDEDul(x, y) unsigned long x; unsigned y
86# endif
87#elif defined(__m68k__) /* big endian, 32 bits */
88#define PADDED(x, y) unsigned y; x
89#define PADDEDptr(x, y) unsigned y; x
90#define PADDEDul(x, y) unsigned y; unsigned long x
91#elif defined(__sparc__) /* big endian, 32 bits */
92#define PADDED(x, y) unsigned y; x
93#define PADDEDptr(x, y) unsigned y; x
94#define PADDEDul(x, y) unsigned y; unsigned long x
95#elif defined(__hppa__)
96# if defined(__arch64__) /* big endian, 64 bits */
97#define PADDED(x, y) unsigned y; x
98#define PADDEDptr(x,y) x
99#define PADDEDul(x, y) unsigned long x
100# else /* big endian, 32 bits */
101#define PADDED(x, y) unsigned y; x
102#define PADDEDptr(x, y) unsigned y; x
103#define PADDEDul(x, y) unsigned y; unsigned long x
104#endif
105#elif defined(__mips__)
106# if defined (__MIPSEB__) /* big endian, 32 bits */
107#define PADDED(x, y) unsigned y; x
108#define PADDEDptr(x, y) unsigned y; x
109#define PADDEDul(x, y) unsigned y; unsigned long x
110# elif defined(__MIPSEL__) /* little endian, 32 bits */
111#define PADDED(x, y) x; unsigned y
112#define PADDEDptr(x, y) x; unsigned y
113#define PADDEDul(x, y) unsigned long x; unsigned y
114# else
115# error "neither mipseb nor mipsel?"
116# endif
117#elif defined(__sh__) /* sh3/sh4*/
118# if defined (__BIG_ENDIAN__) /* big endian, 32 bits */
119#define PADDED(x, y) unsigned y; x
120#define PADDEDptr(x, y) unsigned y; x
121#define PADDEDul(x, y) unsigned y; unsigned long x
122# elif defined(__LITTLE_ENDIAN__) /* little endian, 32 bits */
123#define PADDED(x, y) x; unsigned y
124#define PADDEDptr(x, y) x; unsigned y
125#define PADDEDul(x, y) unsigned long x; unsigned y
126# endif
127#elif defined(__aarch64__)
128# if defined (__AARCH64EB__) /* big endian, 64 bits */
129#define PADDED(x, y) unsigned y; x
130#define PADDEDptr(x,y) x
131#define PADDEDul(x, y) unsigned long x
132# elif defined(__AARCH64EL__) /* little endian, 64 bits */
133#define PADDED(x, y) x, y
134#define PADDEDptr(x, y) x
135#define PADDEDul(x, y) unsigned long x
136# endif
137#else
138#error endian?
139#endif
140
141struct io_iocb_poll {
142 PADDED(int events, __pad1);
143}; /* result code is the set of result flags or -'ve errno */
144
145struct io_iocb_sockaddr {
146 struct sockaddr *addr;
147 int len;
148}; /* result code is the length of the sockaddr, or -'ve errno */
149
150struct io_iocb_common {
151 PADDEDptr(void *buf, __pad1);
152 PADDEDul(nbytes, __pad2);
153 long long offset;
154 long long __pad3;
155 unsigned flags;
156 unsigned resfd;
157}; /* result code is the amount read or -'ve errno */
158
159struct io_iocb_vector {
160 const struct iovec *vec;
161 int nr;
162 long long offset;
163}; /* result code is the amount read or -'ve errno */
164
165struct iocb {
166 PADDEDptr(void *data, __pad1); /* Return in the io completion event */
167 PADDED(unsigned key, __pad2); /* For use in identifying io requests */
168
169 short aio_lio_opcode;
170 short aio_reqprio;
171 int aio_fildes;
172
173 union {
174 struct io_iocb_common c;
175 struct io_iocb_vector v;
176 struct io_iocb_poll poll;
177 struct io_iocb_sockaddr saddr;
178 } u;
179};
180
181struct io_event {
182 PADDEDptr(void *data, __pad1);
183 PADDEDptr(struct iocb *obj, __pad2);
184 PADDEDul(res, __pad3);
185 PADDEDul(res2, __pad4);
186};
187
188#undef PADDED
189#undef PADDEDptr
190#undef PADDEDul
191
192typedef void (*io_callback_t)(io_context_t ctx, struct iocb *iocb, long res, long res2);
193
194/* library wrappers */
195extern int io_queue_init(int maxevents, io_context_t *ctxp);
196/*extern int io_queue_grow(io_context_t ctx, int new_maxevents);*/
197extern int io_queue_release(io_context_t ctx);
198/*extern int io_queue_wait(io_context_t ctx, struct timespec *timeout);*/
199extern int io_queue_run(io_context_t ctx);
200
201/* Actual syscalls */
202extern int io_setup(int maxevents, io_context_t *ctxp);
203extern int io_destroy(io_context_t ctx);
204extern int io_submit(io_context_t ctx, long nr, struct iocb *ios[]);
205extern int io_cancel(io_context_t ctx, struct iocb *iocb, struct io_event *evt);
206extern int io_getevents(io_context_t ctx_id, long min_nr, long nr, struct io_event *events, struct timespec *timeout);
207
208
209static inline void io_set_callback(struct iocb *iocb, io_callback_t cb)
210{
211 iocb->data = (void *)cb;
212}
213
214static inline void io_prep_pread(struct iocb *iocb, int fd, void *buf, size_t count, long long offset)
215{
216 memset(iocb, 0, sizeof(*iocb));
217 iocb->aio_fildes = fd;
218 iocb->aio_lio_opcode = IO_CMD_PREAD;
219 iocb->aio_reqprio = 0;
220 iocb->u.c.buf = buf;
221 iocb->u.c.nbytes = count;
222 iocb->u.c.offset = offset;
223}
224
225static inline void io_prep_pwrite(struct iocb *iocb, int fd, void *buf, size_t count, long long offset)
226{
227 memset(iocb, 0, sizeof(*iocb));
228 iocb->aio_fildes = fd;
229 iocb->aio_lio_opcode = IO_CMD_PWRITE;
230 iocb->aio_reqprio = 0;
231 iocb->u.c.buf = buf;
232 iocb->u.c.nbytes = count;
233 iocb->u.c.offset = offset;
234}
235
236static inline void io_prep_preadv(struct iocb *iocb, int fd, const struct iovec *iov, int iovcnt, long long offset)
237{
238 memset(iocb, 0, sizeof(*iocb));
239 iocb->aio_fildes = fd;
240 iocb->aio_lio_opcode = IO_CMD_PREADV;
241 iocb->aio_reqprio = 0;
242 iocb->u.c.buf = (void *)iov;
243 iocb->u.c.nbytes = iovcnt;
244 iocb->u.c.offset = offset;
245}
246
247static inline void io_prep_pwritev(struct iocb *iocb, int fd, const struct iovec *iov, int iovcnt, long long offset)
248{
249 memset(iocb, 0, sizeof(*iocb));
250 iocb->aio_fildes = fd;
251 iocb->aio_lio_opcode = IO_CMD_PWRITEV;
252 iocb->aio_reqprio = 0;
253 iocb->u.c.buf = (void *)iov;
254 iocb->u.c.nbytes = iovcnt;
255 iocb->u.c.offset = offset;
256}
257
258/* Jeff Moyer says this was implemented in Red Hat AS2.1 and RHEL3.
259 * AFAICT, it was never in mainline, and should not be used. --RR */
260static inline void io_prep_poll(struct iocb *iocb, int fd, int events)
261{
262 memset(iocb, 0, sizeof(*iocb));
263 iocb->aio_fildes = fd;
264 iocb->aio_lio_opcode = IO_CMD_POLL;
265 iocb->aio_reqprio = 0;
266 iocb->u.poll.events = events;
267}
268
269static inline int io_poll(io_context_t ctx, struct iocb *iocb, io_callback_t cb, int fd, int events)
270{
271 io_prep_poll(iocb, fd, events);
272 io_set_callback(iocb, cb);
273 return io_submit(ctx, 1, &iocb);
274}
275
276static inline void io_prep_fsync(struct iocb *iocb, int fd)
277{
278 memset(iocb, 0, sizeof(*iocb));
279 iocb->aio_fildes = fd;
280 iocb->aio_lio_opcode = IO_CMD_FSYNC;
281 iocb->aio_reqprio = 0;
282}
283
284static inline int io_fsync(io_context_t ctx, struct iocb *iocb, io_callback_t cb, int fd)
285{
286 io_prep_fsync(iocb, fd);
287 io_set_callback(iocb, cb);
288 return io_submit(ctx, 1, &iocb);
289}
290
291static inline void io_prep_fdsync(struct iocb *iocb, int fd)
292{
293 memset(iocb, 0, sizeof(*iocb));
294 iocb->aio_fildes = fd;
295 iocb->aio_lio_opcode = IO_CMD_FDSYNC;
296 iocb->aio_reqprio = 0;
297}
298
299static inline int io_fdsync(io_context_t ctx, struct iocb *iocb, io_callback_t cb, int fd)
300{
301 io_prep_fdsync(iocb, fd);
302 io_set_callback(iocb, cb);
303 return io_submit(ctx, 1, &iocb);
304}
305
306static inline void io_set_eventfd(struct iocb *iocb, int eventfd)
307{
308 iocb->u.c.flags |= (1 << 0) /* IOCB_FLAG_RESFD */;
309 iocb->u.c.resfd = eventfd;
310}
311
312#ifdef __cplusplus
313}
314#endif
315
316#endif /* __LIBAIO_H */
317