2bc24e089ecf34c63d24618caa50a317e8b2cb4d
[platform/upstream/libaio.git] / src / libaio.h
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 #include <signal.h>
33
34 struct timespec;
35 struct sockaddr;
36 struct iovec;
37
38 typedef struct io_context *io_context_t;
39
40 typedef enum io_iocb_cmd {
41         IO_CMD_PREAD = 0,
42         IO_CMD_PWRITE = 1,
43
44         IO_CMD_FSYNC = 2,
45         IO_CMD_FDSYNC = 3,
46
47         IO_CMD_POLL = 5,
48         IO_CMD_NOOP = 6,
49         IO_CMD_PREADV = 7,
50         IO_CMD_PWRITEV = 8,
51 } io_iocb_cmd_t;
52
53 /* little endian, 32 bits */
54 #if defined(__i386__) || (defined(__arm__) && !defined(__ARMEB__)) || \
55     defined(__sh__) || defined(__bfin__) || defined(__MIPSEL__) || \
56     defined(__cris__) || (defined(__riscv) && __riscv_xlen == 32) || \
57     (defined(__GNUC__) && defined(__BYTE_ORDER__) && \
58          __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ && __SIZEOF_LONG__ == 4)
59 #define PADDED(x, y)    x; unsigned y
60 #define PADDEDptr(x, y) x; unsigned y
61 #define PADDEDul(x, y)  unsigned long x; unsigned y
62
63 /* little endian, 64 bits */
64 #elif defined(__ia64__) || defined(__x86_64__) || defined(__alpha__) || \
65       (defined(__aarch64__) && defined(__AARCH64EL__)) || \
66       (defined(__riscv) && __riscv_xlen == 64) || \
67       (defined(__GNUC__) && defined(__BYTE_ORDER__) && \
68           __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ && __SIZEOF_LONG__ == 8)
69 #define PADDED(x, y)    x, y
70 #define PADDEDptr(x, y) x
71 #define PADDEDul(x, y)  unsigned long x
72
73 /* big endian, 64 bits */
74 #elif defined(__powerpc64__) || defined(__s390x__) || \
75       (defined(__sparc__) && defined(__arch64__)) || \
76       (defined(__aarch64__) && defined(__AARCH64EB__)) || \
77       (defined(__GNUC__) && defined(__BYTE_ORDER__) && \
78            __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ && __SIZEOF_LONG__ == 8)
79 #define PADDED(x, y)    unsigned y; x
80 #define PADDEDptr(x,y)  x
81 #define PADDEDul(x, y)  unsigned long x
82
83 /* big endian, 32 bits */
84 #elif defined(__PPC__) || defined(__s390__) || \
85       (defined(__arm__) && defined(__ARMEB__)) || \
86       defined(__sparc__) || defined(__MIPSEB__) || defined(__m68k__) || \
87       defined(__hppa__) || defined(__frv__) || defined(__avr32__) || \
88       (defined(__GNUC__) && defined(__BYTE_ORDER__) && \
89            __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ && __SIZEOF_LONG__ == 4)
90 #define PADDED(x, y)    unsigned y; x
91 #define PADDEDptr(x, y) unsigned y; x
92 #define PADDEDul(x, y)  unsigned y; unsigned long x
93
94 #else
95 #error  endian?
96 #endif
97
98 struct io_iocb_poll {
99         PADDED(int events, __pad1);
100 };      /* result code is the set of result flags or -'ve errno */
101
102 struct io_iocb_sockaddr {
103         struct sockaddr *addr;
104         int             len;
105 };      /* result code is the length of the sockaddr, or -'ve errno */
106
107 struct io_iocb_common {
108         PADDEDptr(void  *buf, __pad1);
109         PADDEDul(nbytes, __pad2);
110         long long       offset;
111         long long       __pad3;
112         unsigned        flags;
113         unsigned        resfd;
114 };      /* result code is the amount read or -'ve errno */
115
116 struct io_iocb_vector {
117         const struct iovec      *vec;
118         int                     nr;
119         long long               offset;
120 };      /* result code is the amount read or -'ve errno */
121
122 struct iocb {
123         PADDEDptr(void *data, __pad1);  /* Return in the io completion event */
124         /* key: For use in identifying io requests */
125         /* aio_rw_flags: RWF_* flags (such as RWF_NOWAIT) */
126         PADDED(unsigned key, aio_rw_flags);
127
128         short           aio_lio_opcode; 
129         short           aio_reqprio;
130         int             aio_fildes;
131
132         union {
133                 struct io_iocb_common           c;
134                 struct io_iocb_vector           v;
135                 struct io_iocb_poll             poll;
136                 struct io_iocb_sockaddr saddr;
137         } u;
138 };
139
140 struct io_event {
141         PADDEDptr(void *data, __pad1);
142         PADDEDptr(struct iocb *obj,  __pad2);
143         PADDEDul(res,  __pad3);
144         PADDEDul(res2, __pad4);
145 };
146
147 #undef PADDED
148 #undef PADDEDptr
149 #undef PADDEDul
150
151 typedef void (*io_callback_t)(io_context_t ctx, struct iocb *iocb, long res, long res2);
152
153 /* library wrappers */
154 extern int io_queue_init(int maxevents, io_context_t *ctxp);
155 /*extern int io_queue_grow(io_context_t ctx, int new_maxevents);*/
156 extern int io_queue_release(io_context_t ctx);
157 /*extern int io_queue_wait(io_context_t ctx, struct timespec *timeout);*/
158 extern int io_queue_run(io_context_t ctx);
159
160 /* Actual syscalls */
161 extern int io_setup(int maxevents, io_context_t *ctxp);
162 extern int io_destroy(io_context_t ctx);
163 extern int io_submit(io_context_t ctx, long nr, struct iocb *ios[]);
164 extern int io_cancel(io_context_t ctx, struct iocb *iocb, struct io_event *evt);
165 extern int io_getevents(io_context_t ctx_id, long min_nr, long nr, struct io_event *events, struct timespec *timeout);
166 extern int io_pgetevents(io_context_t ctx_id, long min_nr, long nr,
167                 struct io_event *events, struct timespec *timeout,
168                 sigset_t *sigmask);
169
170
171 static inline void io_set_callback(struct iocb *iocb, io_callback_t cb)
172 {
173         iocb->data = (void *)cb;
174 }
175
176 static inline void io_prep_pread(struct iocb *iocb, int fd, void *buf, size_t count, long long offset)
177 {
178         memset(iocb, 0, sizeof(*iocb));
179         iocb->aio_fildes = fd;
180         iocb->aio_lio_opcode = IO_CMD_PREAD;
181         iocb->aio_reqprio = 0;
182         iocb->u.c.buf = buf;
183         iocb->u.c.nbytes = count;
184         iocb->u.c.offset = offset;
185 }
186
187 static inline void io_prep_pwrite(struct iocb *iocb, int fd, void *buf, size_t count, long long offset)
188 {
189         memset(iocb, 0, sizeof(*iocb));
190         iocb->aio_fildes = fd;
191         iocb->aio_lio_opcode = IO_CMD_PWRITE;
192         iocb->aio_reqprio = 0;
193         iocb->u.c.buf = buf;
194         iocb->u.c.nbytes = count;
195         iocb->u.c.offset = offset;
196 }
197
198 static inline void io_prep_preadv(struct iocb *iocb, int fd, const struct iovec *iov, int iovcnt, long long offset)
199 {
200         memset(iocb, 0, sizeof(*iocb));
201         iocb->aio_fildes = fd;
202         iocb->aio_lio_opcode = IO_CMD_PREADV;
203         iocb->aio_reqprio = 0;
204         iocb->u.c.buf = (void *)iov;
205         iocb->u.c.nbytes = iovcnt;
206         iocb->u.c.offset = offset;
207 }
208
209 static inline void io_prep_pwritev(struct iocb *iocb, int fd, const struct iovec *iov, int iovcnt, long long offset)
210 {
211         memset(iocb, 0, sizeof(*iocb));
212         iocb->aio_fildes = fd;
213         iocb->aio_lio_opcode = IO_CMD_PWRITEV;
214         iocb->aio_reqprio = 0;
215         iocb->u.c.buf = (void *)iov;
216         iocb->u.c.nbytes = iovcnt;
217         iocb->u.c.offset = offset;
218 }
219
220 static inline void io_prep_preadv2(struct iocb *iocb, int fd, const struct iovec *iov, int iovcnt, long long offset, int flags)
221 {
222         memset(iocb, 0, sizeof(*iocb));
223         iocb->aio_fildes = fd;
224         iocb->aio_lio_opcode = IO_CMD_PREADV;
225         iocb->aio_reqprio = 0;
226         iocb->aio_rw_flags = flags;
227         iocb->u.c.buf = (void *)iov;
228         iocb->u.c.nbytes = iovcnt;
229         iocb->u.c.offset = offset;
230 }
231
232 static inline void io_prep_pwritev2(struct iocb *iocb, int fd, const struct iovec *iov, int iovcnt, long long offset, int flags)
233 {
234         memset(iocb, 0, sizeof(*iocb));
235         iocb->aio_fildes = fd;
236         iocb->aio_lio_opcode = IO_CMD_PWRITEV;
237         iocb->aio_reqprio = 0;
238         iocb->aio_rw_flags = flags;
239         iocb->u.c.buf = (void *)iov;
240         iocb->u.c.nbytes = iovcnt;
241         iocb->u.c.offset = offset;
242 }
243
244 static inline void io_prep_poll(struct iocb *iocb, int fd, int events)
245 {
246         memset(iocb, 0, sizeof(*iocb));
247         iocb->aio_fildes = fd;
248         iocb->aio_lio_opcode = IO_CMD_POLL;
249         iocb->aio_reqprio = 0;
250         iocb->u.poll.events = events;
251 }
252
253 static inline int io_poll(io_context_t ctx, struct iocb *iocb, io_callback_t cb, int fd, int events)
254 {
255         io_prep_poll(iocb, fd, events);
256         io_set_callback(iocb, cb);
257         return io_submit(ctx, 1, &iocb);
258 }
259
260 static inline void io_prep_fsync(struct iocb *iocb, int fd)
261 {
262         memset(iocb, 0, sizeof(*iocb));
263         iocb->aio_fildes = fd;
264         iocb->aio_lio_opcode = IO_CMD_FSYNC;
265         iocb->aio_reqprio = 0;
266 }
267
268 static inline int io_fsync(io_context_t ctx, struct iocb *iocb, io_callback_t cb, int fd)
269 {
270         io_prep_fsync(iocb, fd);
271         io_set_callback(iocb, cb);
272         return io_submit(ctx, 1, &iocb);
273 }
274
275 static inline void io_prep_fdsync(struct iocb *iocb, int fd)
276 {
277         memset(iocb, 0, sizeof(*iocb));
278         iocb->aio_fildes = fd;
279         iocb->aio_lio_opcode = IO_CMD_FDSYNC;
280         iocb->aio_reqprio = 0;
281 }
282
283 static inline int io_fdsync(io_context_t ctx, struct iocb *iocb, io_callback_t cb, int fd)
284 {
285         io_prep_fdsync(iocb, fd);
286         io_set_callback(iocb, cb);
287         return io_submit(ctx, 1, &iocb);
288 }
289
290 static inline void io_set_eventfd(struct iocb *iocb, int eventfd)
291 {
292         iocb->u.c.flags |= (1 << 0) /* IOCB_FLAG_RESFD */;
293         iocb->u.c.resfd = eventfd;
294 }
295
296 #ifdef __cplusplus
297 }
298 #endif
299
300 #endif /* __LIBAIO_H */