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 |
27 | extern "C" { |
28 | #endif |
29 | |
30 | #include <sys/types.h> |
31 | #include <string.h> |
32 | |
33 | struct timespec; |
34 | struct sockaddr; |
35 | struct iovec; |
36 | |
37 | typedef struct io_context *io_context_t; |
38 | |
39 | typedef 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 | |
141 | struct io_iocb_poll { |
142 | PADDED(int events, __pad1); |
143 | }; /* result code is the set of result flags or -'ve errno */ |
144 | |
145 | struct io_iocb_sockaddr { |
146 | struct sockaddr *addr; |
147 | int len; |
148 | }; /* result code is the length of the sockaddr, or -'ve errno */ |
149 | |
150 | struct 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 | |
159 | struct 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 | |
165 | struct 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 | |
181 | struct 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 | |
192 | typedef void (*io_callback_t)(io_context_t ctx, struct iocb *iocb, long res, long res2); |
193 | |
194 | /* library wrappers */ |
195 | extern int io_queue_init(int maxevents, io_context_t *ctxp); |
196 | /*extern int io_queue_grow(io_context_t ctx, int new_maxevents);*/ |
197 | extern int io_queue_release(io_context_t ctx); |
198 | /*extern int io_queue_wait(io_context_t ctx, struct timespec *timeout);*/ |
199 | extern int io_queue_run(io_context_t ctx); |
200 | |
201 | /* Actual syscalls */ |
202 | extern int io_setup(int maxevents, io_context_t *ctxp); |
203 | extern int io_destroy(io_context_t ctx); |
204 | extern int io_submit(io_context_t ctx, long nr, struct iocb *ios[]); |
205 | extern int io_cancel(io_context_t ctx, struct iocb *iocb, struct io_event *evt); |
206 | extern int io_getevents(io_context_t ctx_id, long min_nr, long nr, struct io_event *events, struct timespec *timeout); |
207 | |
208 | |
209 | static inline void io_set_callback(struct iocb *iocb, io_callback_t cb) |
210 | { |
211 | iocb->data = (void *)cb; |
212 | } |
213 | |
214 | static 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 | |
225 | static 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 | |
236 | static 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 | |
247 | static 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 */ |
260 | static 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 | |
269 | static 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 | |
276 | static 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 | |
284 | static 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 | |
291 | static 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 | |
299 | static 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 | |
306 | static 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 | |