1/**
2 * D header file for the io_uring interface.
3 * Available since Linux 5.1
4 *
5 * Copyright: Copyright Jens Axboe 2019,
6 *            Copyright Christoph Hellwig 2019.
7 * License : $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)
8 * Authors : Lu��s Ferreira
9 */
10module core.sys.linux.io_uring;
11
12version (linux):
13
14import core.sys.linux.fs : __kernel_rwf_t;
15
16extern (C):
17@system:
18@nogc:
19nothrow:
20@system:
21
22/**
23 * IO submission data structure (Submission Queue Entry)
24 */
25struct io_uring_sqe
26{
27    /// type of operation for this sqe
28    ubyte opcode;
29    /// IOSQE_* flags
30    ubyte flags;
31    /// ioprio for the request
32    ushort ioprio;
33    /// file descriptor to do IO on
34    int fd;
35    union
36    {
37        /// offset into file
38        ulong off;
39        ulong addr2;
40    }
41
42    union
43    {
44        /// pointer to buffer or iovecs
45        ulong addr;
46        ulong splice_off_in;
47    }
48
49    /// buffer size or number of iovecs
50    uint len;
51    union
52    {
53        __kernel_rwf_t rw_flags;
54        uint fsync_flags;
55
56        /// compatibility
57        ushort poll_events;
58        /// word-reversed for BE
59        uint poll32_events;
60
61        uint sync_range_flags;
62        uint msg_flags;
63        uint timeout_flags;
64        uint accept_flags;
65        uint cancel_flags;
66        uint open_flags;
67        uint statx_flags;
68        uint fadvise_advice;
69        uint splice_flags;
70        uint rename_flags;
71        uint unlink_flags;
72    }
73
74    /// data to be passed back at completion time
75    ulong user_data;
76    union
77    {
78        struct
79        {
80            /**
81             * pack this to avoid bogus arm OABI complaints
82             */
83            union
84            {
85                align (1):
86
87                /// index into fixed buffers, if used
88                ushort buf_index;
89                /// for grouped buffer selection
90                ushort buf_group;
91            }
92
93            /// personality to use, if used
94            ushort personality;
95            int splice_fd_in;
96        }
97
98        ulong[3] __pad2;
99    }
100}
101
102enum
103{
104    IOSQE_FIXED_FILE_BIT = 0,
105    IOSQE_IO_DRAIN_BIT = 1,
106    IOSQE_IO_LINK_BIT = 2,
107    IOSQE_IO_HARDLINK_BIT = 3,
108    IOSQE_ASYNC_BIT = 4,
109    IOSQE_BUFFER_SELECT_BIT = 5
110}
111
112enum
113{
114    /// use fixed fileset
115    IOSQE_FIXED_FILE = 1U << IOSQE_FIXED_FILE_BIT,
116    /// issue after inflight IO
117    IOSQE_IO_DRAIN = 1U << IOSQE_IO_DRAIN_BIT,
118    /// links next sqe
119    IOSQE_IO_LINK = 1U << IOSQE_IO_LINK_BIT,
120    /// like LINK, but stronger
121    IOSQE_IO_HARDLINK = 1U << IOSQE_IO_HARDLINK_BIT,
122    /// always go async
123    IOSQE_ASYNC = 1U << IOSQE_ASYNC_BIT,
124    /// select buffer from sqe.buf_group
125    IOSQE_BUFFER_SELECT = 1U << IOSQE_BUFFER_SELECT_BIT,
126}
127
128/**
129 * io_uring_setup() flags
130 */
131enum
132{
133    /// io_context is polled
134    IORING_SETUP_IOPOLL = 1U << 0,
135    /// SQ poll thread
136    IORING_SETUP_SQPOLL = 1U << 1,
137    /// sq_thread_cpu is valid
138    IORING_SETUP_SQ_AFF = 1U << 2,
139    /// app defines CQ size
140    IORING_SETUP_CQSIZE = 1U << 3,
141    /// clamp SQ/CQ ring sizes
142    IORING_SETUP_CLAMP = 1U << 4,
143    /// attach to existing wq
144    IORING_SETUP_ATTACH_WQ = 1U << 5,
145    /// start with ring disabled
146    IORING_SETUP_R_DISABLED = 1U << 6,
147}
148
149enum
150{
151    IORING_OP_NOP = 0,
152    IORING_OP_READV = 1,
153    IORING_OP_WRITEV = 2,
154    IORING_OP_FSYNC = 3,
155    IORING_OP_READ_FIXED = 4,
156    IORING_OP_WRITE_FIXED = 5,
157    IORING_OP_POLL_ADD = 6,
158    IORING_OP_POLL_REMOVE = 7,
159    IORING_OP_SYNC_FILE_RANGE = 8,
160    IORING_OP_SENDMSG = 9,
161    IORING_OP_RECVMSG = 10,
162    IORING_OP_TIMEOUT = 11,
163    IORING_OP_TIMEOUT_REMOVE = 12,
164    IORING_OP_ACCEPT = 13,
165    IORING_OP_ASYNC_CANCEL = 14,
166    IORING_OP_LINK_TIMEOUT = 15,
167    IORING_OP_CONNECT = 16,
168    IORING_OP_FALLOCATE = 17,
169    IORING_OP_OPENAT = 18,
170    IORING_OP_CLOSE = 19,
171    IORING_OP_FILES_UPDATE = 20,
172    IORING_OP_STATX = 21,
173    IORING_OP_READ = 22,
174    IORING_OP_WRITE = 23,
175    IORING_OP_FADVISE = 24,
176    IORING_OP_MADVISE = 25,
177    IORING_OP_SEND = 26,
178    IORING_OP_RECV = 27,
179    IORING_OP_OPENAT2 = 28,
180    IORING_OP_EPOLL_CTL = 29,
181    IORING_OP_SPLICE = 30,
182    IORING_OP_PROVIDE_BUFFERS = 31,
183    IORING_OP_REMOVE_BUFFERS = 32,
184    IORING_OP_TEE = 33,
185    IORING_OP_SHUTDOWN = 34,
186    IORING_OP_RENAMEAT = 35,
187    IORING_OP_UNLINKAT = 36,
188
189    IORING_OP_LAST = 37
190}
191
192enum
193{
194    IORING_FSYNC_DATASYNC = 1U << 0,
195}
196
197enum
198{
199    IORING_TIMEOUT_ABS = 1U << 0,
200    IORING_TIMEOUT_UPDATE = 1U << 1,
201}
202
203enum SPLICE_F_FD_IN_FIXED = 1U << 31;
204
205/**
206 * IO completion data structure (Completion Queue Entry)
207 */
208struct io_uring_cqe
209{
210    /// submission passed back
211    ulong user_data;
212    /// result code for this event
213    int res;
214
215    uint flags;
216}
217
218/**
219 * If set, the upper 16 bits are the buffer ID
220 */
221enum IORING_CQE_F_BUFFER = 1U << 0;
222
223enum
224{
225    IORING_CQE_BUFFER_SHIFT = 16,
226}
227
228/**
229 * Magic offsets for the application to mmap the data it needs
230 */
231enum
232{
233    IORING_OFF_SQ_RING = 0UL,
234    IORING_OFF_CQ_RING = 0x8000000UL,
235    IORING_OFF_SQES = 0x10000000UL,
236}
237
238/**
239 * Filled with the offset for mmap(2)
240 */
241struct io_sqring_offsets
242{
243    uint head;
244    uint tail;
245    uint ring_mask;
246    uint ring_entries;
247    uint flags;
248    uint dropped;
249    uint array;
250    uint resv1;
251    ulong resv2;
252}
253
254enum
255{
256    /// needs io_uring_enter wakeup
257    IORING_SQ_NEED_WAKEUP = 1U << 0,
258    /// CQ ring is overflown
259    IORING_SQ_CQ_OVERFLOW = 1U << 1,
260}
261
262struct io_cqring_offsets
263{
264    uint head;
265    uint tail;
266    uint ring_mask;
267    uint ring_entries;
268    uint overflow;
269    uint cqes;
270    uint flags;
271    uint resv1;
272    ulong resv2;
273}
274
275enum
276{
277    /// disable eventfd notifications
278    IORING_CQ_EVENTFD_DISABLED = 1U << 0,
279}
280
281/**
282 * io_uring_enter(2) flags
283 */
284enum
285{
286    IORING_ENTER_GETEVENTS = 1U << 0,
287    IORING_ENTER_SQ_WAKEUP = 1U << 1,
288    IORING_ENTER_SQ_WAIT = 1U << 2,
289    IORING_ENTER_EXT_ARG = 1U << 3,
290}
291
292/**
293 * Passed in for io_uring_setup(2)
294 */
295struct io_uring_params
296{
297    uint sq_entries;
298    uint cq_entries;
299    uint flags;
300    uint sq_thread_cpu;
301    uint sq_thread_idle;
302    uint features;
303    uint wq_fd;
304    uint[3] resv;
305    io_sqring_offsets sq_off;
306    io_cqring_offsets cq_off;
307}
308
309enum
310{
311    IORING_FEAT_SINGLE_MMAP = 1U << 0,
312    IORING_FEAT_NODROP = 1U << 1,
313    IORING_FEAT_SUBMIT_STABLE = 1U << 2,
314    IORING_FEAT_RW_CUR_POS = 1U << 3,
315    IORING_FEAT_CUR_PERSONALITY = 1U << 4,
316    IORING_FEAT_FAST_POLL = 1U << 5,
317    IORING_FEAT_POLL_32BITS = 1U << 6,
318    IORING_FEAT_SQPOLL_NONFIXED = 1U << 7,
319    IORING_FEAT_EXT_ARG = 1U << 8,
320}
321
322/**
323 * io_uring_register(2) opcodes and arguments
324 */
325enum
326{
327    IORING_REGISTER_BUFFERS = 0,
328    IORING_UNREGISTER_BUFFERS = 1,
329    IORING_REGISTER_FILES = 2,
330    IORING_UNREGISTER_FILES = 3,
331    IORING_REGISTER_EVENTFD = 4,
332    IORING_UNREGISTER_EVENTFD = 5,
333    IORING_REGISTER_FILES_UPDATE = 6,
334    IORING_REGISTER_EVENTFD_ASYNC = 7,
335    IORING_REGISTER_PROBE = 8,
336    IORING_REGISTER_PERSONALITY = 9,
337    IORING_UNREGISTER_PERSONALITY = 10,
338    IORING_REGISTER_RESTRICTIONS = 11,
339    IORING_REGISTER_ENABLE_RINGS = 12,
340
341    IORING_REGISTER_LAST = 13
342}
343
344struct io_uring_files_update
345{
346    uint offset;
347    uint resv;
348    ulong fds;
349}
350
351enum IO_URING_OP_SUPPORTED = 1U << 0;
352
353struct io_uring_probe_op
354{
355    ubyte op;
356    ubyte resv;
357
358    /// IO_URING_OP_* flags
359    ushort flags;
360    uint resv2;
361}
362
363struct io_uring_probe
364{
365    /// last opcode supported
366    ubyte last_op;
367
368    /// length of ops[] array below
369    ubyte ops_len;
370
371    ushort resv;
372    uint[3] resv2;
373    io_uring_probe_op[0] ops;
374}
375
376struct io_uring_restriction
377{
378    ushort opcode;
379
380    union
381    {
382        ubyte register_op;
383        ubyte sqe_op;
384        ubyte sqe_flags;
385    }
386
387    ubyte resv;
388    uint[3] resv2;
389}
390
391enum
392{
393    /// Allow an io_uring_register(2) opcode
394    IORING_RESTRICTION_REGISTER_OP = 0,
395
396    /// Allow an sqe opcode
397    IORING_RESTRICTION_SQE_OP = 1,
398
399    /// Allow sqe flags
400    IORING_RESTRICTION_SQE_FLAGS_ALLOWED = 2,
401
402    /// Require sqe flags (these flags must be set on each submission)
403    IORING_RESTRICTION_SQE_FLAGS_REQUIRED = 3,
404
405    IORING_RESTRICTION_LAST = 4
406}
407
408struct io_uring_getevents_arg
409{
410    ulong sigmask;
411    uint sigmask_sz;
412    uint pad;
413    ulong ts;
414}
415