rustix/io_uring/
mod.rs

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://www.man7.org/linux/man-pages/man7/io_uring.7.html
22//! [io_uring]: https://en.wikipedia.org/wiki/Io_uring
23//! [io_uring header]: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/include/uapi/linux/io_uring.h?h=v6.13
24//! [rustix-uring]: https://crates.io/crates/rustix-uring
25#![allow(unsafe_code)]
26
27mod bindgen_types;
28
29use crate::fd::{AsFd, BorrowedFd, OwnedFd, RawFd};
30use crate::utils::option_as_ptr;
31use crate::{backend, io};
32use bindgen_types::*;
33use core::cmp::Ordering;
34use core::ffi::c_void;
35use core::hash::{Hash, Hasher};
36use core::mem::size_of;
37use core::ptr::null_mut;
38use linux_raw_sys::net;
39
40// Export types used in io_uring APIs.
41pub use crate::clockid::ClockId;
42pub use crate::event::epoll::{
43    Event as EpollEvent, EventData as EpollEventData, EventFlags as EpollEventFlags,
44};
45pub use crate::ffi::c_char;
46pub use crate::fs::{
47    Advice, AtFlags, Mode, OFlags, RenameFlags, ResolveFlags, Statx, StatxFlags, XattrFlags,
48};
49pub use crate::io::ReadWriteFlags;
50pub use crate::kernel_sigset::KernelSigSet;
51pub use crate::net::addr::{SocketAddrLen, SocketAddrOpaque, SocketAddrStorage};
52pub use crate::net::{RecvFlags, SendFlags, SocketFlags};
53pub use crate::signal::Signal;
54pub use crate::thread::futex::{
55    Wait as FutexWait, WaitFlags as FutexWaitFlags, WaitPtr as FutexWaitPtr,
56    WaitvFlags as FutexWaitvFlags,
57};
58pub use crate::timespec::{Nsecs, Secs, Timespec};
59
60mod sys {
61    pub(super) use linux_raw_sys::io_uring::*;
62    #[cfg(test)]
63    pub(super) use {
64        crate::backend::c::iovec, linux_raw_sys::general::open_how, linux_raw_sys::net::msghdr,
65    };
66}
67
68/// `msghdr`
69#[allow(missing_docs)]
70#[repr(C)]
71pub struct MsgHdr {
72    pub msg_name: *mut c_void,
73    pub msg_namelen: SocketAddrLen,
74    pub msg_iov: *mut iovec,
75    pub msg_iovlen: usize,
76    pub msg_control: *mut c_void,
77    pub msg_controllen: usize,
78    pub msg_flags: RecvFlags,
79}
80
81/// `io_uring_setup(entries, params)`—Setup a context for performing
82/// asynchronous I/O.
83///
84/// # Safety
85///
86/// If [`IoringSetupFlags::ATTACH_WQ`] is set, the `wq_fd` field of
87/// `io_uring_params` must be an open file descriptor.
88///
89/// # References
90///  - [Linux]
91///
92/// [Linux]: https://www.man7.org/linux/man-pages/man2/io_uring_setup.2.html
93#[inline]
94pub unsafe fn io_uring_setup(entries: u32, params: &mut io_uring_params) -> io::Result<OwnedFd> {
95    backend::io_uring::syscalls::io_uring_setup(entries, params)
96}
97
98/// `io_uring_register(fd, opcode, arg, nr_args)`—Register files or user
99/// buffers for asynchronous I/O.
100///
101/// To pass flags, use [`io_uring_register_with`].
102///
103/// # Safety
104///
105/// io_uring operates on raw pointers and raw file descriptors. Users are
106/// responsible for ensuring that memory and resources are only accessed in
107/// valid ways.
108///
109/// # References
110///  - [Linux]
111///
112/// [Linux]: https://www.man7.org/linux/man-pages/man2/io_uring_register.2.html
113#[inline]
114pub unsafe fn io_uring_register<Fd: AsFd>(
115    fd: Fd,
116    opcode: IoringRegisterOp,
117    arg: *const c_void,
118    nr_args: u32,
119) -> io::Result<u32> {
120    backend::io_uring::syscalls::io_uring_register(fd.as_fd(), opcode, arg, nr_args)
121}
122
123/// `io_uring_register_with(fd, opcode, flags, arg, nr_args)`—Register files or
124/// user buffers for asynchronous I/O.
125///
126/// # Safety
127///
128/// io_uring operates on raw pointers and raw file descriptors. Users are
129/// responsible for ensuring that memory and resources are only accessed in
130/// valid ways.
131///
132/// # References
133///  - [Linux]
134///
135/// [Linux]: https://www.man7.org/linux/man-pages/man2/io_uring_register.2.html
136#[inline]
137pub unsafe fn io_uring_register_with<Fd: AsFd>(
138    fd: Fd,
139    opcode: IoringRegisterOp,
140    flags: IoringRegisterFlags,
141    arg: *const c_void,
142    nr_args: u32,
143) -> io::Result<u32> {
144    backend::io_uring::syscalls::io_uring_register_with(fd.as_fd(), opcode, flags, arg, nr_args)
145}
146
147/// `io_uring_enter(fd, to_submit, min_complete, flags, 0, 0)`—Initiate
148/// and/or complete asynchronous I/O.
149///
150/// This version has no `arg` argument. To pass:
151///  - a signal mask, use [`io_uring_enter_sigmask`].
152///  - an [`io_uring_getevents_arg`], use [`io_uring_enter_arg`] (aka
153///    `io_uring_enter2`).
154///
155/// # Safety
156///
157/// io_uring operates on raw pointers and raw file descriptors. Users are
158/// responsible for ensuring that memory and resources are only accessed in
159/// valid ways.
160///
161/// And, `flags` must not have [`IoringEnterFlags::EXT_ARG`] or
162/// [`IoringEnterFlags::EXT_ARG_REG`] set.
163///
164/// # References
165///  - [Linux]
166///
167/// [Linux]: https://www.man7.org/linux/man-pages/man2/io_uring_enter.2.html
168#[doc(alias = "io_uring_enter2")]
169#[inline]
170pub unsafe fn io_uring_enter<Fd: AsFd>(
171    fd: Fd,
172    to_submit: u32,
173    min_complete: u32,
174    flags: IoringEnterFlags,
175) -> io::Result<u32> {
176    debug_assert!(!flags.contains(IoringEnterFlags::EXT_ARG));
177    debug_assert!(!flags.contains(IoringEnterFlags::EXT_ARG_REG));
178
179    backend::io_uring::syscalls::io_uring_enter(
180        fd.as_fd(),
181        to_submit,
182        min_complete,
183        flags,
184        null_mut(),
185        0,
186    )
187}
188
189/// `io_uring_enter(fd, to_submit, min_complete, flags, sigmask,
190/// sizeof(*sigmask))`— Initiate and/or complete asynchronous I/O, with a
191/// signal mask.
192///
193/// # Safety
194///
195/// io_uring operates on raw pointers and raw file descriptors. Users are
196/// responsible for ensuring that memory and resources are only accessed in
197/// valid ways.
198///
199/// And, `flags` must not have [`IoringEnterFlags::EXT_ARG`] or
200/// [`IoringEnterFlags::EXT_ARG_REG`] set.
201///
202/// And, the `KernelSigSet` referred to by `arg` must not contain any signal
203/// numbers reserved by libc.
204///
205/// # References
206///  - [Linux]
207///
208/// [Linux]: https://www.man7.org/linux/man-pages/man2/io_uring_enter.2.html
209#[doc(alias = "io_uring_enter")]
210#[inline]
211pub unsafe fn io_uring_enter_sigmask<Fd: AsFd>(
212    fd: Fd,
213    to_submit: u32,
214    min_complete: u32,
215    flags: IoringEnterFlags,
216    sigmask: Option<&KernelSigSet>,
217) -> io::Result<u32> {
218    debug_assert!(!flags.contains(IoringEnterFlags::EXT_ARG));
219    debug_assert!(!flags.contains(IoringEnterFlags::EXT_ARG_REG));
220
221    backend::io_uring::syscalls::io_uring_enter(
222        fd.as_fd(),
223        to_submit,
224        min_complete,
225        flags,
226        option_as_ptr(sigmask).cast::<c_void>(),
227        size_of::<KernelSigSet>(),
228    )
229}
230
231/// `io_uring_enter2(fd, to_submit, min_complete, flags, arg, sizeof(*arg))`—
232/// Initiate and/or complete asynchronous I/O, with a signal mask and a
233/// timeout.
234///
235/// # Safety
236///
237/// io_uring operates on raw pointers and raw file descriptors. Users are
238/// responsible for ensuring that memory and resources are only accessed in
239/// valid ways.
240///
241/// And, `flags` must have [`IoringEnterFlags::EXT_ARG`] set, and must not have
242/// [`IoringEnterFlags::EXT_ARG_REG`] set.
243///
244/// And, the `KernelSigSet` pointed to by the `io_uring_getenvets_arg` referred
245/// to by `arg` must not contain any signal numbers reserved by libc.
246///
247/// # References
248///  - [Linux]
249///
250/// [Linux]: https://www.man7.org/linux/man-pages/man2/io_uring_enter.2.html
251#[doc(alias = "io_uring_enter")]
252#[doc(alias = "io_uring_enter2")]
253#[inline]
254pub unsafe fn io_uring_enter_arg<Fd: AsFd>(
255    fd: Fd,
256    to_submit: u32,
257    min_complete: u32,
258    flags: IoringEnterFlags,
259    arg: Option<&io_uring_getevents_arg>,
260) -> io::Result<u32> {
261    debug_assert!(flags.contains(IoringEnterFlags::EXT_ARG));
262    debug_assert!(!flags.contains(IoringEnterFlags::EXT_ARG_REG));
263
264    backend::io_uring::syscalls::io_uring_enter(
265        fd.as_fd(),
266        to_submit,
267        min_complete,
268        flags,
269        option_as_ptr(arg).cast::<c_void>(),
270        size_of::<io_uring_getevents_arg>(),
271    )
272}
273
274// TODO: Uncomment this when we support `IoringRegisterOp::CQWAIT_REG`.
275/*
276/// `io_uring_enter2(fd, to_submit, min_complete, flags, offset,
277/// sizeof(io_uring_reg_wait))`— Initiate and/or complete asynchronous I/O,
278/// using a previously registered `io_uring_reg_wait`.
279///
280/// `offset` is an offset into an area of wait regions previously registered
281/// with [`io_uring_register`] using the [`IoringRegisterOp::CQWAIT_REG`]
282/// operation.
283///
284/// # Safety
285///
286/// io_uring operates on raw pointers and raw file descriptors. Users are
287/// responsible for ensuring that memory and resources are only accessed in
288/// valid ways.
289///
290/// And, `flags` must have [`IoringEnterFlags::EXT_ARG_REG`] set, and must not
291/// have [`IoringEnterFlags::EXT_ARG`] set.
292///
293/// # References
294///  - [Linux]
295///
296/// [Linux]: https://www.man7.org/linux/man-pages/man2/io_uring_enter.2.html
297#[doc(alias = "io_uring_enter")]
298#[doc(alias = "io_uring_enter2")]
299#[inline]
300pub unsafe fn io_uring_enter_reg_wait<Fd: AsFd>(
301    fd: Fd,
302    to_submit: u32,
303    min_complete: u32,
304    flags: IoringEnterFlags,
305    reg_wait: usize,
306) -> io::Result<u32> {
307    debug_assert!(!flags.contains(IoringEnterFlags::EXT_ARG));
308    debug_assert!(flags.contains(IoringEnterFlags::EXT_ARG_REG));
309
310    backend::io_uring::syscalls::io_uring_enter(
311        fd.as_fd(),
312        to_submit,
313        min_complete,
314        flags,
315        reg_wait as *mut c_void,
316        size_of::<io_uring_reg_wait>(),
317    )
318}
319*/
320
321bitflags::bitflags! {
322    /// `IORING_ENTER_*` flags for use with [`io_uring_enter`].
323    #[repr(transparent)]
324    #[derive(Default, Copy, Clone, Eq, PartialEq, Hash, Debug)]
325    pub struct IoringEnterFlags: u32 {
326        /// `IORING_ENTER_GETEVENTS`
327        const GETEVENTS = sys::IORING_ENTER_GETEVENTS;
328
329        /// `IORING_ENTER_SQ_WAKEUP`
330        const SQ_WAKEUP = sys::IORING_ENTER_SQ_WAKEUP;
331
332        /// `IORING_ENTER_SQ_WAIT`
333        const SQ_WAIT = sys::IORING_ENTER_SQ_WAIT;
334
335        /// `IORING_ENTER_EXT_ARG` (since Linux 5.11)
336        const EXT_ARG = sys::IORING_ENTER_EXT_ARG;
337
338        /// `IORING_ENTER_REGISTERED_RING`
339        const REGISTERED_RING = sys::IORING_ENTER_REGISTERED_RING;
340
341        /// `IORING_ENTER_ABS_TIMER` (since Linux 6.12)
342        const ABS_TIMER = sys::IORING_ENTER_ABS_TIMER;
343
344        /// `IORING_ENTER_EXT_ARG_REG` (since Linux 6.12)
345        const EXT_ARG_REG = sys::IORING_ENTER_EXT_ARG_REG;
346
347        /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags>
348        const _ = !0;
349    }
350}
351
352/// `IORING_REGISTER_*` and `IORING_UNREGISTER_*` constants for use with
353/// [`io_uring_register`].
354#[derive(Debug, Clone, Copy, Eq, PartialEq, Hash)]
355#[repr(u8)]
356#[non_exhaustive]
357pub enum IoringRegisterOp {
358    /// `IORING_REGISTER_BUFFERS`
359    RegisterBuffers = sys::io_uring_register_op::IORING_REGISTER_BUFFERS as _,
360
361    /// `IORING_UNREGISTER_BUFFERS`
362    UnregisterBuffers = sys::io_uring_register_op::IORING_UNREGISTER_BUFFERS as _,
363
364    /// `IORING_REGISTER_FILES`
365    RegisterFiles = sys::io_uring_register_op::IORING_REGISTER_FILES as _,
366
367    /// `IORING_UNREGISTER_FILES`
368    UnregisterFiles = sys::io_uring_register_op::IORING_UNREGISTER_FILES as _,
369
370    /// `IORING_REGISTER_EVENTFD`
371    RegisterEventfd = sys::io_uring_register_op::IORING_REGISTER_EVENTFD as _,
372
373    /// `IORING_UNREGISTER_EVENTFD`
374    UnregisterEventfd = sys::io_uring_register_op::IORING_UNREGISTER_EVENTFD as _,
375
376    /// `IORING_REGISTER_FILES_UPDATE`
377    RegisterFilesUpdate = sys::io_uring_register_op::IORING_REGISTER_FILES_UPDATE as _,
378
379    /// `IORING_REGISTER_EVENTFD_ASYNC`
380    RegisterEventfdAsync = sys::io_uring_register_op::IORING_REGISTER_EVENTFD_ASYNC as _,
381
382    /// `IORING_REGISTER_PROBE`
383    RegisterProbe = sys::io_uring_register_op::IORING_REGISTER_PROBE as _,
384
385    /// `IORING_REGISTER_PERSONALITY`
386    RegisterPersonality = sys::io_uring_register_op::IORING_REGISTER_PERSONALITY as _,
387
388    /// `IORING_UNREGISTER_PERSONALITY`
389    UnregisterPersonality = sys::io_uring_register_op::IORING_UNREGISTER_PERSONALITY as _,
390
391    /// `IORING_REGISTER_RESTRICTIONS`
392    RegisterRestrictions = sys::io_uring_register_op::IORING_REGISTER_RESTRICTIONS as _,
393
394    /// `IORING_REGISTER_ENABLE_RINGS`
395    RegisterEnableRings = sys::io_uring_register_op::IORING_REGISTER_ENABLE_RINGS as _,
396
397    /// `IORING_REGISTER_BUFFERS2`
398    RegisterBuffers2 = sys::io_uring_register_op::IORING_REGISTER_BUFFERS2 as _,
399
400    /// `IORING_REGISTER_BUFFERS_UPDATE`
401    RegisterBuffersUpdate = sys::io_uring_register_op::IORING_REGISTER_BUFFERS_UPDATE as _,
402
403    /// `IORING_REGISTER_FILES2`
404    RegisterFiles2 = sys::io_uring_register_op::IORING_REGISTER_FILES2 as _,
405
406    /// `IORING_REGISTER_FILES_UPDATE2`
407    RegisterFilesUpdate2 = sys::io_uring_register_op::IORING_REGISTER_FILES_UPDATE2 as _,
408
409    /// `IORING_REGISTER_IOWQ_AFF`
410    RegisterIowqAff = sys::io_uring_register_op::IORING_REGISTER_IOWQ_AFF as _,
411
412    /// `IORING_UNREGISTER_IOWQ_AFF`
413    UnregisterIowqAff = sys::io_uring_register_op::IORING_UNREGISTER_IOWQ_AFF as _,
414
415    /// `IORING_REGISTER_IOWQ_MAX_WORKERS`
416    RegisterIowqMaxWorkers = sys::io_uring_register_op::IORING_REGISTER_IOWQ_MAX_WORKERS as _,
417
418    /// `IORING_REGISTER_RING_FDS`
419    RegisterRingFds = sys::io_uring_register_op::IORING_REGISTER_RING_FDS as _,
420
421    /// `IORING_UNREGISTER_RING_FDS`
422    UnregisterRingFds = sys::io_uring_register_op::IORING_UNREGISTER_RING_FDS as _,
423
424    /// `IORING_REGISTER_PBUF_RING`
425    RegisterPbufRing = sys::io_uring_register_op::IORING_REGISTER_PBUF_RING as _,
426
427    /// `IORING_UNREGISTER_PBUF_RING`
428    UnregisterPbufRing = sys::io_uring_register_op::IORING_UNREGISTER_PBUF_RING as _,
429
430    /// `IORING_REGISTER_SYNC_CANCEL`
431    RegisterSyncCancel = sys::io_uring_register_op::IORING_REGISTER_SYNC_CANCEL as _,
432
433    /// `IORING_REGISTER_FILE_ALLOC_RANGE`
434    RegisterFileAllocRange = sys::io_uring_register_op::IORING_REGISTER_FILE_ALLOC_RANGE as _,
435
436    /// `IORING_REGISTER_PBUF_STATUS` (since Linux 6.8)
437    RegisterPbufStatus = sys::io_uring_register_op::IORING_REGISTER_PBUF_STATUS as _,
438
439    /// `IORING_REGISTER_NAPI` (since Linux 6.9)
440    RegisterNapi = sys::io_uring_register_op::IORING_REGISTER_NAPI as _,
441
442    /// `IORING_UNREGISTER_NAPI` (since Linux 6.9)
443    UnregisterNapi = sys::io_uring_register_op::IORING_UNREGISTER_NAPI as _,
444
445    /// `IORING_REGISTER_CLOCK` (since Linux 6.12)
446    RegisterClock = sys::io_uring_register_op::IORING_REGISTER_CLOCK as _,
447
448    /// `IORING_REGISTER_CLONE_BUFFERS ` (since Linux 6.12)
449    RegisterCloneBuffers = sys::io_uring_register_op::IORING_REGISTER_CLONE_BUFFERS as _,
450
451    /// `IORING_REGISTER_SEND_MSG_RING` (since Linux 6.12)
452    RegisterSendMsgRing = sys::io_uring_register_op::IORING_REGISTER_SEND_MSG_RING as _,
453
454    /// `IORING_REGISTER_RESIZE_RINGS`(since Linux 6.13)
455    RegisterResizeRings = sys::io_uring_register_op::IORING_REGISTER_RESIZE_RINGS as _,
456}
457
458bitflags::bitflags! {
459    /// `IORING_REGISTER_*` flags for use with [`io_uring_register_with`].
460    #[repr(transparent)]
461    #[derive(Default, Copy, Clone, Eq, PartialEq, Hash, Debug)]
462    pub struct IoringRegisterFlags: u32 {
463        /// `IORING_REGISTER_USE_REGISTERED_RING`
464        const USE_REGISTERED_RING = sys::io_uring_register_op::IORING_REGISTER_USE_REGISTERED_RING as u32;
465
466        /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags>
467        const _ = !0;
468    }
469}
470
471/// `IORING_OP_*` constants for use with [`io_uring_sqe`].
472#[derive(Debug, Clone, Copy, Eq, PartialEq, Hash)]
473#[repr(u8)]
474#[non_exhaustive]
475pub enum IoringOp {
476    /// `IORING_OP_NOP`
477    Nop = sys::io_uring_op::IORING_OP_NOP as _,
478
479    /// `IORING_OP_ACCEPT`
480    Accept = sys::io_uring_op::IORING_OP_ACCEPT as _,
481
482    /// `IORING_OP_ASYNC_CANCEL`
483    AsyncCancel = sys::io_uring_op::IORING_OP_ASYNC_CANCEL as _,
484
485    /// `IORING_OP_CLOSE`
486    Close = sys::io_uring_op::IORING_OP_CLOSE as _,
487
488    /// `IORING_OP_CONNECT`
489    Connect = sys::io_uring_op::IORING_OP_CONNECT as _,
490
491    /// `IORING_OP_EPOLL_CTL`
492    EpollCtl = sys::io_uring_op::IORING_OP_EPOLL_CTL as _,
493
494    /// `IORING_OP_FADVISE`
495    Fadvise = sys::io_uring_op::IORING_OP_FADVISE as _,
496
497    /// `IORING_OP_FALLOCATE`
498    Fallocate = sys::io_uring_op::IORING_OP_FALLOCATE as _,
499
500    /// `IORING_OP_FILES_UPDATE`
501    FilesUpdate = sys::io_uring_op::IORING_OP_FILES_UPDATE as _,
502
503    /// `IORING_OP_FSYNC`
504    Fsync = sys::io_uring_op::IORING_OP_FSYNC as _,
505
506    /// `IORING_OP_LINKAT`
507    Linkat = sys::io_uring_op::IORING_OP_LINKAT as _,
508
509    /// `IORING_OP_LINK_TIMEOUT`
510    LinkTimeout = sys::io_uring_op::IORING_OP_LINK_TIMEOUT as _,
511
512    /// `IORING_OP_MADVISE`
513    Madvise = sys::io_uring_op::IORING_OP_MADVISE as _,
514
515    /// `IORING_OP_MKDIRAT`
516    Mkdirat = sys::io_uring_op::IORING_OP_MKDIRAT as _,
517
518    /// `IORING_OP_OPENAT`
519    Openat = sys::io_uring_op::IORING_OP_OPENAT as _,
520
521    /// `IORING_OP_OPENAT2`
522    Openat2 = sys::io_uring_op::IORING_OP_OPENAT2 as _,
523
524    /// `IORING_OP_POLL_ADD`
525    PollAdd = sys::io_uring_op::IORING_OP_POLL_ADD as _,
526
527    /// `IORING_OP_POLL_REMOVE`
528    PollRemove = sys::io_uring_op::IORING_OP_POLL_REMOVE as _,
529
530    /// `IORING_OP_PROVIDE_BUFFERS`
531    ProvideBuffers = sys::io_uring_op::IORING_OP_PROVIDE_BUFFERS as _,
532
533    /// `IORING_OP_READ`
534    Read = sys::io_uring_op::IORING_OP_READ as _,
535
536    /// `IORING_OP_READV`
537    Readv = sys::io_uring_op::IORING_OP_READV as _,
538
539    /// `IORING_OP_READ_FIXED`
540    ReadFixed = sys::io_uring_op::IORING_OP_READ_FIXED as _,
541
542    /// `IORING_OP_RECV`
543    Recv = sys::io_uring_op::IORING_OP_RECV as _,
544
545    /// `IORING_OP_RECVMSG`
546    Recvmsg = sys::io_uring_op::IORING_OP_RECVMSG as _,
547
548    /// `IORING_OP_REMOVE_BUFFERS`
549    RemoveBuffers = sys::io_uring_op::IORING_OP_REMOVE_BUFFERS as _,
550
551    /// `IORING_OP_RENAMEAT`
552    Renameat = sys::io_uring_op::IORING_OP_RENAMEAT as _,
553
554    /// `IORING_OP_SEND`
555    Send = sys::io_uring_op::IORING_OP_SEND as _,
556
557    /// `IORING_OP_SENDMSG`
558    Sendmsg = sys::io_uring_op::IORING_OP_SENDMSG as _,
559
560    /// `IORING_OP_SHUTDOWN`
561    Shutdown = sys::io_uring_op::IORING_OP_SHUTDOWN as _,
562
563    /// `IORING_OP_SPLICE`
564    Splice = sys::io_uring_op::IORING_OP_SPLICE as _,
565
566    /// `IORING_OP_STATX`
567    Statx = sys::io_uring_op::IORING_OP_STATX as _,
568
569    /// `IORING_OP_SYMLINKAT`
570    Symlinkat = sys::io_uring_op::IORING_OP_SYMLINKAT as _,
571
572    /// `IORING_OP_SYNC_FILE_RANGE`
573    SyncFileRange = sys::io_uring_op::IORING_OP_SYNC_FILE_RANGE as _,
574
575    /// `IORING_OP_TEE`
576    Tee = sys::io_uring_op::IORING_OP_TEE as _,
577
578    /// `IORING_OP_TIMEOUT`
579    Timeout = sys::io_uring_op::IORING_OP_TIMEOUT as _,
580
581    /// `IORING_OP_TIMEOUT_REMOVE`
582    TimeoutRemove = sys::io_uring_op::IORING_OP_TIMEOUT_REMOVE as _,
583
584    /// `IORING_OP_UNLINKAT`
585    Unlinkat = sys::io_uring_op::IORING_OP_UNLINKAT as _,
586
587    /// `IORING_OP_WRITE`
588    Write = sys::io_uring_op::IORING_OP_WRITE as _,
589
590    /// `IORING_OP_WRITEV`
591    Writev = sys::io_uring_op::IORING_OP_WRITEV as _,
592
593    /// `IORING_OP_WRITE_FIXED`
594    WriteFixed = sys::io_uring_op::IORING_OP_WRITE_FIXED as _,
595
596    /// `IORING_OP_MSG_RING`
597    MsgRing = sys::io_uring_op::IORING_OP_MSG_RING as _,
598
599    /// `IORING_OP_FSETXATTR`
600    Fsetxattr = sys::io_uring_op::IORING_OP_FSETXATTR as _,
601
602    /// `IORING_OP_SETXATTR`
603    Setxattr = sys::io_uring_op::IORING_OP_SETXATTR as _,
604
605    /// `IORING_OP_FGETXATTR`
606    Fgetxattr = sys::io_uring_op::IORING_OP_FGETXATTR as _,
607
608    /// `IORING_OP_GETXATTR`
609    Getxattr = sys::io_uring_op::IORING_OP_GETXATTR as _,
610
611    /// `IORING_OP_SOCKET`
612    Socket = sys::io_uring_op::IORING_OP_SOCKET as _,
613
614    /// `IORING_OP_URING_CMD`
615    UringCmd = sys::io_uring_op::IORING_OP_URING_CMD as _,
616
617    /// `IORING_OP_SEND_ZC`
618    SendZc = sys::io_uring_op::IORING_OP_SEND_ZC as _,
619
620    /// `IORING_OP_SENDMSG_ZC`
621    SendmsgZc = sys::io_uring_op::IORING_OP_SENDMSG_ZC as _,
622
623    /// `IORING_OP_READ_MULTISHOT` (since Linux 6.7)
624    ReadMultishot = sys::io_uring_op::IORING_OP_READ_MULTISHOT as _,
625
626    /// `IORING_OP_WAITID` (since Linux 6.5)
627    Waitid = sys::io_uring_op::IORING_OP_WAITID as _,
628
629    /// `IORING_OP_FUTEX_WAIT` (since Linux 6.7)
630    FutexWait = sys::io_uring_op::IORING_OP_FUTEX_WAIT as _,
631
632    /// `IORING_OP_FUTEX_WAKE` (since Linux 6.7)
633    FutexWake = sys::io_uring_op::IORING_OP_FUTEX_WAKE as _,
634
635    /// `IORING_OP_FUTEX_WAITV` (since Linux 6.7)
636    FutexWaitv = sys::io_uring_op::IORING_OP_FUTEX_WAITV as _,
637
638    /// `IORING_OP_FIXED_FD_INSTALL` (since Linux 6.8)
639    FixedFdInstall = sys::io_uring_op::IORING_OP_FIXED_FD_INSTALL as _,
640
641    /// `IORING_OP_FTRUNCATE` (since Linux 6.9)
642    Ftruncate = sys::io_uring_op::IORING_OP_FTRUNCATE as _,
643
644    /// `IORING_OP_BIND` (since Linux 6.11)
645    Bind = sys::io_uring_op::IORING_OP_BIND as _,
646
647    /// `IORING_OP_LISTEN` (since Linux 6.11)
648    Listen = sys::io_uring_op::IORING_OP_LISTEN as _,
649}
650
651impl Default for IoringOp {
652    #[inline]
653    fn default() -> Self {
654        Self::Nop
655    }
656}
657
658/// `IORING_RESTRICTION_*` constants for use with [`io_uring_restriction`].
659#[derive(Debug, Clone, Copy, Eq, PartialEq, Hash)]
660#[repr(u16)]
661#[non_exhaustive]
662pub enum IoringRestrictionOp {
663    /// `IORING_RESTRICTION_REGISTER_OP`
664    RegisterOp = sys::io_uring_register_restriction_op::IORING_RESTRICTION_REGISTER_OP as _,
665
666    /// `IORING_RESTRICTION_SQE_FLAGS_ALLOWED`
667    SqeFlagsAllowed =
668        sys::io_uring_register_restriction_op::IORING_RESTRICTION_SQE_FLAGS_ALLOWED as _,
669
670    /// `IORING_RESTRICTION_SQE_FLAGS_REQUIRED`
671    SqeFlagsRequired =
672        sys::io_uring_register_restriction_op::IORING_RESTRICTION_SQE_FLAGS_REQUIRED as _,
673
674    /// `IORING_RESTRICTION_SQE_OP`
675    SqeOp = sys::io_uring_register_restriction_op::IORING_RESTRICTION_SQE_OP as _,
676}
677
678impl Default for IoringRestrictionOp {
679    #[inline]
680    fn default() -> Self {
681        Self::RegisterOp
682    }
683}
684
685/// `IORING_MSG_*` constants which represent commands for use with
686/// [`IoringOp::MsgRing`], (`seq.addr`)
687#[derive(Debug, Clone, Copy, Eq, PartialEq, Hash)]
688#[repr(u64)]
689#[non_exhaustive]
690pub enum IoringMsgringCmds {
691    /// `IORING_MSG_DATA`
692    Data = sys::io_uring_msg_ring_flags::IORING_MSG_DATA as _,
693
694    /// `IORING_MSG_SEND_FD`
695    SendFd = sys::io_uring_msg_ring_flags::IORING_MSG_SEND_FD as _,
696}
697
698bitflags::bitflags! {
699    /// `IORING_SETUP_*` flags for use with [`io_uring_params`].
700    #[repr(transparent)]
701    #[derive(Default, Copy, Clone, Eq, PartialEq, Hash, Debug)]
702    pub struct IoringSetupFlags: u32 {
703        /// `IORING_SETUP_ATTACH_WQ`
704        const ATTACH_WQ = sys::IORING_SETUP_ATTACH_WQ;
705
706        /// `IORING_SETUP_CLAMP`
707        const CLAMP = sys::IORING_SETUP_CLAMP;
708
709        /// `IORING_SETUP_CQSIZE`
710        const CQSIZE = sys::IORING_SETUP_CQSIZE;
711
712        /// `IORING_SETUP_IOPOLL`
713        const IOPOLL = sys::IORING_SETUP_IOPOLL;
714
715        /// `IORING_SETUP_R_DISABLED`
716        const R_DISABLED = sys::IORING_SETUP_R_DISABLED;
717
718        /// `IORING_SETUP_SQPOLL`
719        const SQPOLL = sys::IORING_SETUP_SQPOLL;
720
721        /// `IORING_SETUP_SQ_AFF`
722        const SQ_AFF = sys::IORING_SETUP_SQ_AFF;
723
724        /// `IORING_SETUP_SQE128`
725        const SQE128 = sys::IORING_SETUP_SQE128;
726
727        /// `IORING_SETUP_CQE32`
728        const CQE32 = sys::IORING_SETUP_CQE32;
729
730        /// `IORING_SETUP_SUBMIT_ALL`
731        const SUBMIT_ALL = sys::IORING_SETUP_SUBMIT_ALL;
732
733        /// `IORING_SETUP_COOP_TRASKRUN`
734        const COOP_TASKRUN = sys::IORING_SETUP_COOP_TASKRUN;
735
736        /// `IORING_SETUP_TASKRUN_FLAG`
737        const TASKRUN_FLAG = sys::IORING_SETUP_TASKRUN_FLAG;
738
739        /// `IORING_SETUP_SINGLE_ISSUER`
740        const SINGLE_ISSUER = sys::IORING_SETUP_SINGLE_ISSUER;
741
742        /// `IORING_SETUP_DEFER_TASKRUN`
743        const DEFER_TASKRUN = sys::IORING_SETUP_DEFER_TASKRUN;
744
745        /// `IORING_SETUP_NO_MMAP`
746        const NO_MMAP = sys::IORING_SETUP_NO_MMAP;
747
748        /// `IORING_SETUP_REGISTERED_FD_ONLY`
749        const REGISTERED_FD_ONLY = sys::IORING_SETUP_REGISTERED_FD_ONLY;
750
751        /// `IORING_SETUP_NO_SQARRAY`
752        const NO_SQARRAY = sys::IORING_SETUP_NO_SQARRAY;
753
754        /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags>
755        const _ = !0;
756    }
757}
758
759bitflags::bitflags! {
760    /// `IOSQE_*` flags for use with [`io_uring_sqe`].
761    #[repr(transparent)]
762    #[derive(Default, Copy, Clone, Eq, PartialEq, Hash, Debug)]
763    pub struct IoringSqeFlags: u8 {
764        /// `1 << IOSQE_ASYNC_BIT`
765        const ASYNC = 1 << sys::io_uring_sqe_flags_bit::IOSQE_ASYNC_BIT as u8;
766
767        /// `1 << IOSQE_BUFFER_SELECT_BIT`
768        const BUFFER_SELECT = 1 << sys::io_uring_sqe_flags_bit::IOSQE_BUFFER_SELECT_BIT as u8;
769
770        /// `1 << IOSQE_FIXED_FILE_BIT`
771        const FIXED_FILE = 1 << sys::io_uring_sqe_flags_bit::IOSQE_FIXED_FILE_BIT as u8;
772
773        /// 1 << `IOSQE_IO_DRAIN_BIT`
774        const IO_DRAIN = 1 << sys::io_uring_sqe_flags_bit::IOSQE_IO_DRAIN_BIT as u8;
775
776        /// `1 << IOSQE_IO_HARDLINK_BIT`
777        const IO_HARDLINK = 1 << sys::io_uring_sqe_flags_bit::IOSQE_IO_HARDLINK_BIT as u8;
778
779        /// `1 << IOSQE_IO_LINK_BIT`
780        const IO_LINK = 1 << sys::io_uring_sqe_flags_bit::IOSQE_IO_LINK_BIT as u8;
781
782        /// `1 << IOSQE_CQE_SKIP_SUCCESS_BIT`
783        const CQE_SKIP_SUCCESS = 1 << sys::io_uring_sqe_flags_bit::IOSQE_CQE_SKIP_SUCCESS_BIT as u8;
784
785        /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags>
786        const _ = !0;
787    }
788}
789
790bitflags::bitflags! {
791    /// `IORING_CQE_F_*` flags for use with [`io_uring_cqe`].
792    #[repr(transparent)]
793    #[derive(Default, Copy, Clone, Eq, PartialEq, Hash, Debug)]
794    pub struct IoringCqeFlags: u32 {
795        /// `IORING_CQE_F_BUFFER`
796        const BUFFER = bitcast!(sys::IORING_CQE_F_BUFFER);
797
798        /// `IORING_CQE_F_MORE`
799        const MORE = bitcast!(sys::IORING_CQE_F_MORE);
800
801        /// `IORING_CQE_F_SOCK_NONEMPTY`
802        const SOCK_NONEMPTY = bitcast!(sys::IORING_CQE_F_SOCK_NONEMPTY);
803
804        /// `IORING_CQE_F_NOTIF`
805        const NOTIF = bitcast!(sys::IORING_CQE_F_NOTIF);
806
807        /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags>
808        const _ = !0;
809    }
810}
811
812bitflags::bitflags! {
813    /// `IORING_FSYNC_*` flags for use with [`io_uring_sqe`].
814    #[repr(transparent)]
815    #[derive(Default, Copy, Clone, Eq, PartialEq, Hash, Debug)]
816    pub struct IoringFsyncFlags: u32 {
817        /// `IORING_FSYNC_DATASYNC`
818        const DATASYNC = sys::IORING_FSYNC_DATASYNC;
819
820        /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags>
821        const _ = !0;
822    }
823}
824
825bitflags::bitflags! {
826    /// `IORING_TIMEOUT_*` and `IORING_LINK_TIMEOUT_UPDATE` flags for use with
827    /// [`io_uring_sqe`].
828    #[repr(transparent)]
829    #[derive(Default, Copy, Clone, Eq, PartialEq, Hash, Debug)]
830    pub struct IoringTimeoutFlags: u32 {
831        /// `IORING_TIMEOUT_ABS`
832        const ABS = sys::IORING_TIMEOUT_ABS;
833
834        /// `IORING_TIMEOUT_UPDATE`
835        const UPDATE = sys::IORING_TIMEOUT_UPDATE;
836
837        /// `IORING_TIMEOUT_BOOTTIME`
838        const BOOTTIME = sys::IORING_TIMEOUT_BOOTTIME;
839
840        /// `IORING_TIMEOUT_ETIME_SUCCESS`
841        const ETIME_SUCCESS = sys::IORING_TIMEOUT_ETIME_SUCCESS;
842
843        /// `IORING_TIMEOUT_REALTIME`
844        const REALTIME = sys::IORING_TIMEOUT_REALTIME;
845
846        /// `IORING_TIMEOUT_CLOCK_MASK`
847        const CLOCK_MASK = sys::IORING_TIMEOUT_CLOCK_MASK;
848
849        /// `IORING_TIMEOUT_UPDATE_MASK`
850        const UPDATE_MASK = sys::IORING_TIMEOUT_UPDATE_MASK;
851
852        /// `IORING_LINK_TIMEOUT_UPDATE`
853        const LINK_TIMEOUT_UPDATE = sys::IORING_LINK_TIMEOUT_UPDATE;
854
855        /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags>
856        const _ = !0;
857    }
858}
859
860bitflags::bitflags! {
861    /// `SPLICE_F_*` flags for use with [`io_uring_sqe`].
862    #[repr(transparent)]
863    #[derive(Default, Copy, Clone, Eq, PartialEq, Hash, Debug)]
864    pub struct SpliceFlags: u32 {
865        /// `SPLICE_F_FD_IN_FIXED`
866        const FD_IN_FIXED = sys::SPLICE_F_FD_IN_FIXED;
867
868        /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags>
869        const _ = !0;
870    }
871}
872
873bitflags::bitflags! {
874    /// `IORING_MSG_RING_*` flags for use with [`io_uring_sqe`].
875    #[repr(transparent)]
876    #[derive(Default, Copy, Clone, Eq, PartialEq, Hash, Debug)]
877    pub struct IoringMsgringFlags: u32 {
878        /// `IORING_MSG_RING_CQE_SKIP`
879        const CQE_SKIP = sys::IORING_MSG_RING_CQE_SKIP;
880
881        /// `IORING_MSG_RING_FLAGS_PASS`
882        const FLAGS_PASS = sys::IORING_MSG_RING_FLAGS_PASS;
883
884        /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags>
885        const _ = !0;
886    }
887}
888
889bitflags::bitflags! {
890    /// `IORING_URING_CMD_*` flags for use with [`io_uring_sqe`].
891    #[repr(transparent)]
892    #[derive(Default, Copy, Clone, Eq, PartialEq, Hash, Debug)]
893    pub struct IoringUringCmdFlags: u32 {
894        /// `IORING_URING_CMD_FIXED`
895        const FIXED = sys::IORING_URING_CMD_FIXED;
896
897        /// `IORING_URING_CMD_MASK`
898        const MASK = sys::IORING_URING_CMD_MASK;
899
900        /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags>
901        const _ = !0;
902    }
903}
904
905bitflags::bitflags! {
906    /// `IORING_ASYNC_CANCEL_*` flags for use with [`io_uring_sqe`].
907    #[repr(transparent)]
908    #[derive(Default, Copy, Clone, Eq, PartialEq, Hash, Debug)]
909    pub struct IoringAsyncCancelFlags: u32 {
910        /// `IORING_ASYNC_CANCEL_ALL`
911        const ALL = sys::IORING_ASYNC_CANCEL_ALL;
912
913        /// `IORING_ASYNC_CANCEL_FD`
914        const FD = sys::IORING_ASYNC_CANCEL_FD;
915
916        /// `IORING_ASYNC_CANCEL_FD`
917        const ANY = sys::IORING_ASYNC_CANCEL_ANY;
918
919        /// `IORING_ASYNC_CANCEL_FD`
920        const FD_FIXED = sys::IORING_ASYNC_CANCEL_FD_FIXED;
921
922        /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags>
923        const _ = !0;
924    }
925}
926
927bitflags::bitflags! {
928    /// `IORING_FIXED_FD_*` flags for use with [`io_uring_sqe`].
929    #[repr(transparent)]
930    #[derive(Default, Copy, Clone, Eq, PartialEq, Hash, Debug)]
931    pub struct IoringFixedFdFlags: u32 {
932        /// `IORING_FIXED_FD_NO_CLOEXEC`
933        const NO_CLOEXEC = sys::IORING_FIXED_FD_NO_CLOEXEC;
934
935        /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags>
936        const _ = !0;
937    }
938}
939
940bitflags::bitflags! {
941    /// `IORING_FEAT_*` flags for use with [`io_uring_params`].
942    #[repr(transparent)]
943    #[derive(Default, Copy, Clone, Eq, PartialEq, Hash, Debug)]
944    pub struct IoringFeatureFlags: u32 {
945        /// `IORING_FEAT_CQE_SKIP`
946        const CQE_SKIP = sys::IORING_FEAT_CQE_SKIP;
947
948        /// `IORING_FEAT_CUR_PERSONALITY`
949        const CUR_PERSONALITY = sys::IORING_FEAT_CUR_PERSONALITY;
950
951        /// `IORING_FEAT_EXT_ARG`
952        const EXT_ARG = sys::IORING_FEAT_EXT_ARG;
953
954        /// `IORING_FEAT_FAST_POLL`
955        const FAST_POLL = sys::IORING_FEAT_FAST_POLL;
956
957        /// `IORING_FEAT_NATIVE_WORKERS`
958        const NATIVE_WORKERS = sys::IORING_FEAT_NATIVE_WORKERS;
959
960        /// `IORING_FEAT_NODROP`
961        const NODROP = sys::IORING_FEAT_NODROP;
962
963        /// `IORING_FEAT_POLL_32BITS`
964        const POLL_32BITS = sys::IORING_FEAT_POLL_32BITS;
965
966        /// `IORING_FEAT_RSRC_TAGS`
967        const RSRC_TAGS = sys::IORING_FEAT_RSRC_TAGS;
968
969        /// `IORING_FEAT_RW_CUR_POS`
970        const RW_CUR_POS = sys::IORING_FEAT_RW_CUR_POS;
971
972        /// `IORING_FEAT_SINGLE_MMAP`
973        const SINGLE_MMAP = sys::IORING_FEAT_SINGLE_MMAP;
974
975        /// `IORING_FEAT_SQPOLL_NONFIXED`
976        const SQPOLL_NONFIXED = sys::IORING_FEAT_SQPOLL_NONFIXED;
977
978        /// `IORING_FEAT_SUBMIT_STABLE`
979        const SUBMIT_STABLE = sys::IORING_FEAT_SUBMIT_STABLE;
980
981        /// `IORING_FEAT_LINKED_FILE`
982        const LINKED_FILE = sys::IORING_FEAT_LINKED_FILE;
983
984        /// `IORING_FEAT_REG_REG_RING`
985        const REG_REG_RING = sys::IORING_FEAT_REG_REG_RING;
986
987        /// `IORING_FEAT_RECVSEND_BUNDLE`
988        const RECVSEND_BUNDLE = sys::IORING_FEAT_RECVSEND_BUNDLE;
989
990        /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags>
991        const _ = !0;
992    }
993}
994
995bitflags::bitflags! {
996    /// `IO_URING_OP_*` flags for use with [`io_uring_probe_op`].
997    #[repr(transparent)]
998    #[derive(Default, Copy, Clone, Eq, PartialEq, Hash, Debug)]
999    pub struct IoringOpFlags: u16 {
1000        /// `IO_URING_OP_SUPPORTED`
1001        const SUPPORTED = sys::IO_URING_OP_SUPPORTED as _;
1002
1003        /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags>
1004        const _ = !0;
1005    }
1006}
1007
1008bitflags::bitflags! {
1009    /// `IORING_RSRC_*` flags for use with [`io_uring_rsrc_register`].
1010    #[repr(transparent)]
1011    #[derive(Default, Copy, Clone, Eq, PartialEq, Hash, Debug)]
1012    pub struct IoringRsrcFlags: u32 {
1013        /// `IORING_RSRC_REGISTER_SPARSE`
1014        const REGISTER_SPARSE = sys::IORING_RSRC_REGISTER_SPARSE as _;
1015
1016        /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags>
1017        const _ = !0;
1018    }
1019}
1020
1021bitflags::bitflags! {
1022    /// `IORING_SQ_*` flags.
1023    #[repr(transparent)]
1024    #[derive(Default, Copy, Clone, Eq, PartialEq, Hash, Debug)]
1025    pub struct IoringSqFlags: u32 {
1026        /// `IORING_SQ_NEED_WAKEUP`
1027        const NEED_WAKEUP = sys::IORING_SQ_NEED_WAKEUP;
1028
1029        /// `IORING_SQ_CQ_OVERFLOW`
1030        const CQ_OVERFLOW = sys::IORING_SQ_CQ_OVERFLOW;
1031
1032        /// `IORING_SQ_TASKRUN`
1033        const TASKRUN = sys::IORING_SQ_TASKRUN;
1034
1035        /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags>
1036        const _ = !0;
1037    }
1038}
1039
1040bitflags::bitflags! {
1041    /// `IORING_CQ_*` flags.
1042    #[repr(transparent)]
1043    #[derive(Default, Copy, Clone, Eq, PartialEq, Hash, Debug)]
1044    pub struct IoringCqFlags: u32 {
1045        /// `IORING_CQ_EVENTFD_DISABLED`
1046        const EVENTFD_DISABLED = sys::IORING_CQ_EVENTFD_DISABLED;
1047
1048        /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags>
1049        const _ = !0;
1050    }
1051}
1052
1053bitflags::bitflags! {
1054    /// `IORING_POLL_*` flags.
1055    #[repr(transparent)]
1056    #[derive(Default, Copy, Clone, Eq, PartialEq, Hash, Debug)]
1057    pub struct IoringPollFlags: u32 {
1058        /// `IORING_POLL_ADD_MULTI`
1059        const ADD_MULTI = sys::IORING_POLL_ADD_MULTI;
1060
1061        /// `IORING_POLL_UPDATE_EVENTS`
1062        const UPDATE_EVENTS = sys::IORING_POLL_UPDATE_EVENTS;
1063
1064        /// `IORING_POLL_UPDATE_USER_DATA`
1065        const UPDATE_USER_DATA = sys::IORING_POLL_UPDATE_USER_DATA;
1066
1067        /// `IORING_POLL_ADD_LEVEL`
1068        const ADD_LEVEL = sys::IORING_POLL_ADD_LEVEL;
1069
1070        /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags>
1071        const _ = !0;
1072    }
1073}
1074
1075bitflags::bitflags! {
1076    /// send/sendmsg flags (`sqe.ioprio`)
1077    #[repr(transparent)]
1078    #[derive(Default, Copy, Clone, Eq, PartialEq, Hash, Debug)]
1079    pub struct IoringSendFlags: u16 {
1080        /// `IORING_RECVSEND_POLL_FIRST`.
1081        ///
1082        /// See also [`IoringRecvFlags::POLL_FIRST`].
1083        const POLL_FIRST = sys::IORING_RECVSEND_POLL_FIRST as _;
1084
1085        /// `IORING_RECVSEND_FIXED_BUF`
1086        ///
1087        /// See also [`IoringRecvFlags::FIXED_BUF`].
1088        const FIXED_BUF = sys::IORING_RECVSEND_FIXED_BUF as _;
1089
1090        /// `IORING_SEND_ZC_REPORT_USAGE` (since Linux 6.2)
1091        const ZC_REPORT_USAGE = sys::IORING_SEND_ZC_REPORT_USAGE as _;
1092
1093        /// `IORING_RECVSEND_BUNDLE`
1094        ///
1095        /// See also [`IoringRecvFlags::BUNDLE`].
1096        const BUNDLE = sys::IORING_RECVSEND_BUNDLE as _;
1097
1098        /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags>
1099        const _ = !0;
1100    }
1101}
1102
1103bitflags::bitflags! {
1104    /// recv/recvmsg flags (`sqe.ioprio`)
1105    #[repr(transparent)]
1106    #[derive(Default, Copy, Clone, Eq, PartialEq, Hash, Debug)]
1107    pub struct IoringRecvFlags: u16 {
1108        /// `IORING_RECVSEND_POLL_FIRST`
1109        ///
1110        /// See also [`IoringSendFlags::POLL_FIRST`].
1111        const POLL_FIRST = sys::IORING_RECVSEND_POLL_FIRST as _;
1112
1113        /// `IORING_RECV_MULTISHOT`
1114        const MULTISHOT = sys::IORING_RECV_MULTISHOT as _;
1115
1116        /// `IORING_RECVSEND_FIXED_BUF`
1117        ///
1118        /// See also [`IoringSendFlags::FIXED_BUF`].
1119        const FIXED_BUF = sys::IORING_RECVSEND_FIXED_BUF as _;
1120
1121        /// `IORING_RECVSEND_BUNDLE`
1122        ///
1123        /// See also [`IoringSendFlags::BUNDLE`].
1124        const BUNDLE = sys::IORING_RECVSEND_BUNDLE as _;
1125
1126        /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags>
1127        const _ = !0;
1128    }
1129}
1130
1131bitflags::bitflags! {
1132    /// accept flags (`sqe.ioprio`)
1133    #[repr(transparent)]
1134    #[derive(Default, Copy, Clone, Eq, PartialEq, Hash, Debug)]
1135    pub struct IoringAcceptFlags: u16 {
1136        /// `IORING_ACCEPT_MULTISHOT`
1137        const MULTISHOT = sys::IORING_ACCEPT_MULTISHOT as _;
1138
1139        /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags>
1140        const _ = !0;
1141    }
1142}
1143
1144bitflags::bitflags! {
1145    /// recvmsg out flags
1146    #[repr(transparent)]
1147    #[derive(Default, Copy, Clone, Eq, PartialEq, Hash, Debug)]
1148    pub struct RecvmsgOutFlags: u32 {
1149        /// `MSG_EOR`
1150        const EOR = net::MSG_EOR;
1151
1152        /// `MSG_TRUNC`
1153        const TRUNC = net::MSG_TRUNC;
1154
1155        /// `MSG_CTRUNC`
1156        const CTRUNC = net::MSG_CTRUNC;
1157
1158        /// `MSG_OOB`
1159        const OOB = net::MSG_OOB;
1160
1161        /// `MSG_ERRQUEUE`
1162        const ERRQUEUE = net::MSG_ERRQUEUE;
1163
1164        /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags>
1165        const _ = !0;
1166    }
1167}
1168
1169#[allow(missing_docs)]
1170pub const IORING_CQE_BUFFER_SHIFT: u32 = sys::IORING_CQE_BUFFER_SHIFT as _;
1171#[allow(missing_docs)]
1172pub const IORING_FILE_INDEX_ALLOC: i32 = sys::IORING_FILE_INDEX_ALLOC as _;
1173
1174// Re-export these as `u64`, which is the `offset` type in `rustix::io::mmap`.
1175#[allow(missing_docs)]
1176pub const IORING_OFF_SQ_RING: u64 = sys::IORING_OFF_SQ_RING as _;
1177#[allow(missing_docs)]
1178pub const IORING_OFF_CQ_RING: u64 = sys::IORING_OFF_CQ_RING as _;
1179#[allow(missing_docs)]
1180pub const IORING_OFF_SQES: u64 = sys::IORING_OFF_SQES as _;
1181
1182/// `IORING_REGISTER_FILES_SKIP`
1183// SAFETY: `IORING_REGISTER_FILES_SKIP` is a reserved value that is never
1184// dynamically allocated, so it'll remain valid for the duration of
1185// `'static`.
1186pub const IORING_REGISTER_FILES_SKIP: BorrowedFd<'static> =
1187    unsafe { BorrowedFd::<'static>::borrow_raw(sys::IORING_REGISTER_FILES_SKIP as RawFd) };
1188
1189/// `IORING_NOTIF_USAGE_ZC_COPIED` (since Linux 6.2)
1190pub const IORING_NOTIF_USAGE_ZC_COPIED: i32 = sys::IORING_NOTIF_USAGE_ZC_COPIED as _;
1191
1192/// A pointer in the io_uring API.
1193///
1194/// `io_uring`'s native API represents pointers as `u64` values. In order to
1195/// preserve strict-provenance, use a `*mut c_void`. On platforms where
1196/// pointers are narrower than 64 bits, this requires additional padding.
1197#[repr(C)]
1198#[cfg_attr(any(target_arch = "arm", target_arch = "powerpc"), repr(align(8)))]
1199#[derive(Copy, Clone)]
1200#[non_exhaustive]
1201pub struct io_uring_ptr {
1202    #[cfg(all(target_pointer_width = "32", target_endian = "big"))]
1203    #[doc(hidden)]
1204    pub __pad32: u32,
1205    #[cfg(all(target_pointer_width = "16", target_endian = "big"))]
1206    #[doc(hidden)]
1207    pub __pad16: u16,
1208
1209    /// The pointer value.
1210    pub ptr: *mut c_void,
1211
1212    #[cfg(all(target_pointer_width = "16", target_endian = "little"))]
1213    #[doc(hidden)]
1214    pub __pad16: u16,
1215    #[cfg(all(target_pointer_width = "32", target_endian = "little"))]
1216    #[doc(hidden)]
1217    pub __pad32: u32,
1218}
1219
1220impl io_uring_ptr {
1221    /// Construct a null `io_uring_ptr`.
1222    #[inline]
1223    pub const fn null() -> Self {
1224        Self::new(null_mut())
1225    }
1226
1227    /// Construct a new `io_uring_ptr`.
1228    #[inline]
1229    pub const fn new(ptr: *mut c_void) -> Self {
1230        Self {
1231            ptr,
1232
1233            #[cfg(target_pointer_width = "16")]
1234            __pad16: 0,
1235            #[cfg(any(target_pointer_width = "16", target_pointer_width = "32"))]
1236            __pad32: 0,
1237        }
1238    }
1239}
1240
1241impl From<*mut c_void> for io_uring_ptr {
1242    #[inline]
1243    fn from(ptr: *mut c_void) -> Self {
1244        Self::new(ptr)
1245    }
1246}
1247
1248impl PartialEq for io_uring_ptr {
1249    #[inline]
1250    fn eq(&self, other: &Self) -> bool {
1251        self.ptr.eq(&other.ptr)
1252    }
1253}
1254
1255impl Eq for io_uring_ptr {}
1256
1257#[allow(clippy::non_canonical_partial_ord_impl)]
1258impl PartialOrd for io_uring_ptr {
1259    #[inline]
1260    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
1261        self.ptr.partial_cmp(&other.ptr)
1262    }
1263}
1264
1265impl Ord for io_uring_ptr {
1266    #[inline]
1267    fn cmp(&self, other: &Self) -> Ordering {
1268        self.ptr.cmp(&other.ptr)
1269    }
1270}
1271
1272impl Hash for io_uring_ptr {
1273    #[inline]
1274    fn hash<H: Hasher>(&self, state: &mut H) {
1275        self.ptr.hash(state)
1276    }
1277}
1278
1279impl Default for io_uring_ptr {
1280    #[inline]
1281    fn default() -> Self {
1282        Self::null()
1283    }
1284}
1285
1286impl core::fmt::Pointer for io_uring_ptr {
1287    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
1288        self.ptr.fmt(f)
1289    }
1290}
1291
1292impl core::fmt::Debug for io_uring_ptr {
1293    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
1294        self.ptr.fmt(f)
1295    }
1296}
1297
1298/// User data in the io_uring API.
1299///
1300/// `io_uring`'s native API represents `user_data` fields as `u64` values. In
1301/// order to preserve strict-provenance, use a union which allows users to
1302/// optionally store pointers.
1303#[repr(C)]
1304#[derive(Copy, Clone)]
1305pub union io_uring_user_data {
1306    /// An arbitrary `u64`.
1307    pub u64_: u64,
1308
1309    /// A pointer.
1310    pub ptr: io_uring_ptr,
1311}
1312
1313impl io_uring_user_data {
1314    /// Create a zero-initialized `Self`.
1315    pub const fn zeroed() -> Self {
1316        // Initialize the `u64_` field, which is the size of the full union.
1317        // This can use `core::mem::zeroed` in Rust 1.75.
1318        Self { u64_: 0 }
1319    }
1320
1321    /// Return the `u64` value.
1322    #[inline]
1323    pub const fn u64_(self) -> u64 {
1324        // SAFETY: All the fields have the same underlying representation.
1325        unsafe { self.u64_ }
1326    }
1327
1328    /// Create a `Self` from a `u64` value.
1329    #[inline]
1330    pub const fn from_u64(u64_: u64) -> Self {
1331        Self { u64_ }
1332    }
1333
1334    /// Return the `ptr` pointer value.
1335    #[inline]
1336    pub const fn ptr(self) -> *mut c_void {
1337        // SAFETY: All the fields have the same underlying representation.
1338        unsafe { self.ptr }.ptr
1339    }
1340
1341    /// Create a `Self` from a pointer value.
1342    #[inline]
1343    pub const fn from_ptr(ptr: *mut c_void) -> Self {
1344        Self {
1345            ptr: io_uring_ptr::new(ptr),
1346        }
1347    }
1348}
1349
1350impl From<u64> for io_uring_user_data {
1351    #[inline]
1352    fn from(u64_: u64) -> Self {
1353        Self::from_u64(u64_)
1354    }
1355}
1356
1357impl From<*mut c_void> for io_uring_user_data {
1358    #[inline]
1359    fn from(ptr: *mut c_void) -> Self {
1360        Self::from_ptr(ptr)
1361    }
1362}
1363
1364impl PartialEq for io_uring_user_data {
1365    #[inline]
1366    fn eq(&self, other: &Self) -> bool {
1367        // SAFETY: `io_uring_ptr` and `u64` have the same layout.
1368        unsafe { self.u64_.eq(&other.u64_) }
1369    }
1370}
1371
1372impl Eq for io_uring_user_data {}
1373
1374#[allow(clippy::non_canonical_partial_ord_impl)]
1375impl PartialOrd for io_uring_user_data {
1376    #[inline]
1377    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
1378        // SAFETY: `io_uring_ptr` and `u64` have the same layout.
1379        unsafe { self.u64_.partial_cmp(&other.u64_) }
1380    }
1381}
1382
1383impl Ord for io_uring_user_data {
1384    #[inline]
1385    fn cmp(&self, other: &Self) -> Ordering {
1386        // SAFETY: `io_uring_ptr` and `u64` have the same layout.
1387        unsafe { self.u64_.cmp(&other.u64_) }
1388    }
1389}
1390
1391impl Hash for io_uring_user_data {
1392    #[inline]
1393    fn hash<H: Hasher>(&self, state: &mut H) {
1394        // SAFETY: `io_uring_ptr` and `u64` have the same layout.
1395        unsafe { self.u64_.hash(state) }
1396    }
1397}
1398
1399impl Default for io_uring_user_data {
1400    #[inline]
1401    fn default() -> Self {
1402        Self::zeroed()
1403    }
1404}
1405
1406impl core::fmt::Debug for io_uring_user_data {
1407    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
1408        // SAFETY: Just format as a `u64`, since formatting doesn't preserve
1409        // provenance, and we don't have a discriminant.
1410        unsafe { self.u64_.fmt(f) }
1411    }
1412}
1413
1414/// An io_uring Submission Queue Entry.
1415#[allow(missing_docs)]
1416#[repr(C)]
1417#[derive(Copy, Clone, Default)]
1418pub struct io_uring_sqe {
1419    pub opcode: IoringOp,
1420    pub flags: IoringSqeFlags,
1421    pub ioprio: ioprio_union,
1422    pub fd: RawFd,
1423    pub off_or_addr2: off_or_addr2_union,
1424    pub addr_or_splice_off_in: addr_or_splice_off_in_union,
1425    pub len: len_union,
1426    pub op_flags: op_flags_union,
1427    pub user_data: io_uring_user_data,
1428    pub buf: buf_union,
1429    pub personality: u16,
1430    pub splice_fd_in_or_file_index_or_addr_len: splice_fd_in_or_file_index_or_addr_len_union,
1431    pub addr3_or_cmd: addr3_or_cmd_union,
1432}
1433
1434#[allow(missing_docs)]
1435#[repr(C)]
1436#[derive(Copy, Clone)]
1437pub union ioprio_union {
1438    pub recv_flags: IoringRecvFlags,
1439    pub send_flags: IoringSendFlags,
1440    pub accept_flags: IoringAcceptFlags,
1441    pub ioprio: u16,
1442}
1443
1444#[allow(missing_docs)]
1445#[repr(C)]
1446#[derive(Copy, Clone)]
1447pub union len_union {
1448    pub poll_flags: IoringPollFlags,
1449    pub len: u32,
1450}
1451
1452#[allow(missing_docs)]
1453#[repr(C)]
1454#[derive(Copy, Clone)]
1455pub union addr3_or_cmd_union {
1456    pub addr3: addr3_struct,
1457    pub cmd: [u8; 0],
1458}
1459
1460#[allow(missing_docs)]
1461#[repr(C)]
1462#[derive(Copy, Clone, Default)]
1463#[non_exhaustive]
1464pub struct addr3_struct {
1465    pub addr3: u64,
1466    #[doc(hidden)]
1467    pub __pad2: [u64; 1],
1468}
1469
1470#[allow(missing_docs)]
1471#[repr(C)]
1472#[derive(Copy, Clone)]
1473pub union off_or_addr2_union {
1474    pub off: u64,
1475    pub addr2: io_uring_ptr,
1476    pub cmd_op: cmd_op_struct,
1477    pub user_data: io_uring_user_data,
1478}
1479
1480#[allow(missing_docs)]
1481#[repr(C)]
1482#[derive(Copy, Clone)]
1483#[non_exhaustive]
1484pub struct cmd_op_struct {
1485    pub cmd_op: u32,
1486    #[doc(hidden)]
1487    pub __pad1: u32,
1488}
1489
1490#[allow(missing_docs)]
1491#[repr(C)]
1492#[derive(Copy, Clone)]
1493pub union addr_or_splice_off_in_union {
1494    pub addr: io_uring_ptr,
1495    pub splice_off_in: u64,
1496    pub msgring_cmd: IoringMsgringCmds,
1497    pub user_data: io_uring_user_data,
1498}
1499
1500#[allow(missing_docs)]
1501#[repr(C)]
1502#[derive(Copy, Clone)]
1503pub union op_flags_union {
1504    pub rw_flags: crate::io::ReadWriteFlags,
1505    pub fsync_flags: IoringFsyncFlags,
1506    pub poll_events: u16,
1507    pub poll32_events: u32,
1508    pub sync_range_flags: u32,
1509    /// `msg_flags` is split into `send_flags` and `recv_flags`.
1510    #[doc(alias = "msg_flags")]
1511    pub send_flags: SendFlags,
1512    /// `msg_flags` is split into `send_flags` and `recv_flags`.
1513    #[doc(alias = "msg_flags")]
1514    pub recv_flags: RecvFlags,
1515    pub timeout_flags: IoringTimeoutFlags,
1516    pub accept_flags: SocketFlags,
1517    pub cancel_flags: IoringAsyncCancelFlags,
1518    pub open_flags: OFlags,
1519    pub statx_flags: AtFlags,
1520    pub fadvise_advice: Advice,
1521    pub splice_flags: SpliceFlags,
1522    pub rename_flags: RenameFlags,
1523    pub unlink_flags: AtFlags,
1524    pub hardlink_flags: AtFlags,
1525    pub xattr_flags: XattrFlags,
1526    pub msg_ring_flags: IoringMsgringFlags,
1527    pub uring_cmd_flags: IoringUringCmdFlags,
1528    pub futex_flags: FutexWaitvFlags,
1529    pub install_fd_flags: IoringFixedFdFlags,
1530}
1531
1532#[allow(missing_docs)]
1533#[repr(C, packed)]
1534#[derive(Copy, Clone)]
1535pub union buf_union {
1536    pub buf_index: u16,
1537    pub buf_group: u16,
1538}
1539
1540#[allow(missing_docs)]
1541#[repr(C)]
1542#[derive(Copy, Clone)]
1543pub union splice_fd_in_or_file_index_or_addr_len_union {
1544    pub splice_fd_in: i32,
1545    pub file_index: u32,
1546    pub addr_len: addr_len_struct,
1547}
1548
1549#[allow(missing_docs)]
1550#[repr(C)]
1551#[derive(Copy, Clone)]
1552#[non_exhaustive]
1553pub struct addr_len_struct {
1554    pub addr_len: u16,
1555    #[doc(hidden)]
1556    pub __pad3: [u16; 1],
1557}
1558
1559#[allow(missing_docs)]
1560#[repr(C)]
1561#[derive(Copy, Clone)]
1562#[non_exhaustive]
1563pub struct io_uring_sync_cancel_reg {
1564    pub addr: io_uring_user_data,
1565    pub fd: i32,
1566    pub flags: IoringAsyncCancelFlags,
1567    pub timeout: Timespec,
1568    pub opcode: u8,
1569    #[doc(hidden)]
1570    pub pad: [u8; 7],
1571    #[doc(hidden)]
1572    pub pad2: [u64; 3],
1573}
1574
1575impl Default for io_uring_sync_cancel_reg {
1576    #[inline]
1577    fn default() -> Self {
1578        Self {
1579            addr: Default::default(),
1580            fd: Default::default(),
1581            flags: Default::default(),
1582            timeout: Timespec {
1583                tv_sec: 0,
1584                tv_nsec: 0,
1585            },
1586            opcode: Default::default(),
1587            pad: Default::default(),
1588            pad2: Default::default(),
1589        }
1590    }
1591}
1592
1593/// An io_uring Completion Queue Entry.
1594///
1595/// This does not derive `Copy` or `Clone` because the `big_cqe` field is not
1596/// automatically copyable.
1597#[allow(missing_docs)]
1598#[repr(C)]
1599#[derive(Debug, Default)]
1600pub struct io_uring_cqe {
1601    pub user_data: io_uring_user_data,
1602    pub res: i32,
1603    pub flags: IoringCqeFlags,
1604    pub big_cqe: IncompleteArrayField<u64>,
1605}
1606
1607#[allow(missing_docs)]
1608#[repr(C)]
1609#[derive(Copy, Clone, Default)]
1610#[non_exhaustive]
1611pub struct io_uring_restriction {
1612    pub opcode: IoringRestrictionOp,
1613    pub register_or_sqe_op_or_sqe_flags: register_or_sqe_op_or_sqe_flags_union,
1614    #[doc(hidden)]
1615    pub resv: u8,
1616    #[doc(hidden)]
1617    pub resv2: [u32; 3],
1618}
1619
1620#[allow(missing_docs)]
1621#[repr(C)]
1622#[derive(Copy, Clone)]
1623pub union register_or_sqe_op_or_sqe_flags_union {
1624    pub register_op: IoringRegisterOp,
1625    pub sqe_op: IoringOp,
1626    pub sqe_flags: IoringSqeFlags,
1627}
1628
1629#[allow(missing_docs)]
1630#[repr(C)]
1631#[derive(Debug, Copy, Clone, Default)]
1632#[non_exhaustive]
1633pub struct io_uring_params {
1634    pub sq_entries: u32,
1635    pub cq_entries: u32,
1636    pub flags: IoringSetupFlags,
1637    pub sq_thread_cpu: u32,
1638    pub sq_thread_idle: u32,
1639    pub features: IoringFeatureFlags,
1640    pub wq_fd: RawFd,
1641    #[doc(hidden)]
1642    pub resv: [u32; 3],
1643    pub sq_off: io_sqring_offsets,
1644    pub cq_off: io_cqring_offsets,
1645}
1646
1647#[allow(missing_docs)]
1648#[repr(C)]
1649#[derive(Debug, Copy, Clone, Default)]
1650#[non_exhaustive]
1651pub struct io_sqring_offsets {
1652    pub head: u32,
1653    pub tail: u32,
1654    pub ring_mask: u32,
1655    pub ring_entries: u32,
1656    pub flags: u32,
1657    pub dropped: u32,
1658    pub array: u32,
1659    #[doc(hidden)]
1660    pub resv1: u32,
1661    pub user_addr: io_uring_ptr,
1662}
1663
1664#[allow(missing_docs)]
1665#[repr(C)]
1666#[derive(Debug, Copy, Clone, Default)]
1667#[non_exhaustive]
1668pub struct io_cqring_offsets {
1669    pub head: u32,
1670    pub tail: u32,
1671    pub ring_mask: u32,
1672    pub ring_entries: u32,
1673    pub overflow: u32,
1674    pub cqes: u32,
1675    pub flags: u32,
1676    #[doc(hidden)]
1677    pub resv1: u32,
1678    pub user_addr: io_uring_ptr,
1679}
1680
1681#[allow(missing_docs)]
1682#[repr(C)]
1683#[derive(Debug, Default)]
1684#[non_exhaustive]
1685pub struct io_uring_probe {
1686    pub last_op: IoringOp,
1687    pub ops_len: u8,
1688    #[doc(hidden)]
1689    pub resv: u16,
1690    #[doc(hidden)]
1691    pub resv2: [u32; 3],
1692    pub ops: IncompleteArrayField<io_uring_probe_op>,
1693}
1694
1695#[allow(missing_docs)]
1696#[repr(C)]
1697#[derive(Debug, Copy, Clone, Default)]
1698#[non_exhaustive]
1699pub struct io_uring_probe_op {
1700    pub op: IoringOp,
1701    #[doc(hidden)]
1702    pub resv: u8,
1703    pub flags: IoringOpFlags,
1704    #[doc(hidden)]
1705    pub resv2: u32,
1706}
1707
1708#[allow(missing_docs)]
1709#[repr(C, align(8))]
1710#[derive(Debug, Copy, Clone, Default)]
1711#[non_exhaustive]
1712pub struct io_uring_files_update {
1713    pub offset: u32,
1714    #[doc(hidden)]
1715    pub resv: u32,
1716    pub fds: io_uring_ptr,
1717}
1718
1719#[allow(missing_docs)]
1720#[repr(C, align(8))]
1721#[derive(Debug, Copy, Clone, Default)]
1722#[non_exhaustive]
1723pub struct io_uring_rsrc_register {
1724    pub nr: u32,
1725    pub flags: IoringRsrcFlags,
1726    #[doc(hidden)]
1727    pub resv2: u64,
1728    pub data: io_uring_ptr,
1729    pub tags: io_uring_ptr,
1730}
1731
1732#[allow(missing_docs)]
1733#[repr(C, align(8))]
1734#[derive(Debug, Copy, Clone, Default)]
1735#[non_exhaustive]
1736pub struct io_uring_rsrc_update {
1737    pub offset: u32,
1738    #[doc(hidden)]
1739    pub resv: u32,
1740    pub data: io_uring_ptr,
1741}
1742
1743#[allow(missing_docs)]
1744#[repr(C, align(8))]
1745#[derive(Debug, Copy, Clone, Default)]
1746#[non_exhaustive]
1747pub struct io_uring_rsrc_update2 {
1748    pub offset: u32,
1749    #[doc(hidden)]
1750    pub resv: u32,
1751    pub data: io_uring_ptr,
1752    pub tags: io_uring_ptr,
1753    pub nr: u32,
1754    #[doc(hidden)]
1755    pub resv2: u32,
1756}
1757
1758#[allow(missing_docs)]
1759#[repr(C)]
1760#[derive(Debug, Copy, Clone, Default)]
1761pub struct io_uring_getevents_arg {
1762    pub sigmask: io_uring_ptr,
1763    pub sigmask_sz: u32,
1764    pub min_wait_usec: u32,
1765    pub ts: io_uring_ptr,
1766}
1767
1768#[allow(missing_docs)]
1769#[repr(C)]
1770#[derive(Debug, Default, Copy, Clone)]
1771pub struct io_uring_recvmsg_out {
1772    pub namelen: SocketAddrLen,
1773    pub controllen: u32,
1774    pub payloadlen: u32,
1775    pub flags: RecvmsgOutFlags,
1776}
1777
1778#[allow(missing_docs)]
1779#[repr(C)]
1780#[derive(Debug, Copy, Clone)]
1781pub struct iovec {
1782    pub iov_base: *mut c_void,
1783    pub iov_len: usize,
1784}
1785
1786#[allow(missing_docs)]
1787#[repr(C)]
1788#[derive(Debug, Copy, Clone, Default)]
1789#[non_exhaustive]
1790pub struct open_how {
1791    /// An [`OFlags`] value represented as a `u64`.
1792    pub flags: u64,
1793
1794    /// A [`Mode`] value represented as a `u64`.
1795    pub mode: u64,
1796
1797    pub resolve: ResolveFlags,
1798}
1799
1800impl open_how {
1801    /// Create a zero-initialized `Self`.
1802    pub const fn zeroed() -> Self {
1803        Self {
1804            flags: 0,
1805            mode: 0,
1806            resolve: ResolveFlags::empty(),
1807        }
1808    }
1809}
1810
1811#[allow(missing_docs)]
1812#[repr(C)]
1813#[derive(Debug, Copy, Clone, Default)]
1814#[non_exhaustive]
1815pub struct io_uring_buf_reg {
1816    pub ring_addr: io_uring_ptr,
1817    pub ring_entries: u32,
1818    pub bgid: u16,
1819    pub flags: u16,
1820    #[doc(hidden)]
1821    pub resv: [u64; 3_usize],
1822}
1823
1824#[allow(missing_docs)]
1825#[repr(C)]
1826#[derive(Debug, Copy, Clone, Default)]
1827#[non_exhaustive]
1828pub struct io_uring_buf {
1829    pub addr: io_uring_ptr,
1830    pub len: u32,
1831    pub bid: u16,
1832    #[doc(hidden)]
1833    pub resv: u16,
1834}
1835
1836#[allow(missing_docs)]
1837#[repr(C)]
1838#[derive(Debug, Copy, Clone, Default)]
1839#[non_exhaustive]
1840pub struct buf_ring_tail_struct {
1841    #[doc(hidden)]
1842    pub resv1: u64,
1843    #[doc(hidden)]
1844    pub resv2: u32,
1845    #[doc(hidden)]
1846    pub resv3: u16,
1847    pub tail: u16,
1848}
1849
1850#[allow(missing_docs)]
1851#[repr(C)]
1852#[derive(Debug, Default)]
1853pub struct buf_ring_bufs_struct {
1854    pub bufs: IncompleteArrayField<io_uring_buf>,
1855}
1856
1857#[allow(missing_docs)]
1858#[repr(C)]
1859#[derive(Debug, Default)]
1860pub struct tail_or_bufs_struct {
1861    pub tail: UnionField<buf_ring_tail_struct>,
1862    pub bufs: UnionField<buf_ring_bufs_struct>,
1863    pub union_field: [u64; 2],
1864}
1865
1866#[allow(missing_docs)]
1867#[repr(C)]
1868#[derive(Debug, Default)]
1869pub struct io_uring_buf_ring {
1870    pub tail_or_bufs: tail_or_bufs_struct,
1871}
1872
1873#[allow(missing_docs)]
1874#[repr(C)]
1875#[derive(Debug, Default)]
1876#[non_exhaustive]
1877pub struct io_uring_napi {
1878    pub busy_poll_to: u32,
1879    pub prefer_busy_poll: u8,
1880    pub opcode: u8,
1881    #[doc(hidden)]
1882    pub pad: [u8; 2],
1883    pub op_param: u32,
1884    #[doc(hidden)]
1885    pub resv: u32,
1886}
1887
1888#[allow(missing_docs)]
1889#[repr(C)]
1890#[derive(Debug, Default)]
1891#[non_exhaustive]
1892pub struct io_uring_clone_buffers {
1893    pub src_fd: u32,
1894    pub flags: u32,
1895    pub src_off: u32,
1896    pub dst_off: u32,
1897    pub nr: u32,
1898    #[doc(hidden)]
1899    pub pad: [u32; 3],
1900}
1901
1902#[allow(missing_docs)]
1903#[repr(C)]
1904#[derive(Debug, Default)]
1905#[non_exhaustive]
1906pub struct io_uring_reg_wait {
1907    pub ts: Timespec,
1908    pub min_wait_usec: u32,
1909    pub flags: u32,
1910    pub sigmask: io_uring_ptr,
1911    pub sigmask_sz: u32,
1912    #[doc(hidden)]
1913    pub pad: [u32; 3],
1914    #[doc(hidden)]
1915    pub pad2: [u64; 2],
1916}
1917
1918impl Default for ioprio_union {
1919    #[inline]
1920    fn default() -> Self {
1921        default_union!(ioprio_union, ioprio)
1922    }
1923}
1924
1925impl Default for len_union {
1926    #[inline]
1927    fn default() -> Self {
1928        default_union!(len_union, len)
1929    }
1930}
1931
1932impl Default for off_or_addr2_union {
1933    #[inline]
1934    fn default() -> Self {
1935        default_union!(off_or_addr2_union, off)
1936    }
1937}
1938
1939impl Default for addr_or_splice_off_in_union {
1940    #[inline]
1941    fn default() -> Self {
1942        default_union!(addr_or_splice_off_in_union, splice_off_in)
1943    }
1944}
1945
1946impl Default for addr3_or_cmd_union {
1947    #[inline]
1948    fn default() -> Self {
1949        default_union!(addr3_or_cmd_union, addr3)
1950    }
1951}
1952
1953impl Default for op_flags_union {
1954    #[inline]
1955    fn default() -> Self {
1956        default_union!(op_flags_union, sync_range_flags)
1957    }
1958}
1959
1960impl Default for buf_union {
1961    #[inline]
1962    fn default() -> Self {
1963        default_union!(buf_union, buf_index)
1964    }
1965}
1966
1967impl Default for splice_fd_in_or_file_index_or_addr_len_union {
1968    #[inline]
1969    fn default() -> Self {
1970        default_union!(splice_fd_in_or_file_index_or_addr_len_union, splice_fd_in)
1971    }
1972}
1973
1974impl Default for register_or_sqe_op_or_sqe_flags_union {
1975    #[inline]
1976    fn default() -> Self {
1977        default_union!(register_or_sqe_op_or_sqe_flags_union, sqe_flags)
1978    }
1979}
1980
1981#[cfg(test)]
1982mod tests {
1983    use super::*;
1984    use crate::fd::AsRawFd as _;
1985
1986    /// Check that our custom structs and unions have the same layout as the
1987    /// kernel's versions.
1988    #[test]
1989    fn io_uring_layouts() {
1990        use sys as c;
1991
1992        // `io_uring_ptr` is a replacement for `u64`.
1993        assert_eq_size!(io_uring_ptr, u64);
1994        assert_eq_align!(io_uring_ptr, u64);
1995
1996        // Test that pointers are stored in `io_uring_ptr` in the way that
1997        // io_uring stores them in a `u64`.
1998        unsafe {
1999            const MAGIC: u64 = !0x0123_4567_89ab_cdef;
2000            let ptr = io_uring_ptr::new(MAGIC as usize as *mut c_void);
2001            assert_eq!(ptr.ptr, MAGIC as usize as *mut c_void);
2002            #[cfg(target_pointer_width = "16")]
2003            assert_eq!(ptr.__pad16, 0);
2004            #[cfg(any(target_pointer_width = "16", target_pointer_width = "32"))]
2005            assert_eq!(ptr.__pad32, 0);
2006            let int = core::mem::transmute::<io_uring_ptr, u64>(ptr);
2007            assert_eq!(int, MAGIC as usize as u64);
2008        }
2009
2010        // `io_uring_user_data` is a replacement for `u64`.
2011        assert_eq_size!(io_uring_user_data, u64);
2012        assert_eq_align!(io_uring_user_data, u64);
2013
2014        // Test that `u64`s and pointers are properly stored in
2015        // `io_uring_user_data`.
2016        unsafe {
2017            const MAGIC: u64 = !0x0123_4567_89ab_cdef;
2018            let user_data = io_uring_user_data::from_u64(MAGIC);
2019            assert_eq!(user_data.u64_(), MAGIC);
2020            assert_eq!(
2021                core::mem::transmute::<io_uring_user_data, u64>(user_data),
2022                MAGIC
2023            );
2024            let user_data = io_uring_user_data::from_ptr(MAGIC as usize as *mut c_void);
2025            assert_eq!(user_data.ptr(), MAGIC as usize as *mut c_void);
2026            assert_eq!(
2027                core::mem::transmute::<io_uring_user_data, u64>(user_data),
2028                MAGIC as usize as u64
2029            );
2030        }
2031
2032        check_renamed_type!(off_or_addr2_union, io_uring_sqe__bindgen_ty_1);
2033        check_renamed_type!(addr_or_splice_off_in_union, io_uring_sqe__bindgen_ty_2);
2034        check_renamed_type!(addr3_or_cmd_union, io_uring_sqe__bindgen_ty_6);
2035        check_renamed_type!(op_flags_union, io_uring_sqe__bindgen_ty_3);
2036        check_renamed_type!(buf_union, io_uring_sqe__bindgen_ty_4);
2037        check_renamed_type!(
2038            splice_fd_in_or_file_index_or_addr_len_union,
2039            io_uring_sqe__bindgen_ty_5
2040        );
2041        check_renamed_type!(addr_len_struct, io_uring_sqe__bindgen_ty_5__bindgen_ty_1);
2042        check_renamed_type!(
2043            register_or_sqe_op_or_sqe_flags_union,
2044            io_uring_restriction__bindgen_ty_1
2045        );
2046
2047        check_renamed_type!(addr3_struct, io_uring_sqe__bindgen_ty_6__bindgen_ty_1);
2048        check_renamed_type!(cmd_op_struct, io_uring_sqe__bindgen_ty_1__bindgen_ty_1);
2049
2050        check_type!(io_uring_sqe);
2051        check_struct_field!(io_uring_sqe, opcode);
2052        check_struct_field!(io_uring_sqe, flags);
2053        check_struct_field!(io_uring_sqe, ioprio);
2054        check_struct_field!(io_uring_sqe, fd);
2055        check_struct_renamed_field!(io_uring_sqe, off_or_addr2, __bindgen_anon_1);
2056        check_struct_renamed_field!(io_uring_sqe, addr_or_splice_off_in, __bindgen_anon_2);
2057        check_struct_field!(io_uring_sqe, len);
2058        check_struct_renamed_field!(io_uring_sqe, op_flags, __bindgen_anon_3);
2059        check_struct_field!(io_uring_sqe, user_data);
2060        check_struct_renamed_field!(io_uring_sqe, buf, __bindgen_anon_4);
2061        check_struct_field!(io_uring_sqe, personality);
2062        check_struct_renamed_field!(
2063            io_uring_sqe,
2064            splice_fd_in_or_file_index_or_addr_len,
2065            __bindgen_anon_5
2066        );
2067        check_struct_renamed_field!(io_uring_sqe, addr3_or_cmd, __bindgen_anon_6);
2068
2069        check_type!(io_uring_restriction);
2070        check_struct_field!(io_uring_restriction, opcode);
2071        check_struct_renamed_field!(
2072            io_uring_restriction,
2073            register_or_sqe_op_or_sqe_flags,
2074            __bindgen_anon_1
2075        );
2076        check_struct_field!(io_uring_restriction, resv);
2077        check_struct_field!(io_uring_restriction, resv2);
2078
2079        check_struct!(io_uring_cqe, user_data, res, flags, big_cqe);
2080        check_struct!(
2081            io_uring_params,
2082            sq_entries,
2083            cq_entries,
2084            flags,
2085            sq_thread_cpu,
2086            sq_thread_idle,
2087            features,
2088            wq_fd,
2089            resv,
2090            sq_off,
2091            cq_off
2092        );
2093        check_struct!(
2094            io_sqring_offsets,
2095            head,
2096            tail,
2097            ring_mask,
2098            ring_entries,
2099            flags,
2100            dropped,
2101            array,
2102            resv1,
2103            user_addr
2104        );
2105        check_struct!(
2106            io_cqring_offsets,
2107            head,
2108            tail,
2109            ring_mask,
2110            ring_entries,
2111            overflow,
2112            cqes,
2113            flags,
2114            resv1,
2115            user_addr
2116        );
2117        check_struct!(io_uring_recvmsg_out, namelen, controllen, payloadlen, flags);
2118        check_struct!(io_uring_probe, last_op, ops_len, resv, resv2, ops);
2119        check_struct!(io_uring_probe_op, op, resv, flags, resv2);
2120        check_struct!(io_uring_files_update, offset, resv, fds);
2121        check_struct!(io_uring_rsrc_register, nr, flags, resv2, data, tags);
2122        check_struct!(io_uring_rsrc_update, offset, resv, data);
2123        check_struct!(io_uring_rsrc_update2, offset, resv, data, tags, nr, resv2);
2124        check_struct!(
2125            io_uring_getevents_arg,
2126            sigmask,
2127            sigmask_sz,
2128            min_wait_usec,
2129            ts
2130        );
2131        check_struct!(iovec, iov_base, iov_len);
2132        check_struct!(open_how, flags, mode, resolve);
2133        check_struct!(io_uring_buf_reg, ring_addr, ring_entries, bgid, flags, resv);
2134        check_struct!(io_uring_buf, addr, len, bid, resv);
2135        check_struct!(
2136            io_uring_sync_cancel_reg,
2137            addr,
2138            fd,
2139            flags,
2140            timeout,
2141            opcode,
2142            pad,
2143            pad2
2144        );
2145
2146        check_renamed_type!(tail_or_bufs_struct, io_uring_buf_ring__bindgen_ty_1);
2147        check_renamed_type!(
2148            buf_ring_tail_struct,
2149            io_uring_buf_ring__bindgen_ty_1__bindgen_ty_1
2150        );
2151        check_renamed_type!(
2152            buf_ring_bufs_struct,
2153            io_uring_buf_ring__bindgen_ty_1__bindgen_ty_2
2154        );
2155        check_struct_renamed_field!(io_uring_buf_ring, tail_or_bufs, __bindgen_anon_1);
2156
2157        check_struct!(
2158            io_uring_napi,
2159            busy_poll_to,
2160            prefer_busy_poll,
2161            opcode,
2162            pad,
2163            op_param,
2164            resv
2165        );
2166        check_struct!(
2167            io_uring_clone_buffers,
2168            src_fd,
2169            flags,
2170            src_off,
2171            dst_off,
2172            nr,
2173            pad
2174        );
2175        check_struct!(
2176            io_uring_reg_wait,
2177            ts,
2178            min_wait_usec,
2179            flags,
2180            sigmask,
2181            sigmask_sz,
2182            pad,
2183            pad2
2184        );
2185
2186        check_renamed_struct!(
2187            MsgHdr,
2188            msghdr,
2189            msg_name,
2190            msg_namelen,
2191            msg_iov,
2192            msg_iovlen,
2193            msg_control,
2194            msg_controllen,
2195            msg_flags
2196        );
2197    }
2198
2199    #[test]
2200    fn test_io_uring_register_files_skip() {
2201        use crate::backend::c;
2202        assert!(IORING_REGISTER_FILES_SKIP.as_raw_fd() != -1);
2203        assert!(IORING_REGISTER_FILES_SKIP.as_raw_fd() != c::STDIN_FILENO);
2204        assert!(IORING_REGISTER_FILES_SKIP.as_raw_fd() != c::STDOUT_FILENO);
2205        assert!(IORING_REGISTER_FILES_SKIP.as_raw_fd() != c::STDERR_FILENO);
2206    }
2207}