1 //! Linux [io_uring].
2 //!
3 //! This API is very low-level. The main adaptations it makes from the raw
4 //! Linux io_uring API are the use of appropriately-sized `bitflags`, `enum`,
5 //! `Result`, `OwnedFd`, `AsFd`, `RawFd`, and `*mut c_void` in place of plain
6 //! integers.
7 //!
8 //! For a higher-level API built on top of this, see the [rustix-uring] crate.
9 //!
10 //! # Safety
11 //!
12 //! io_uring operates on raw pointers and raw file descriptors. Rustix does not
13 //! attempt to provide a safe API for these, because the abstraction level is
14 //! too low for this to be practical. Safety should be introduced in
15 //! higher-level abstraction layers.
16 //!
17 //! # References
18 //! - [Linux]
19 //! - [io_uring header]
20 //!
21 //! [Linux]: https://man.archlinux.org/man/io_uring.7.en
22 //! [io_uring]: https://en.wikipedia.org/wiki/Io_uring
23 //! [io_uring header]: https://github.com/torvalds/linux/blob/master/include/uapi/linux/io_uring.h
24 //! [rustix-uring]: https://crates.io/crates/rustix-uring
25 #![allow(unsafe_code)]
26
27 use crate::fd::{AsFd, BorrowedFd, OwnedFd, RawFd};
28 use crate::{backend, io};
29 use core::ffi::c_void;
30 use core::mem::MaybeUninit;
31 use core::ptr::{null_mut, write_bytes};
32 use linux_raw_sys::net;
33
34 // Export types used in io_uring APIs.
35 pub use crate::event::epoll::{
36 Event as EpollEvent, EventData as EpollEventData, EventFlags as EpollEventFlags,
37 };
38 pub use crate::fs::{Advice, AtFlags, Mode, OFlags, RenameFlags, ResolveFlags, Statx, StatxFlags};
39 pub use crate::io::ReadWriteFlags;
40 pub use crate::net::{RecvFlags, SendFlags, SocketFlags};
41 pub use crate::timespec::Timespec;
42 pub use linux_raw_sys::general::sigset_t;
43
44 pub use net::{__kernel_sockaddr_storage as sockaddr_storage, msghdr, sockaddr, socklen_t};
45
46 // Declare the `c_char` type for use with entries that take pointers
47 // to C strings. Define it as unsigned or signed according to the platform
48 // so that we match what Rust's `CStr` uses.
49 //
50 // When we can update to linux-raw-sys 0.5, we can remove this, as its
51 // `c_char` type will declare this.
52 /// The C `char` type.
53 #[cfg(any(
54 target_arch = "aarch64",
55 target_arch = "arm",
56 target_arch = "msp430",
57 target_arch = "powerpc",
58 target_arch = "powerpc64",
59 target_arch = "riscv32",
60 target_arch = "riscv64",
61 target_arch = "s390x",
62 ))]
63 #[allow(non_camel_case_types)]
64 pub type c_char = u8;
65 /// The C `char` type.
66 #[cfg(any(
67 target_arch = "mips",
68 target_arch = "mips64",
69 target_arch = "sparc64",
70 target_arch = "x86",
71 target_arch = "x86_64",
72 target_arch = "xtensa",
73 ))]
74 #[allow(non_camel_case_types)]
75 pub type c_char = i8;
76
77 mod sys {
78 pub(super) use linux_raw_sys::io_uring::*;
79 #[cfg(test)]
80 pub(super) use {crate::backend::c::iovec, linux_raw_sys::general::open_how};
81 }
82
83 /// `io_uring_setup(entries, params)`—Setup a context for performing
84 /// asynchronous I/O.
85 ///
86 /// # References
87 /// - [Linux]
88 ///
89 /// [Linux]: https://man.archlinux.org/man/io_uring_setup.2.en
90 #[inline]
io_uring_setup(entries: u32, params: &mut io_uring_params) -> io::Result<OwnedFd>91 pub fn io_uring_setup(entries: u32, params: &mut io_uring_params) -> io::Result<OwnedFd> {
92 backend::io_uring::syscalls::io_uring_setup(entries, params)
93 }
94
95 /// `io_uring_register(fd, opcode, arg, nr_args)`—Register files or user
96 /// buffers for asynchronous I/O.
97 ///
98 /// # Safety
99 ///
100 /// io_uring operates on raw pointers and raw file descriptors. Users are
101 /// responsible for ensuring that memory and resources are only accessed in
102 /// valid ways.
103 ///
104 /// # References
105 /// - [Linux]
106 ///
107 /// [Linux]: https://man.archlinux.org/man/io_uring_register.2.en
108 #[inline]
io_uring_register<Fd: AsFd>( fd: Fd, opcode: IoringRegisterOp, arg: *const c_void, nr_args: u32, ) -> io::Result<u32>109 pub unsafe fn io_uring_register<Fd: AsFd>(
110 fd: Fd,
111 opcode: IoringRegisterOp,
112 arg: *const c_void,
113 nr_args: u32,
114 ) -> io::Result<u32> {
115 backend::io_uring::syscalls::io_uring_register(fd.as_fd(), opcode, arg, nr_args)
116 }
117
118 /// `io_uring_enter(fd, to_submit, min_complete, flags, arg, size)`—Initiate
119 /// and/or complete asynchronous I/O.
120 ///
121 /// # Safety
122 ///
123 /// io_uring operates on raw pointers and raw file descriptors. Users are
124 /// responsible for ensuring that memory and resources are only accessed in
125 /// valid ways.
126 ///
127 /// # References
128 /// - [Linux]
129 ///
130 /// [Linux]: https://man.archlinux.org/man/io_uring_enter.2.en
131 #[inline]
io_uring_enter<Fd: AsFd>( fd: Fd, to_submit: u32, min_complete: u32, flags: IoringEnterFlags, arg: *const c_void, size: usize, ) -> io::Result<u32>132 pub unsafe fn io_uring_enter<Fd: AsFd>(
133 fd: Fd,
134 to_submit: u32,
135 min_complete: u32,
136 flags: IoringEnterFlags,
137 arg: *const c_void,
138 size: usize,
139 ) -> io::Result<u32> {
140 backend::io_uring::syscalls::io_uring_enter(
141 fd.as_fd(),
142 to_submit,
143 min_complete,
144 flags,
145 arg,
146 size,
147 )
148 }
149
150 bitflags::bitflags! {
151 /// `IORING_ENTER_*` flags for use with [`io_uring_enter`].
152 #[repr(transparent)]
153 #[derive(Default, Copy, Clone, Eq, PartialEq, Hash, Debug)]
154 pub struct IoringEnterFlags: u32 {
155 /// `IORING_ENTER_GETEVENTS`
156 const GETEVENTS = sys::IORING_ENTER_GETEVENTS;
157
158 /// `IORING_ENTER_SQ_WAKEUP`
159 const SQ_WAKEUP = sys::IORING_ENTER_SQ_WAKEUP;
160
161 /// `IORING_ENTER_SQ_WAIT`
162 const SQ_WAIT = sys::IORING_ENTER_SQ_WAIT;
163
164 /// `IORING_ENTER_EXT_ARG`
165 const EXT_ARG = sys::IORING_ENTER_EXT_ARG;
166
167 /// `IORING_ENTER_REGISTERED_RING`
168 const REGISTERED_RING = sys::IORING_ENTER_REGISTERED_RING;
169
170 /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags>
171 const _ = !0;
172 }
173 }
174
175 /// `IORING_REGISTER_*` and `IORING_UNREGISTER_*` constants for use with
176 /// [`io_uring_register`].
177 #[derive(Debug, Clone, Copy, Eq, PartialEq, Hash)]
178 #[repr(u8)]
179 #[non_exhaustive]
180 pub enum IoringRegisterOp {
181 /// `IORING_REGISTER_BUFFERS`
182 RegisterBuffers = sys::IORING_REGISTER_BUFFERS as _,
183
184 /// `IORING_UNREGISTER_BUFFERS`
185 UnregisterBuffers = sys::IORING_UNREGISTER_BUFFERS as _,
186
187 /// `IORING_REGISTER_FILES`
188 RegisterFiles = sys::IORING_REGISTER_FILES as _,
189
190 /// `IORING_UNREGISTER_FILES`
191 UnregisterFiles = sys::IORING_UNREGISTER_FILES as _,
192
193 /// `IORING_REGISTER_EVENTFD`
194 RegisterEventfd = sys::IORING_REGISTER_EVENTFD as _,
195
196 /// `IORING_UNREGISTER_EVENTFD`
197 UnregisterEventfd = sys::IORING_UNREGISTER_EVENTFD as _,
198
199 /// `IORING_REGISTER_FILES_UPDATE`
200 RegisterFilesUpdate = sys::IORING_REGISTER_FILES_UPDATE as _,
201
202 /// `IORING_REGISTER_EVENTFD_ASYNC`
203 RegisterEventfdAsync = sys::IORING_REGISTER_EVENTFD_ASYNC as _,
204
205 /// `IORING_REGISTER_PROBE`
206 RegisterProbe = sys::IORING_REGISTER_PROBE as _,
207
208 /// `IORING_REGISTER_PERSONALITY`
209 RegisterPersonality = sys::IORING_REGISTER_PERSONALITY as _,
210
211 /// `IORING_UNREGISTER_PERSONALITY`
212 UnregisterPersonality = sys::IORING_UNREGISTER_PERSONALITY as _,
213
214 /// `IORING_REGISTER_RESTRICTIONS`
215 RegisterRestrictions = sys::IORING_REGISTER_RESTRICTIONS as _,
216
217 /// `IORING_REGISTER_ENABLE_RINGS`
218 RegisterEnableRings = sys::IORING_REGISTER_ENABLE_RINGS as _,
219
220 /// `IORING_REGISTER_BUFFERS2`
221 RegisterBuffers2 = sys::IORING_REGISTER_BUFFERS2 as _,
222
223 /// `IORING_REGISTER_BUFFERS_UPDATE`
224 RegisterBuffersUpdate = sys::IORING_REGISTER_BUFFERS_UPDATE as _,
225
226 /// `IORING_REGISTER_FILES2`
227 RegisterFiles2 = sys::IORING_REGISTER_FILES2 as _,
228
229 /// `IORING_REGISTER_FILES_SKIP`
230 RegisterFilesSkip = sys::IORING_REGISTER_FILES_SKIP as _,
231
232 /// `IORING_REGISTER_FILES_UPDATE2`
233 RegisterFilesUpdate2 = sys::IORING_REGISTER_FILES_UPDATE2 as _,
234
235 /// `IORING_REGISTER_IOWQ_AFF`
236 RegisterIowqAff = sys::IORING_REGISTER_IOWQ_AFF as _,
237
238 /// `IORING_UNREGISTER_IOWQ_AFF`
239 UnregisterIowqAff = sys::IORING_UNREGISTER_IOWQ_AFF as _,
240
241 /// `IORING_REGISTER_IOWQ_MAX_WORKERS`
242 RegisterIowqMaxWorkers = sys::IORING_REGISTER_IOWQ_MAX_WORKERS as _,
243
244 /// `IORING_REGISTER_RING_FDS`
245 RegisterRingFds = sys::IORING_REGISTER_RING_FDS as _,
246
247 /// `IORING_UNREGISTER_RING_FDS`
248 UnregisterRingFds = sys::IORING_UNREGISTER_RING_FDS as _,
249
250 /// `IORING_REGISTER_PBUF_RING`
251 RegisterPbufRing = sys::IORING_REGISTER_PBUF_RING as _,
252
253 /// `IORING_UNREGISTER_PBUF_RING`
254 UnregisterPbufRing = sys::IORING_UNREGISTER_PBUF_RING as _,
255
256 /// `IORING_REGISTER_SYNC_CANCEL`
257 RegisterSyncCancel = sys::IORING_REGISTER_SYNC_CANCEL as _,
258
259 /// `IORING_REGISTER_FILE_ALLOC_RANGE`
260 RegisterFileAllocRange = sys::IORING_REGISTER_FILE_ALLOC_RANGE as _,
261 }
262
263 /// `IORING_OP_*` constants for use with [`io_uring_sqe`].
264 #[derive(Debug, Clone, Copy, Eq, PartialEq, Hash)]
265 #[repr(u8)]
266 #[non_exhaustive]
267 pub enum IoringOp {
268 /// `IORING_OP_NOP`
269 Nop = sys::io_uring_op::IORING_OP_NOP as _,
270
271 /// `IORING_OP_ACCEPT`
272 Accept = sys::io_uring_op::IORING_OP_ACCEPT as _,
273
274 /// `IORING_OP_ASYNC_CANCEL`
275 AsyncCancel = sys::io_uring_op::IORING_OP_ASYNC_CANCEL as _,
276
277 /// `IORING_OP_CLOSE`
278 Close = sys::io_uring_op::IORING_OP_CLOSE as _,
279
280 /// `IORING_OP_CONNECT`
281 Connect = sys::io_uring_op::IORING_OP_CONNECT as _,
282
283 /// `IORING_OP_EPOLL_CTL`
284 EpollCtl = sys::io_uring_op::IORING_OP_EPOLL_CTL as _,
285
286 /// `IORING_OP_FADVISE`
287 Fadvise = sys::io_uring_op::IORING_OP_FADVISE as _,
288
289 /// `IORING_OP_FALLOCATE`
290 Fallocate = sys::io_uring_op::IORING_OP_FALLOCATE as _,
291
292 /// `IORING_OP_FILES_UPDATE`
293 FilesUpdate = sys::io_uring_op::IORING_OP_FILES_UPDATE as _,
294
295 /// `IORING_OP_FSYNC`
296 Fsync = sys::io_uring_op::IORING_OP_FSYNC as _,
297
298 /// `IORING_OP_LINKAT`
299 Linkat = sys::io_uring_op::IORING_OP_LINKAT as _,
300
301 /// `IORING_OP_LINK_TIMEOUT`
302 LinkTimeout = sys::io_uring_op::IORING_OP_LINK_TIMEOUT as _,
303
304 /// `IORING_OP_MADVISE`
305 Madvise = sys::io_uring_op::IORING_OP_MADVISE as _,
306
307 /// `IORING_OP_MKDIRAT`
308 Mkdirat = sys::io_uring_op::IORING_OP_MKDIRAT as _,
309
310 /// `IORING_OP_OPENAT`
311 Openat = sys::io_uring_op::IORING_OP_OPENAT as _,
312
313 /// `IORING_OP_OPENAT2`
314 Openat2 = sys::io_uring_op::IORING_OP_OPENAT2 as _,
315
316 /// `IORING_OP_POLL_ADD`
317 PollAdd = sys::io_uring_op::IORING_OP_POLL_ADD as _,
318
319 /// `IORING_OP_POLL_REMOVE`
320 PollRemove = sys::io_uring_op::IORING_OP_POLL_REMOVE as _,
321
322 /// `IORING_OP_PROVIDE_BUFFERS`
323 ProvideBuffers = sys::io_uring_op::IORING_OP_PROVIDE_BUFFERS as _,
324
325 /// `IORING_OP_READ`
326 Read = sys::io_uring_op::IORING_OP_READ as _,
327
328 /// `IORING_OP_READV`
329 Readv = sys::io_uring_op::IORING_OP_READV as _,
330
331 /// `IORING_OP_READ_FIXED`
332 ReadFixed = sys::io_uring_op::IORING_OP_READ_FIXED as _,
333
334 /// `IORING_OP_RECV`
335 Recv = sys::io_uring_op::IORING_OP_RECV as _,
336
337 /// `IORING_OP_RECVMSG`
338 Recvmsg = sys::io_uring_op::IORING_OP_RECVMSG as _,
339
340 /// `IORING_OP_REMOVE_BUFFERS`
341 RemoveBuffers = sys::io_uring_op::IORING_OP_REMOVE_BUFFERS as _,
342
343 /// `IORING_OP_RENAMEAT`
344 Renameat = sys::io_uring_op::IORING_OP_RENAMEAT as _,
345
346 /// `IORING_OP_SEND`
347 Send = sys::io_uring_op::IORING_OP_SEND as _,
348
349 /// `IORING_OP_SENDMSG`
350 Sendmsg = sys::io_uring_op::IORING_OP_SENDMSG as _,
351
352 /// `IORING_OP_SHUTDOWN`
353 Shutdown = sys::io_uring_op::IORING_OP_SHUTDOWN as _,
354
355 /// `IORING_OP_SPLICE`
356 Splice = sys::io_uring_op::IORING_OP_SPLICE as _,
357
358 /// `IORING_OP_STATX`
359 Statx = sys::io_uring_op::IORING_OP_STATX as _,
360
361 /// `IORING_OP_SYMLINKAT`
362 Symlinkat = sys::io_uring_op::IORING_OP_SYMLINKAT as _,
363
364 /// `IORING_OP_SYNC_FILE_RANGE`
365 SyncFileRange = sys::io_uring_op::IORING_OP_SYNC_FILE_RANGE as _,
366
367 /// `IORING_OP_TEE`
368 Tee = sys::io_uring_op::IORING_OP_TEE as _,
369
370 /// `IORING_OP_TIMEOUT`
371 Timeout = sys::io_uring_op::IORING_OP_TIMEOUT as _,
372
373 /// `IORING_OP_TIMEOUT_REMOVE`
374 TimeoutRemove = sys::io_uring_op::IORING_OP_TIMEOUT_REMOVE as _,
375
376 /// `IORING_OP_UNLINKAT`
377 Unlinkat = sys::io_uring_op::IORING_OP_UNLINKAT as _,
378
379 /// `IORING_OP_WRITE`
380 Write = sys::io_uring_op::IORING_OP_WRITE as _,
381
382 /// `IORING_OP_WRITEV`
383 Writev = sys::io_uring_op::IORING_OP_WRITEV as _,
384
385 /// `IORING_OP_WRITE_FIXED`
386 WriteFixed = sys::io_uring_op::IORING_OP_WRITE_FIXED as _,
387
388 /// `IORING_OP_MSG_RING`
389 MsgRing = sys::io_uring_op::IORING_OP_MSG_RING as _,
390
391 /// `IORING_OP_FSETXATTR`
392 Fsetxattr = sys::io_uring_op::IORING_OP_FSETXATTR as _,
393
394 /// `IORING_OP_SETXATTR`
395 Setxattr = sys::io_uring_op::IORING_OP_SETXATTR as _,
396
397 /// `IORING_OP_FGETXATTR`
398 Fgetxattr = sys::io_uring_op::IORING_OP_FGETXATTR as _,
399
400 /// `IORING_OP_GETXATTR`
401 Getxattr = sys::io_uring_op::IORING_OP_GETXATTR as _,
402
403 /// `IORING_OP_SOCKET`
404 Socket = sys::io_uring_op::IORING_OP_SOCKET as _,
405
406 /// `IORING_OP_URING_CMD`
407 UringCmd = sys::io_uring_op::IORING_OP_URING_CMD as _,
408
409 /// `IORING_OP_SEND_ZC`
410 SendZc = sys::io_uring_op::IORING_OP_SEND_ZC as _,
411
412 /// `IORING_OP_SENDMSG_ZC`
413 SendmsgZc = sys::io_uring_op::IORING_OP_SENDMSG_ZC as _,
414 }
415
416 impl Default for IoringOp {
417 #[inline]
default() -> Self418 fn default() -> Self {
419 Self::Nop
420 }
421 }
422
423 /// `IORING_RESTRICTION_*` constants for use with [`io_uring_restriction`].
424 #[derive(Debug, Clone, Copy, Eq, PartialEq, Hash)]
425 #[repr(u16)]
426 #[non_exhaustive]
427 pub enum IoringRestrictionOp {
428 /// `IORING_RESTRICTION_REGISTER_OP`
429 RegisterOp = sys::IORING_RESTRICTION_REGISTER_OP as _,
430
431 /// `IORING_RESTRICTION_SQE_FLAGS_ALLOWED`
432 SqeFlagsAllowed = sys::IORING_RESTRICTION_SQE_FLAGS_ALLOWED as _,
433
434 /// `IORING_RESTRICTION_SQE_FLAGS_REQUIRED`
435 SqeFlagsRequired = sys::IORING_RESTRICTION_SQE_FLAGS_REQUIRED as _,
436
437 /// `IORING_RESTRICTION_SQE_OP`
438 SqeOp = sys::IORING_RESTRICTION_SQE_OP as _,
439 }
440
441 impl Default for IoringRestrictionOp {
442 #[inline]
default() -> Self443 fn default() -> Self {
444 Self::RegisterOp
445 }
446 }
447
448 /// `IORING_MSG_*` constants which represent commands for use with
449 /// [`IoringOp::MsgRing`], (`seq.addr`)
450 #[derive(Debug, Clone, Copy, Eq, PartialEq, Hash)]
451 #[repr(u64)]
452 #[non_exhaustive]
453 pub enum IoringMsgringCmds {
454 /// `IORING_MSG_DATA`
455 Data = sys::IORING_MSG_DATA as _,
456
457 /// `IORING_MSG_SEND_FD`
458 SendFd = sys::IORING_MSG_SEND_FD as _,
459 }
460
461 bitflags::bitflags! {
462 /// `IORING_SETUP_*` flags for use with [`io_uring_params`].
463 #[repr(transparent)]
464 #[derive(Default, Copy, Clone, Eq, PartialEq, Hash, Debug)]
465 pub struct IoringSetupFlags: u32 {
466 /// `IORING_SETUP_ATTACH_WQ`
467 const ATTACH_WQ = sys::IORING_SETUP_ATTACH_WQ;
468
469 /// `IORING_SETUP_CLAMP`
470 const CLAMP = sys::IORING_SETUP_CLAMP;
471
472 /// `IORING_SETUP_CQSIZE`
473 const CQSIZE = sys::IORING_SETUP_CQSIZE;
474
475 /// `IORING_SETUP_IOPOLL`
476 const IOPOLL = sys::IORING_SETUP_IOPOLL;
477
478 /// `IORING_SETUP_R_DISABLED`
479 const R_DISABLED = sys::IORING_SETUP_R_DISABLED;
480
481 /// `IORING_SETUP_SQPOLL`
482 const SQPOLL = sys::IORING_SETUP_SQPOLL;
483
484 /// `IORING_SETUP_SQ_AFF`
485 const SQ_AFF = sys::IORING_SETUP_SQ_AFF;
486
487 /// `IORING_SETUP_SQE128`
488 const SQE128 = sys::IORING_SETUP_SQE128;
489
490 /// `IORING_SETUP_CQE32`
491 const CQE32 = sys::IORING_SETUP_CQE32;
492
493 /// `IORING_SETUP_SUBMIT_ALL`
494 const SUBMIT_ALL = sys::IORING_SETUP_SUBMIT_ALL;
495
496 /// `IORING_SETUP_COOP_TRASKRUN`
497 const COOP_TASKRUN = sys::IORING_SETUP_COOP_TASKRUN;
498
499 /// `IORING_SETUP_TASKRUN_FLAG`
500 const TASKRUN_FLAG = sys::IORING_SETUP_TASKRUN_FLAG;
501
502 /// `IORING_SETUP_SINGLE_ISSUER`
503 const SINGLE_ISSUER = sys::IORING_SETUP_SINGLE_ISSUER;
504
505 /// `IORING_SETUP_DEFER_TASKRUN`
506 const DEFER_TASKRUN = sys::IORING_SETUP_DEFER_TASKRUN;
507
508 /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags>
509 const _ = !0;
510 }
511 }
512
513 bitflags::bitflags! {
514 /// `IOSQE_*` flags for use with [`io_uring_sqe`].
515 #[repr(transparent)]
516 #[derive(Default, Copy, Clone, Eq, PartialEq, Hash, Debug)]
517 pub struct IoringSqeFlags: u8 {
518 /// `1 << IOSQE_ASYNC_BIT`
519 const ASYNC = 1 << sys::IOSQE_ASYNC_BIT as u8;
520
521 /// `1 << IOSQE_BUFFER_SELECT_BIT`
522 const BUFFER_SELECT = 1 << sys::IOSQE_BUFFER_SELECT_BIT as u8;
523
524 /// `1 << IOSQE_FIXED_FILE_BIT`
525 const FIXED_FILE = 1 << sys::IOSQE_FIXED_FILE_BIT as u8;
526
527 /// 1 << `IOSQE_IO_DRAIN_BIT`
528 const IO_DRAIN = 1 << sys::IOSQE_IO_DRAIN_BIT as u8;
529
530 /// `1 << IOSQE_IO_HARDLINK_BIT`
531 const IO_HARDLINK = 1 << sys::IOSQE_IO_HARDLINK_BIT as u8;
532
533 /// `1 << IOSQE_IO_LINK_BIT`
534 const IO_LINK = 1 << sys::IOSQE_IO_LINK_BIT as u8;
535
536 /// `1 << IOSQE_CQE_SKIP_SUCCESS_BIT`
537 const CQE_SKIP_SUCCESS = 1 << sys::IOSQE_CQE_SKIP_SUCCESS_BIT as u8;
538
539 /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags>
540 const _ = !0;
541 }
542 }
543
544 bitflags::bitflags! {
545 /// `IORING_CQE_F_*` flags for use with [`io_uring_cqe`].
546 #[repr(transparent)]
547 #[derive(Default, Copy, Clone, Eq, PartialEq, Hash, Debug)]
548 pub struct IoringCqeFlags: u32 {
549 /// `IORING_CQE_F_BUFFER`
550 const BUFFER = bitcast!(sys::IORING_CQE_F_BUFFER);
551
552 /// `IORING_CQE_F_MORE`
553 const MORE = bitcast!(sys::IORING_CQE_F_MORE);
554
555 /// `IORING_CQE_F_SOCK_NONEMPTY`
556 const SOCK_NONEMPTY = bitcast!(sys::IORING_CQE_F_SOCK_NONEMPTY);
557
558 /// `IORING_CQE_F_NOTIF`
559 const NOTIF = bitcast!(sys::IORING_CQE_F_NOTIF);
560
561 /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags>
562 const _ = !0;
563 }
564 }
565
566 bitflags::bitflags! {
567 /// `IORING_FSYNC_*` flags for use with [`io_uring_sqe`].
568 #[repr(transparent)]
569 #[derive(Default, Copy, Clone, Eq, PartialEq, Hash, Debug)]
570 pub struct IoringFsyncFlags: u32 {
571 /// `IORING_FSYNC_DATASYNC`
572 const DATASYNC = sys::IORING_FSYNC_DATASYNC;
573
574 /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags>
575 const _ = !0;
576 }
577 }
578
579 bitflags::bitflags! {
580 /// `IORING_TIMEOUT_*` and `IORING_LINK_TIMEOUT_UPDATE` flags for use with
581 /// [`io_uring_sqe`].
582 #[repr(transparent)]
583 #[derive(Default, Copy, Clone, Eq, PartialEq, Hash, Debug)]
584 pub struct IoringTimeoutFlags: u32 {
585 /// `IORING_TIMEOUT_ABS`
586 const ABS = sys::IORING_TIMEOUT_ABS;
587
588 /// `IORING_TIMEOUT_UPDATE`
589 const UPDATE = sys::IORING_TIMEOUT_UPDATE;
590
591 /// `IORING_TIMEOUT_BOOTTIME`
592 const BOOTTIME = sys::IORING_TIMEOUT_BOOTTIME;
593
594 /// `IORING_TIMEOUT_ETIME_SUCCESS`
595 const ETIME_SUCCESS = sys::IORING_TIMEOUT_ETIME_SUCCESS;
596
597 /// `IORING_TIMEOUT_REALTIME`
598 const REALTIME = sys::IORING_TIMEOUT_REALTIME;
599
600 /// `IORING_TIMEOUT_CLOCK_MASK`
601 const CLOCK_MASK = sys::IORING_TIMEOUT_CLOCK_MASK;
602
603 /// `IORING_TIMEOUT_UPDATE_MASK`
604 const UPDATE_MASK = sys::IORING_TIMEOUT_UPDATE_MASK;
605
606 /// `IORING_LINK_TIMEOUT_UPDATE`
607 const LINK_TIMEOUT_UPDATE = sys::IORING_LINK_TIMEOUT_UPDATE;
608
609 /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags>
610 const _ = !0;
611 }
612 }
613
614 bitflags::bitflags! {
615 /// `SPLICE_F_*` flags for use with [`io_uring_sqe`].
616 #[repr(transparent)]
617 #[derive(Default, Copy, Clone, Eq, PartialEq, Hash, Debug)]
618 pub struct SpliceFlags: u32 {
619 /// `SPLICE_F_FD_IN_FIXED`
620 const FD_IN_FIXED = sys::SPLICE_F_FD_IN_FIXED;
621
622 /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags>
623 const _ = !0;
624 }
625 }
626
627 bitflags::bitflags! {
628 /// `IORING_MSG_RING_*` flags for use with [`io_uring_sqe`].
629 #[repr(transparent)]
630 #[derive(Default, Copy, Clone, Eq, PartialEq, Hash, Debug)]
631 pub struct IoringMsgringFlags: u32 {
632 /// `IORING_MSG_RING_CQE_SKIP`
633 const CQE_SKIP = sys::IORING_MSG_RING_CQE_SKIP;
634
635 /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags>
636 const _ = !0;
637 }
638 }
639
640 bitflags::bitflags! {
641 /// `IORING_ASYNC_CANCEL_*` flags for use with [`io_uring_sqe`].
642 #[repr(transparent)]
643 #[derive(Default, Copy, Clone, Eq, PartialEq, Hash, Debug)]
644 pub struct IoringAsyncCancelFlags: u32 {
645 /// `IORING_ASYNC_CANCEL_ALL`
646 const ALL = sys::IORING_ASYNC_CANCEL_ALL;
647
648 /// `IORING_ASYNC_CANCEL_FD`
649 const FD = sys::IORING_ASYNC_CANCEL_FD;
650
651 /// `IORING_ASYNC_CANCEL_FD`
652 const ANY = sys::IORING_ASYNC_CANCEL_ANY;
653
654 /// `IORING_ASYNC_CANCEL_FD`
655 const FD_FIXED = sys::IORING_ASYNC_CANCEL_FD_FIXED;
656
657 /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags>
658 const _ = !0;
659 }
660 }
661
662 bitflags::bitflags! {
663 /// `IORING_FEAT_*` flags for use with [`io_uring_params`].
664 #[repr(transparent)]
665 #[derive(Default, Copy, Clone, Eq, PartialEq, Hash, Debug)]
666 pub struct IoringFeatureFlags: u32 {
667 /// `IORING_FEAT_CQE_SKIP`
668 const CQE_SKIP = sys::IORING_FEAT_CQE_SKIP;
669
670 /// `IORING_FEAT_CUR_PERSONALITY`
671 const CUR_PERSONALITY = sys::IORING_FEAT_CUR_PERSONALITY;
672
673 /// `IORING_FEAT_EXT_ARG`
674 const EXT_ARG = sys::IORING_FEAT_EXT_ARG;
675
676 /// `IORING_FEAT_FAST_POLL`
677 const FAST_POLL = sys::IORING_FEAT_FAST_POLL;
678
679 /// `IORING_FEAT_NATIVE_WORKERS`
680 const NATIVE_WORKERS = sys::IORING_FEAT_NATIVE_WORKERS;
681
682 /// `IORING_FEAT_NODROP`
683 const NODROP = sys::IORING_FEAT_NODROP;
684
685 /// `IORING_FEAT_POLL_32BITS`
686 const POLL_32BITS = sys::IORING_FEAT_POLL_32BITS;
687
688 /// `IORING_FEAT_RSRC_TAGS`
689 const RSRC_TAGS = sys::IORING_FEAT_RSRC_TAGS;
690
691 /// `IORING_FEAT_RW_CUR_POS`
692 const RW_CUR_POS = sys::IORING_FEAT_RW_CUR_POS;
693
694 /// `IORING_FEAT_SINGLE_MMAP`
695 const SINGLE_MMAP = sys::IORING_FEAT_SINGLE_MMAP;
696
697 /// `IORING_FEAT_SQPOLL_NONFIXED`
698 const SQPOLL_NONFIXED = sys::IORING_FEAT_SQPOLL_NONFIXED;
699
700 /// `IORING_FEAT_SUBMIT_STABLE`
701 const SUBMIT_STABLE = sys::IORING_FEAT_SUBMIT_STABLE;
702
703 /// `IORING_FEAT_LINKED_FILE`
704 const LINKED_FILE = sys::IORING_FEAT_LINKED_FILE;
705
706 /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags>
707 const _ = !0;
708 }
709 }
710
711 bitflags::bitflags! {
712 /// `IO_URING_OP_*` flags for use with [`io_uring_probe_op`].
713 #[repr(transparent)]
714 #[derive(Default, Copy, Clone, Eq, PartialEq, Hash, Debug)]
715 pub struct IoringOpFlags: u16 {
716 /// `IO_URING_OP_SUPPORTED`
717 const SUPPORTED = sys::IO_URING_OP_SUPPORTED as _;
718
719 /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags>
720 const _ = !0;
721 }
722 }
723
724 bitflags::bitflags! {
725 /// `IORING_RSRC_*` flags for use with [`io_uring_rsrc_register`].
726 #[repr(transparent)]
727 #[derive(Default, Copy, Clone, Eq, PartialEq, Hash, Debug)]
728 pub struct IoringRsrcFlags: u32 {
729 /// `IORING_RSRC_REGISTER_SPARSE`
730 const REGISTER_SPARSE = sys::IORING_RSRC_REGISTER_SPARSE as _;
731
732 /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags>
733 const _ = !0;
734 }
735 }
736
737 bitflags::bitflags! {
738 /// `IORING_SQ_*` flags.
739 #[repr(transparent)]
740 #[derive(Default, Copy, Clone, Eq, PartialEq, Hash, Debug)]
741 pub struct IoringSqFlags: u32 {
742 /// `IORING_SQ_NEED_WAKEUP`
743 const NEED_WAKEUP = sys::IORING_SQ_NEED_WAKEUP;
744
745 /// `IORING_SQ_CQ_OVERFLOW`
746 const CQ_OVERFLOW = sys::IORING_SQ_CQ_OVERFLOW;
747
748 /// `IORING_SQ_TASKRUN`
749 const TASKRUN = sys::IORING_SQ_TASKRUN;
750
751 /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags>
752 const _ = !0;
753 }
754 }
755
756 bitflags::bitflags! {
757 /// `IORING_CQ_*` flags.
758 #[repr(transparent)]
759 #[derive(Default, Copy, Clone, Eq, PartialEq, Hash, Debug)]
760 pub struct IoringCqFlags: u32 {
761 /// `IORING_CQ_EVENTFD_DISABLED`
762 const EVENTFD_DISABLED = sys::IORING_CQ_EVENTFD_DISABLED;
763
764 /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags>
765 const _ = !0;
766 }
767 }
768
769 bitflags::bitflags! {
770 /// `IORING_POLL_*` flags.
771 #[repr(transparent)]
772 #[derive(Default, Copy, Clone, Eq, PartialEq, Hash, Debug)]
773 pub struct IoringPollFlags: u32 {
774 /// `IORING_POLL_ADD_MULTI`
775 const ADD_MULTI = sys::IORING_POLL_ADD_MULTI;
776
777 /// `IORING_POLL_UPDATE_EVENTS`
778 const UPDATE_EVENTS = sys::IORING_POLL_UPDATE_EVENTS;
779
780 /// `IORING_POLL_UPDATE_USER_DATA`
781 const UPDATE_USER_DATA = sys::IORING_POLL_UPDATE_USER_DATA;
782
783 /// `IORING_POLL_ADD_LEVEL`
784 const ADD_LEVEL = sys::IORING_POLL_ADD_LEVEL;
785
786 /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags>
787 const _ = !0;
788 }
789 }
790
791 bitflags::bitflags! {
792 /// send/sendmsg flags (`sqe.ioprio`)
793 #[repr(transparent)]
794 #[derive(Default, Copy, Clone, Eq, PartialEq, Hash, Debug)]
795 pub struct IoringSendFlags: u16 {
796 /// `IORING_RECVSEND_POLL_FIRST`.
797 ///
798 /// See also [`IoringRecvFlags::POLL_FIRST`].
799 const POLL_FIRST = sys::IORING_RECVSEND_POLL_FIRST as _;
800
801 /// `IORING_RECVSEND_FIXED_BUF`
802 ///
803 /// See also [`IoringRecvFlags::FIXED_BUF`].
804 const FIXED_BUF = sys::IORING_RECVSEND_FIXED_BUF as _;
805
806 /// `IORING_SEND_ZC_REPORT_USAGE` (since Linux 6.2)
807 const ZC_REPORT_USAGE = sys::IORING_SEND_ZC_REPORT_USAGE as _;
808
809 /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags>
810 const _ = !0;
811 }
812 }
813
814 bitflags::bitflags! {
815 /// recv/recvmsg flags (`sqe.ioprio`)
816 #[repr(transparent)]
817 #[derive(Default, Copy, Clone, Eq, PartialEq, Hash, Debug)]
818 pub struct IoringRecvFlags: u16 {
819 /// `IORING_RECVSEND_POLL_FIRST`
820 ///
821 /// See also [`IoringSendFlags::POLL_FIRST`].
822 const POLL_FIRST = sys::IORING_RECVSEND_POLL_FIRST as _;
823
824 /// `IORING_RECV_MULTISHOT`
825 const MULTISHOT = sys::IORING_RECV_MULTISHOT as _;
826
827 /// `IORING_RECVSEND_FIXED_BUF`
828 ///
829 /// See also [`IoringSendFlags::FIXED_BUF`].
830 const FIXED_BUF = sys::IORING_RECVSEND_FIXED_BUF as _;
831
832 /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags>
833 const _ = !0;
834 }
835 }
836
837 bitflags::bitflags! {
838 /// accept flags (`sqe.ioprio`)
839 #[repr(transparent)]
840 #[derive(Default, Copy, Clone, Eq, PartialEq, Hash, Debug)]
841 pub struct IoringAcceptFlags: u16 {
842 /// `IORING_ACCEPT_MULTISHOT`
843 const MULTISHOT = sys::IORING_ACCEPT_MULTISHOT as _;
844
845 /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags>
846 const _ = !0;
847 }
848 }
849
850 bitflags::bitflags! {
851 /// recvmsg out flags
852 #[repr(transparent)]
853 #[derive(Default, Copy, Clone, Eq, PartialEq, Hash, Debug)]
854 pub struct RecvmsgOutFlags: u32 {
855 /// `MSG_EOR`
856 const EOR = net::MSG_EOR;
857
858 /// `MSG_TRUNC`
859 const TRUNC = net::MSG_TRUNC;
860
861 /// `MSG_CTRUNC`
862 const CTRUNC = net::MSG_CTRUNC;
863
864 /// `MSG_OOB`
865 const OOB = net::MSG_OOB;
866
867 /// `MSG_ERRQUEUE`
868 const ERRQUEUE = net::MSG_ERRQUEUE;
869
870 /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags>
871 const _ = !0;
872 }
873 }
874
875 #[allow(missing_docs)]
876 pub const IORING_CQE_BUFFER_SHIFT: u32 = sys::IORING_CQE_BUFFER_SHIFT as _;
877 #[allow(missing_docs)]
878 pub const IORING_FILE_INDEX_ALLOC: i32 = sys::IORING_FILE_INDEX_ALLOC as _;
879
880 // Re-export these as `u64`, which is the `offset` type in `rustix::io::mmap`.
881 #[allow(missing_docs)]
882 pub const IORING_OFF_SQ_RING: u64 = sys::IORING_OFF_SQ_RING as _;
883 #[allow(missing_docs)]
884 pub const IORING_OFF_CQ_RING: u64 = sys::IORING_OFF_CQ_RING as _;
885 #[allow(missing_docs)]
886 pub const IORING_OFF_SQES: u64 = sys::IORING_OFF_SQES as _;
887
888 /// `IORING_REGISTER_FILES_SKIP`
889 #[inline]
890 #[doc(alias = "IORING_REGISTER_FILES_SKIP")]
io_uring_register_files_skip() -> BorrowedFd<'static>891 pub const fn io_uring_register_files_skip() -> BorrowedFd<'static> {
892 let files_skip = sys::IORING_REGISTER_FILES_SKIP as RawFd;
893
894 // SAFETY: `IORING_REGISTER_FILES_SKIP` is a reserved value that is never
895 // dynamically allocated, so it'll remain valid for the duration of
896 // `'static`.
897 unsafe { BorrowedFd::<'static>::borrow_raw(files_skip) }
898 }
899
900 /// `IORING_NOTIF_USAGE_ZC_COPIED` (since Linux 6.2)
901 pub const IORING_NOTIF_USAGE_ZC_COPIED: i32 = sys::IORING_NOTIF_USAGE_ZC_COPIED as _;
902
903 /// A pointer in the io_uring API.
904 ///
905 /// `io_uring`'s native API represents pointers as `u64` values. In order to
906 /// preserve strict-provenance, use a `*mut c_void`. On platforms where
907 /// pointers are narrower than 64 bits, this requires additional padding.
908 #[repr(C)]
909 #[derive(Copy, Clone)]
910 pub struct io_uring_ptr {
911 #[cfg(all(target_pointer_width = "32", target_endian = "big"))]
912 #[doc(hidden)]
913 pub __pad32: u32,
914 #[cfg(all(target_pointer_width = "16", target_endian = "big"))]
915 #[doc(hidden)]
916 pub __pad16: u16,
917
918 /// The pointer value.
919 pub ptr: *mut c_void,
920
921 #[cfg(all(target_pointer_width = "16", target_endian = "little"))]
922 #[doc(hidden)]
923 pub __pad16: u16,
924 #[cfg(all(target_pointer_width = "32", target_endian = "little"))]
925 #[doc(hidden)]
926 pub __pad32: u32,
927 }
928
929 impl From<*mut c_void> for io_uring_ptr {
930 #[inline]
from(ptr: *mut c_void) -> Self931 fn from(ptr: *mut c_void) -> Self {
932 Self {
933 ptr,
934
935 #[cfg(target_pointer_width = "16")]
936 __pad16: Default::default(),
937 #[cfg(any(target_pointer_width = "16", target_pointer_width = "32"))]
938 __pad32: Default::default(),
939 }
940 }
941 }
942
943 impl Default for io_uring_ptr {
944 #[inline]
default() -> Self945 fn default() -> Self {
946 Self::from(null_mut())
947 }
948 }
949
950 /// User data in the io_uring API.
951 ///
952 /// `io_uring`'s native API represents `user_data` fields as `u64` values. In
953 /// order to preserve strict-provenance, use a union which allows users to
954 /// optionally store pointers.
955 #[repr(C)]
956 #[derive(Copy, Clone)]
957 pub union io_uring_user_data {
958 /// An arbitrary `u64`.
959 pub u64_: u64,
960
961 /// A pointer.
962 pub ptr: io_uring_ptr,
963 }
964
965 impl io_uring_user_data {
966 /// Return the `u64` value.
967 #[inline]
u64_(self) -> u64968 pub fn u64_(self) -> u64 {
969 // SAFETY: All the fields have the same underlying representation.
970 unsafe { self.u64_ }
971 }
972
973 /// Create a `Self` from a `u64` value.
974 #[inline]
from_u64(u64_: u64) -> Self975 pub fn from_u64(u64_: u64) -> Self {
976 Self { u64_ }
977 }
978
979 /// Return the `ptr` pointer value.
980 #[inline]
ptr(self) -> *mut c_void981 pub fn ptr(self) -> *mut c_void {
982 // SAFETY: All the fields have the same underlying representation.
983 unsafe { self.ptr }.ptr
984 }
985
986 /// Create a `Self` from a pointer value.
987 #[inline]
from_ptr(ptr: *mut c_void) -> Self988 pub fn from_ptr(ptr: *mut c_void) -> Self {
989 Self {
990 ptr: io_uring_ptr::from(ptr),
991 }
992 }
993 }
994
995 impl Default for io_uring_user_data {
996 #[inline]
default() -> Self997 fn default() -> Self {
998 let mut s = MaybeUninit::<Self>::uninit();
999 // SAFETY: All of Linux's io_uring structs may be zero-initialized.
1000 unsafe {
1001 write_bytes(s.as_mut_ptr(), 0, 1);
1002 s.assume_init()
1003 }
1004 }
1005 }
1006
1007 impl core::fmt::Debug for io_uring_user_data {
fmt(&self, fmt: &mut core::fmt::Formatter<'_>) -> core::fmt::Result1008 fn fmt(&self, fmt: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
1009 // SAFETY: Just format as a `u64`, since formatting doesn't preserve
1010 // provenance, and we don't have a discriminant.
1011 unsafe { self.u64_.fmt(fmt) }
1012 }
1013 }
1014
1015 /// An io_uring Submission Queue Entry.
1016 #[allow(missing_docs)]
1017 #[repr(C)]
1018 #[derive(Copy, Clone, Default)]
1019 pub struct io_uring_sqe {
1020 pub opcode: IoringOp,
1021 pub flags: IoringSqeFlags,
1022 pub ioprio: ioprio_union,
1023 pub fd: RawFd,
1024 pub off_or_addr2: off_or_addr2_union,
1025 pub addr_or_splice_off_in: addr_or_splice_off_in_union,
1026 pub len: len_union,
1027 pub op_flags: op_flags_union,
1028 pub user_data: io_uring_user_data,
1029 pub buf: buf_union,
1030 pub personality: u16,
1031 pub splice_fd_in_or_file_index: splice_fd_in_or_file_index_union,
1032 pub addr3_or_cmd: addr3_or_cmd_union,
1033 }
1034
1035 #[allow(missing_docs)]
1036 #[repr(C)]
1037 #[derive(Copy, Clone)]
1038 pub union ioprio_union {
1039 pub recv_flags: IoringRecvFlags,
1040 pub send_flags: IoringSendFlags,
1041 pub accept_flags: IoringAcceptFlags,
1042 pub ioprio: u16,
1043 }
1044
1045 #[allow(missing_docs)]
1046 #[repr(C)]
1047 #[derive(Copy, Clone)]
1048 pub union len_union {
1049 pub poll_flags: IoringPollFlags,
1050 pub len: u32,
1051 }
1052
1053 #[allow(missing_docs)]
1054 #[repr(C)]
1055 #[derive(Copy, Clone)]
1056 pub union addr3_or_cmd_union {
1057 pub addr3: addr3_struct,
1058 pub cmd: [u8; 0],
1059 }
1060
1061 #[allow(missing_docs)]
1062 #[repr(C)]
1063 #[derive(Copy, Clone, Default)]
1064 pub struct addr3_struct {
1065 pub addr3: u64,
1066 pub __pad2: [u64; 1],
1067 }
1068
1069 #[allow(missing_docs)]
1070 #[repr(C)]
1071 #[derive(Copy, Clone)]
1072 pub union off_or_addr2_union {
1073 pub off: u64,
1074 pub addr2: io_uring_ptr,
1075 pub cmd_op: cmd_op_struct,
1076 pub user_data: io_uring_user_data,
1077 }
1078
1079 #[allow(missing_docs)]
1080 #[repr(C)]
1081 #[derive(Copy, Clone)]
1082 pub struct cmd_op_struct {
1083 pub cmd_op: u32,
1084 pub __pad1: u32,
1085 }
1086
1087 #[allow(missing_docs)]
1088 #[repr(C)]
1089 #[derive(Copy, Clone)]
1090 pub union addr_or_splice_off_in_union {
1091 pub addr: io_uring_ptr,
1092 pub splice_off_in: u64,
1093 pub msgring_cmd: IoringMsgringCmds,
1094 pub user_data: io_uring_user_data,
1095 }
1096
1097 #[allow(missing_docs)]
1098 #[repr(C)]
1099 #[derive(Copy, Clone)]
1100 pub union op_flags_union {
1101 pub rw_flags: crate::io::ReadWriteFlags,
1102 pub fsync_flags: IoringFsyncFlags,
1103 pub poll_events: u16,
1104 pub poll32_events: u32,
1105 pub sync_range_flags: u32,
1106 /// `msg_flags` is split into `send_flags` and `recv_flags`.
1107 #[doc(alias = "msg_flags")]
1108 pub send_flags: SendFlags,
1109 /// `msg_flags` is split into `send_flags` and `recv_flags`.
1110 #[doc(alias = "msg_flags")]
1111 pub recv_flags: RecvFlags,
1112 pub timeout_flags: IoringTimeoutFlags,
1113 pub accept_flags: SocketFlags,
1114 pub cancel_flags: IoringAsyncCancelFlags,
1115 pub open_flags: OFlags,
1116 pub statx_flags: AtFlags,
1117 pub fadvise_advice: Advice,
1118 pub splice_flags: SpliceFlags,
1119 pub rename_flags: RenameFlags,
1120 pub unlink_flags: AtFlags,
1121 pub hardlink_flags: AtFlags,
1122 pub msg_ring_flags: IoringMsgringFlags,
1123 }
1124
1125 #[allow(missing_docs)]
1126 #[repr(C, packed)]
1127 #[derive(Copy, Clone)]
1128 pub union buf_union {
1129 pub buf_index: u16,
1130 pub buf_group: u16,
1131 }
1132
1133 // TODO: Rename this to include `addr_len` when we have a semver bump?
1134 #[allow(missing_docs)]
1135 #[repr(C)]
1136 #[derive(Copy, Clone)]
1137 pub union splice_fd_in_or_file_index_union {
1138 pub splice_fd_in: i32,
1139 pub file_index: u32,
1140 pub addr_len: addr_len_struct,
1141 }
1142
1143 #[allow(missing_docs)]
1144 #[repr(C)]
1145 #[derive(Copy, Clone)]
1146 pub struct addr_len_struct {
1147 pub addr_len: u16,
1148 pub __pad3: [u16; 1],
1149 }
1150
1151 #[allow(missing_docs)]
1152 #[repr(C)]
1153 #[derive(Copy, Clone)]
1154 pub struct io_uring_sync_cancel_reg {
1155 pub addr: u64,
1156 pub fd: i32,
1157 pub flags: IoringAsyncCancelFlags,
1158 pub timeout: Timespec,
1159 pub pad: [u64; 4],
1160 }
1161
1162 /// An io_uring Completion Queue Entry.
1163 ///
1164 /// This does not derive `Copy` or `Clone` because the `big_cqe` field is not
1165 /// automatically copyable.
1166 #[allow(missing_docs)]
1167 #[repr(C)]
1168 #[derive(Debug, Default)]
1169 pub struct io_uring_cqe {
1170 pub user_data: io_uring_user_data,
1171 pub res: i32,
1172 pub flags: IoringCqeFlags,
1173 pub big_cqe: sys::__IncompleteArrayField<u64>,
1174 }
1175
1176 #[allow(missing_docs)]
1177 #[repr(C)]
1178 #[derive(Copy, Clone, Default)]
1179 pub struct io_uring_restriction {
1180 pub opcode: IoringRestrictionOp,
1181 pub register_or_sqe_op_or_sqe_flags: register_or_sqe_op_or_sqe_flags_union,
1182 pub resv: u8,
1183 pub resv2: [u32; 3],
1184 }
1185
1186 #[allow(missing_docs)]
1187 #[repr(C)]
1188 #[derive(Copy, Clone)]
1189 pub union register_or_sqe_op_or_sqe_flags_union {
1190 pub register_op: IoringRegisterOp,
1191 pub sqe_op: IoringOp,
1192 pub sqe_flags: IoringSqeFlags,
1193 }
1194
1195 #[allow(missing_docs)]
1196 #[repr(C)]
1197 #[derive(Debug, Copy, Clone, Default)]
1198 pub struct io_uring_params {
1199 pub sq_entries: u32,
1200 pub cq_entries: u32,
1201 pub flags: IoringSetupFlags,
1202 pub sq_thread_cpu: u32,
1203 pub sq_thread_idle: u32,
1204 pub features: IoringFeatureFlags,
1205 pub wq_fd: u32,
1206 pub resv: [u32; 3],
1207 pub sq_off: io_sqring_offsets,
1208 pub cq_off: io_cqring_offsets,
1209 }
1210
1211 #[allow(missing_docs)]
1212 #[repr(C)]
1213 #[derive(Debug, Copy, Clone, Default)]
1214 pub struct io_sqring_offsets {
1215 pub head: u32,
1216 pub tail: u32,
1217 pub ring_mask: u32,
1218 pub ring_entries: u32,
1219 pub flags: u32,
1220 pub dropped: u32,
1221 pub array: u32,
1222 pub resv1: u32,
1223 pub resv2: u64,
1224 }
1225
1226 #[allow(missing_docs)]
1227 #[repr(C)]
1228 #[derive(Debug, Copy, Clone, Default)]
1229 pub struct io_cqring_offsets {
1230 pub head: u32,
1231 pub tail: u32,
1232 pub ring_mask: u32,
1233 pub ring_entries: u32,
1234 pub overflow: u32,
1235 pub cqes: u32,
1236 pub flags: u32,
1237 pub resv1: u32,
1238 pub resv2: u64,
1239 }
1240
1241 #[allow(missing_docs)]
1242 #[repr(C)]
1243 #[derive(Debug, Default)]
1244 pub struct io_uring_probe {
1245 pub last_op: IoringOp,
1246 pub ops_len: u8,
1247 pub resv: u16,
1248 pub resv2: [u32; 3],
1249 pub ops: sys::__IncompleteArrayField<io_uring_probe_op>,
1250 }
1251
1252 #[allow(missing_docs)]
1253 #[repr(C)]
1254 #[derive(Debug, Copy, Clone, Default)]
1255 pub struct io_uring_probe_op {
1256 pub op: IoringOp,
1257 pub resv: u8,
1258 pub flags: IoringOpFlags,
1259 pub resv2: u32,
1260 }
1261
1262 #[allow(missing_docs)]
1263 #[repr(C, align(8))]
1264 #[derive(Debug, Copy, Clone, Default)]
1265 pub struct io_uring_files_update {
1266 pub offset: u32,
1267 pub resv: u32,
1268 pub fds: u64,
1269 }
1270
1271 #[allow(missing_docs)]
1272 #[repr(C, align(8))]
1273 #[derive(Debug, Copy, Clone, Default)]
1274 pub struct io_uring_rsrc_register {
1275 pub nr: u32,
1276 pub flags: IoringRsrcFlags,
1277 pub resv2: u64,
1278 pub data: u64,
1279 pub tags: u64,
1280 }
1281
1282 #[allow(missing_docs)]
1283 #[repr(C, align(8))]
1284 #[derive(Debug, Copy, Clone, Default)]
1285 pub struct io_uring_rsrc_update {
1286 pub offset: u32,
1287 pub resv: u32,
1288 pub data: u64,
1289 }
1290
1291 #[allow(missing_docs)]
1292 #[repr(C, align(8))]
1293 #[derive(Debug, Copy, Clone, Default)]
1294 pub struct io_uring_rsrc_update2 {
1295 pub offset: u32,
1296 pub resv: u32,
1297 pub data: u64,
1298 pub tags: u64,
1299 pub nr: u32,
1300 pub resv2: u32,
1301 }
1302
1303 #[allow(missing_docs)]
1304 #[repr(C)]
1305 #[derive(Debug, Copy, Clone, Default)]
1306 pub struct io_uring_getevents_arg {
1307 pub sigmask: u64,
1308 pub sigmask_sz: u32,
1309 pub pad: u32,
1310 pub ts: u64,
1311 }
1312
1313 #[allow(missing_docs)]
1314 #[repr(C)]
1315 #[derive(Debug, Default, Copy, Clone)]
1316 pub struct io_uring_recvmsg_out {
1317 pub namelen: u32,
1318 pub controllen: u32,
1319 pub payloadlen: u32,
1320 pub flags: RecvmsgOutFlags,
1321 }
1322
1323 #[allow(missing_docs)]
1324 #[repr(C)]
1325 #[derive(Debug, Copy, Clone)]
1326 pub struct iovec {
1327 pub iov_base: *mut c_void,
1328 pub iov_len: usize,
1329 }
1330
1331 #[allow(missing_docs)]
1332 #[repr(C)]
1333 #[derive(Debug, Copy, Clone, Default)]
1334 pub struct open_how {
1335 /// An [`OFlags`] value represented as a `u64`.
1336 pub flags: u64,
1337
1338 /// A [`Mode`] value represented as a `u64`.
1339 pub mode: u64,
1340
1341 pub resolve: ResolveFlags,
1342 }
1343
1344 #[allow(missing_docs)]
1345 #[repr(C)]
1346 #[derive(Debug, Copy, Clone, Default)]
1347 pub struct io_uring_buf_reg {
1348 pub ring_addr: u64,
1349 pub ring_entries: u32,
1350 pub bgid: u16,
1351 pub pad: u16,
1352 pub resv: [u64; 3_usize],
1353 }
1354
1355 #[allow(missing_docs)]
1356 #[repr(C)]
1357 #[derive(Debug, Copy, Clone, Default)]
1358 pub struct io_uring_buf {
1359 pub addr: u64,
1360 pub len: u32,
1361 pub bid: u16,
1362 pub resv: u16,
1363 }
1364
1365 impl Default for ioprio_union {
1366 #[inline]
default() -> Self1367 fn default() -> Self {
1368 default_union!(ioprio_union, ioprio)
1369 }
1370 }
1371
1372 impl Default for len_union {
1373 #[inline]
default() -> Self1374 fn default() -> Self {
1375 default_union!(len_union, len)
1376 }
1377 }
1378
1379 impl Default for off_or_addr2_union {
1380 #[inline]
default() -> Self1381 fn default() -> Self {
1382 default_union!(off_or_addr2_union, off)
1383 }
1384 }
1385
1386 impl Default for addr_or_splice_off_in_union {
1387 #[inline]
default() -> Self1388 fn default() -> Self {
1389 default_union!(addr_or_splice_off_in_union, splice_off_in)
1390 }
1391 }
1392
1393 impl Default for addr3_or_cmd_union {
1394 #[inline]
default() -> Self1395 fn default() -> Self {
1396 default_union!(addr3_or_cmd_union, addr3)
1397 }
1398 }
1399
1400 impl Default for op_flags_union {
1401 #[inline]
default() -> Self1402 fn default() -> Self {
1403 default_union!(op_flags_union, sync_range_flags)
1404 }
1405 }
1406
1407 impl Default for buf_union {
1408 #[inline]
default() -> Self1409 fn default() -> Self {
1410 default_union!(buf_union, buf_index)
1411 }
1412 }
1413
1414 impl Default for splice_fd_in_or_file_index_union {
1415 #[inline]
default() -> Self1416 fn default() -> Self {
1417 default_union!(splice_fd_in_or_file_index_union, splice_fd_in)
1418 }
1419 }
1420
1421 impl Default for register_or_sqe_op_or_sqe_flags_union {
1422 #[inline]
default() -> Self1423 fn default() -> Self {
1424 default_union!(register_or_sqe_op_or_sqe_flags_union, sqe_flags)
1425 }
1426 }
1427
1428 /// Check that our custom structs and unions have the same layout as the
1429 /// kernel's versions.
1430 #[test]
io_uring_layouts()1431 fn io_uring_layouts() {
1432 use sys as c;
1433
1434 assert_eq_size!(io_uring_ptr, u64);
1435
1436 check_renamed_type!(off_or_addr2_union, io_uring_sqe__bindgen_ty_1);
1437 check_renamed_type!(addr_or_splice_off_in_union, io_uring_sqe__bindgen_ty_2);
1438 check_renamed_type!(addr3_or_cmd_union, io_uring_sqe__bindgen_ty_6);
1439 check_renamed_type!(op_flags_union, io_uring_sqe__bindgen_ty_3);
1440 check_renamed_type!(buf_union, io_uring_sqe__bindgen_ty_4);
1441 check_renamed_type!(splice_fd_in_or_file_index_union, io_uring_sqe__bindgen_ty_5);
1442 check_renamed_type!(addr_len_struct, io_uring_sqe__bindgen_ty_5__bindgen_ty_1);
1443 check_renamed_type!(
1444 register_or_sqe_op_or_sqe_flags_union,
1445 io_uring_restriction__bindgen_ty_1
1446 );
1447
1448 check_renamed_type!(addr3_struct, io_uring_sqe__bindgen_ty_6__bindgen_ty_1);
1449 check_renamed_type!(cmd_op_struct, io_uring_sqe__bindgen_ty_1__bindgen_ty_1);
1450
1451 check_type!(io_uring_sqe);
1452 check_struct_field!(io_uring_sqe, opcode);
1453 check_struct_field!(io_uring_sqe, flags);
1454 check_struct_field!(io_uring_sqe, ioprio);
1455 check_struct_field!(io_uring_sqe, fd);
1456 check_struct_renamed_field!(io_uring_sqe, off_or_addr2, __bindgen_anon_1);
1457 check_struct_renamed_field!(io_uring_sqe, addr_or_splice_off_in, __bindgen_anon_2);
1458 check_struct_field!(io_uring_sqe, len);
1459 check_struct_renamed_field!(io_uring_sqe, op_flags, __bindgen_anon_3);
1460 check_struct_field!(io_uring_sqe, user_data);
1461 check_struct_renamed_field!(io_uring_sqe, buf, __bindgen_anon_4);
1462 check_struct_field!(io_uring_sqe, personality);
1463 check_struct_renamed_field!(io_uring_sqe, splice_fd_in_or_file_index, __bindgen_anon_5);
1464 check_struct_renamed_field!(io_uring_sqe, addr3_or_cmd, __bindgen_anon_6);
1465
1466 check_type!(io_uring_restriction);
1467 check_struct_field!(io_uring_restriction, opcode);
1468 check_struct_renamed_field!(
1469 io_uring_restriction,
1470 register_or_sqe_op_or_sqe_flags,
1471 __bindgen_anon_1
1472 );
1473 check_struct_field!(io_uring_restriction, resv);
1474 check_struct_field!(io_uring_restriction, resv2);
1475
1476 check_struct!(io_uring_cqe, user_data, res, flags, big_cqe);
1477 check_struct!(
1478 io_uring_params,
1479 sq_entries,
1480 cq_entries,
1481 flags,
1482 sq_thread_cpu,
1483 sq_thread_idle,
1484 features,
1485 wq_fd,
1486 resv,
1487 sq_off,
1488 cq_off
1489 );
1490 check_struct!(
1491 io_sqring_offsets,
1492 head,
1493 tail,
1494 ring_mask,
1495 ring_entries,
1496 flags,
1497 dropped,
1498 array,
1499 resv1,
1500 resv2
1501 );
1502 check_struct!(
1503 io_cqring_offsets,
1504 head,
1505 tail,
1506 ring_mask,
1507 ring_entries,
1508 overflow,
1509 cqes,
1510 flags,
1511 resv1,
1512 resv2
1513 );
1514 check_struct!(io_uring_recvmsg_out, namelen, controllen, payloadlen, flags);
1515 check_struct!(io_uring_probe, last_op, ops_len, resv, resv2, ops);
1516 check_struct!(io_uring_probe_op, op, resv, flags, resv2);
1517 check_struct!(io_uring_files_update, offset, resv, fds);
1518 check_struct!(io_uring_rsrc_register, nr, flags, resv2, data, tags);
1519 check_struct!(io_uring_rsrc_update, offset, resv, data);
1520 check_struct!(io_uring_rsrc_update2, offset, resv, data, tags, nr, resv2);
1521 check_struct!(io_uring_getevents_arg, sigmask, sigmask_sz, pad, ts);
1522 check_struct!(iovec, iov_base, iov_len);
1523 check_struct!(open_how, flags, mode, resolve);
1524 check_struct!(io_uring_buf_reg, ring_addr, ring_entries, bgid, pad, resv);
1525 check_struct!(io_uring_buf, addr, len, bid, resv);
1526 check_struct!(io_uring_sync_cancel_reg, addr, fd, flags, timeout, pad);
1527 }
1528