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 | /* little endian, 32 bits */ |
53 | #if defined(__i386__) || (defined(__arm__) && !defined(__ARMEB__)) || \ |
54 | (defined(__sh__) && defined(__LITTLE_ENDIAN__)) || \ |
55 | defined(__bfin__) || \ |
56 | (defined(__MIPSEL__) && !defined(__mips64)) || \ |
57 | defined(__cris__) |
58 | #define PADDED(x, y) x; unsigned y |
59 | #define PADDEDptr(x, y) x; unsigned y |
60 | #define PADDEDul(x, y) unsigned long x; unsigned y |
61 | |
62 | /* little endian, 64 bits */ |
63 | #elif defined(__ia64__) || defined(__x86_64__) || defined(__alpha__) || \ |
64 | (defined(__mips64) && defined(__MIPSEL__)) || \ |
65 | (defined(__aarch64__) && defined(__AARCH64EL__)) |
66 | #define PADDED(x, y) x, y |
67 | #define PADDEDptr(x, y) x |
68 | #define PADDEDul(x, y) unsigned long x |
69 | |
70 | /* big endian, 64 bits */ |
71 | #elif defined(__powerpc64__) || defined(__s390x__) || \ |
72 | (defined(__hppa__) && defined(__arch64__)) || \ |
73 | (defined(__sparc__) && defined(__arch64__)) || \ |
74 | (defined(__mips64) && defined(__MIPSEB__)) || \ |
75 | (defined(__aarch64__) && defined(__AARCH64EB__)) |
76 | #define PADDED(x, y) unsigned y; x |
77 | #define PADDEDptr(x,y) x |
78 | #define PADDEDul(x, y) unsigned long x |
79 | |
80 | /* big endian, 32 bits */ |
81 | #elif defined(__PPC__) || defined(__s390__) || \ |
82 | (defined(__arm__) && defined(__ARMEB__)) || \ |
83 | (defined(__sh__) && defined (__BIG_ENDIAN__)) || \ |
84 | defined(__sparc__) || defined(__MIPSEB__) || defined(__m68k__) || \ |
85 | defined(__hppa__) || defined(__frv__) || defined(__avr32__) |
86 | #define PADDED(x, y) unsigned y; x |
87 | #define PADDEDptr(x, y) unsigned y; x |
88 | #define PADDEDul(x, y) unsigned y; unsigned long x |
89 | |
90 | #else |
91 | #error endian? |
92 | #endif |
93 | |
94 | struct io_iocb_poll { |
95 | PADDED(int events, __pad1); |
96 | }; /* result code is the set of result flags or -'ve errno */ |
97 | |
98 | struct io_iocb_sockaddr { |
99 | struct sockaddr *addr; |
100 | int len; |
101 | }; /* result code is the length of the sockaddr, or -'ve errno */ |
102 | |
103 | struct io_iocb_common { |
104 | PADDEDptr(void *buf, __pad1); |
105 | PADDEDul(nbytes, __pad2); |
106 | long long offset; |
107 | long long __pad3; |
108 | unsigned flags; |
109 | unsigned resfd; |
110 | }; /* result code is the amount read or -'ve errno */ |
111 | |
112 | struct io_iocb_vector { |
113 | const struct iovec *vec; |
114 | int nr; |
115 | long long offset; |
116 | }; /* result code is the amount read or -'ve errno */ |
117 | |
118 | struct iocb { |
119 | PADDEDptr(void *data, __pad1); /* Return in the io completion event */ |
120 | PADDED(unsigned key, __pad2); /* For use in identifying io requests */ |
121 | |
122 | short aio_lio_opcode; |
123 | short aio_reqprio; |
124 | int aio_fildes; |
125 | |
126 | union { |
127 | struct io_iocb_common c; |
128 | struct io_iocb_vector v; |
129 | struct io_iocb_poll poll; |
130 | struct io_iocb_sockaddr saddr; |
131 | } u; |
132 | }; |
133 | |
134 | struct io_event { |
135 | PADDEDptr(void *data, __pad1); |
136 | PADDEDptr(struct iocb *obj, __pad2); |
137 | PADDEDul(res, __pad3); |
138 | PADDEDul(res2, __pad4); |
139 | }; |
140 | |
141 | #undef PADDED |
142 | #undef PADDEDptr |
143 | #undef PADDEDul |
144 | |
145 | typedef void (*io_callback_t)(io_context_t ctx, struct iocb *iocb, long res, long res2); |
146 | |
147 | /* library wrappers */ |
148 | extern int io_queue_init(int maxevents, io_context_t *ctxp); |
149 | /*extern int io_queue_grow(io_context_t ctx, int new_maxevents);*/ |
150 | extern int io_queue_release(io_context_t ctx); |
151 | /*extern int io_queue_wait(io_context_t ctx, struct timespec *timeout);*/ |
152 | extern int io_queue_run(io_context_t ctx); |
153 | |
154 | /* Actual syscalls */ |
155 | extern int io_setup(int maxevents, io_context_t *ctxp); |
156 | extern int io_destroy(io_context_t ctx); |
157 | extern int io_submit(io_context_t ctx, long nr, struct iocb *ios[]); |
158 | extern int io_cancel(io_context_t ctx, struct iocb *iocb, struct io_event *evt); |
159 | extern int io_getevents(io_context_t ctx_id, long min_nr, long nr, struct io_event *events, struct timespec *timeout); |
160 | |
161 | |
162 | static inline void io_set_callback(struct iocb *iocb, io_callback_t cb) |
163 | { |
164 | iocb->data = (void *)cb; |
165 | } |
166 | |
167 | static inline void io_prep_pread(struct iocb *iocb, int fd, void *buf, size_t count, long long offset) |
168 | { |
169 | memset(iocb, 0, sizeof(*iocb)); |
170 | iocb->aio_fildes = fd; |
171 | iocb->aio_lio_opcode = IO_CMD_PREAD; |
172 | iocb->aio_reqprio = 0; |
173 | iocb->u.c.buf = buf; |
174 | iocb->u.c.nbytes = count; |
175 | iocb->u.c.offset = offset; |
176 | } |
177 | |
178 | static inline void io_prep_pwrite(struct iocb *iocb, int fd, void *buf, size_t count, long long offset) |
179 | { |
180 | memset(iocb, 0, sizeof(*iocb)); |
181 | iocb->aio_fildes = fd; |
182 | iocb->aio_lio_opcode = IO_CMD_PWRITE; |
183 | iocb->aio_reqprio = 0; |
184 | iocb->u.c.buf = buf; |
185 | iocb->u.c.nbytes = count; |
186 | iocb->u.c.offset = offset; |
187 | } |
188 | |
189 | static inline void io_prep_preadv(struct iocb *iocb, int fd, const struct iovec *iov, int iovcnt, long long offset) |
190 | { |
191 | memset(iocb, 0, sizeof(*iocb)); |
192 | iocb->aio_fildes = fd; |
193 | iocb->aio_lio_opcode = IO_CMD_PREADV; |
194 | iocb->aio_reqprio = 0; |
195 | iocb->u.c.buf = (void *)iov; |
196 | iocb->u.c.nbytes = iovcnt; |
197 | iocb->u.c.offset = offset; |
198 | } |
199 | |
200 | static inline void io_prep_pwritev(struct iocb *iocb, int fd, const struct iovec *iov, int iovcnt, long long offset) |
201 | { |
202 | memset(iocb, 0, sizeof(*iocb)); |
203 | iocb->aio_fildes = fd; |
204 | iocb->aio_lio_opcode = IO_CMD_PWRITEV; |
205 | iocb->aio_reqprio = 0; |
206 | iocb->u.c.buf = (void *)iov; |
207 | iocb->u.c.nbytes = iovcnt; |
208 | iocb->u.c.offset = offset; |
209 | } |
210 | |
211 | /* Jeff Moyer says this was implemented in Red Hat AS2.1 and RHEL3. |
212 | * AFAICT, it was never in mainline, and should not be used. --RR */ |
213 | static inline void io_prep_poll(struct iocb *iocb, int fd, int events) |
214 | { |
215 | memset(iocb, 0, sizeof(*iocb)); |
216 | iocb->aio_fildes = fd; |
217 | iocb->aio_lio_opcode = IO_CMD_POLL; |
218 | iocb->aio_reqprio = 0; |
219 | iocb->u.poll.events = events; |
220 | } |
221 | |
222 | static inline int io_poll(io_context_t ctx, struct iocb *iocb, io_callback_t cb, int fd, int events) |
223 | { |
224 | io_prep_poll(iocb, fd, events); |
225 | io_set_callback(iocb, cb); |
226 | return io_submit(ctx, 1, &iocb); |
227 | } |
228 | |
229 | static inline void io_prep_fsync(struct iocb *iocb, int fd) |
230 | { |
231 | memset(iocb, 0, sizeof(*iocb)); |
232 | iocb->aio_fildes = fd; |
233 | iocb->aio_lio_opcode = IO_CMD_FSYNC; |
234 | iocb->aio_reqprio = 0; |
235 | } |
236 | |
237 | static inline int io_fsync(io_context_t ctx, struct iocb *iocb, io_callback_t cb, int fd) |
238 | { |
239 | io_prep_fsync(iocb, fd); |
240 | io_set_callback(iocb, cb); |
241 | return io_submit(ctx, 1, &iocb); |
242 | } |
243 | |
244 | static inline void io_prep_fdsync(struct iocb *iocb, int fd) |
245 | { |
246 | memset(iocb, 0, sizeof(*iocb)); |
247 | iocb->aio_fildes = fd; |
248 | iocb->aio_lio_opcode = IO_CMD_FDSYNC; |
249 | iocb->aio_reqprio = 0; |
250 | } |
251 | |
252 | static inline int io_fdsync(io_context_t ctx, struct iocb *iocb, io_callback_t cb, int fd) |
253 | { |
254 | io_prep_fdsync(iocb, fd); |
255 | io_set_callback(iocb, cb); |
256 | return io_submit(ctx, 1, &iocb); |
257 | } |
258 | |
259 | static inline void io_set_eventfd(struct iocb *iocb, int eventfd) |
260 | { |
261 | iocb->u.c.flags |= (1 << 0) /* IOCB_FLAG_RESFD */; |
262 | iocb->u.c.resfd = eventfd; |
263 | } |
264 | |
265 | #ifdef __cplusplus |
266 | } |
267 | #endif |
268 | |
269 | #endif /* __LIBAIO_H */ |
270 | |