Skip to main content

liburing_rs/
lib.rs

1#![no_std]
2#![allow(unsafe_op_in_unsafe_fn, non_snake_case)]
3#![warn(clippy::pedantic)]
4#![allow(clippy::missing_safety_doc,
5         clippy::cast_sign_loss,
6         clippy::similar_names,
7         clippy::cast_possible_truncation,
8         clippy::cast_possible_wrap,
9         clippy::cast_ptr_alignment,
10         clippy::used_underscore_items,
11         clippy::unnecessary_cast,
12         clippy::doc_markdown)]
13#![doc = include_str!("../README.md")]
14
15#[doc(hidden)]
16mod uring;
17
18use core::{
19    ffi::{c_char, c_int, c_longlong, c_uint, c_ulong, c_ushort, c_void},
20    mem::{self, zeroed},
21    ptr,
22    sync::atomic::{
23        AtomicU16, AtomicU32,
24        Ordering::{self, Acquire, Relaxed, Release},
25    },
26    time::Duration,
27};
28
29#[doc(hidden)]
30pub use uring::*;
31
32#[doc = include_str!("../docs/io_uring.md")]
33pub use uring::io_uring;
34
35#[doc = include_str!("../docs/io_uring_enter.md")]
36pub use uring::io_uring_enter;
37
38#[doc = include_str!("../docs/io_uring_enter.md")]
39pub use uring::io_uring_enter2;
40
41#[doc = include_str!("../docs/io_uring_setup.md")]
42pub use uring::io_uring_setup;
43
44#[doc = include_str!("../docs/io_uring_register.md")]
45pub use uring::io_uring_register;
46
47#[doc = include_str!("../docs/io_uring_submit_and_wait.md")]
48pub use uring::io_uring_submit_and_wait;
49
50#[doc = include_str!("../docs/io_uring_check_version.md")]
51pub use uring::io_uring_check_version;
52
53#[doc = include_str!("../docs/io_uring_check_version.md")]
54pub use uring::io_uring_major_version;
55
56#[doc = include_str!("../docs/io_uring_check_version.md")]
57pub use uring::io_uring_minor_version;
58
59#[doc = include_str!("../docs/io_uring_clone_buffers.md")]
60pub use uring::io_uring_clone_buffers;
61
62#[doc = include_str!("../docs/io_uring_clone_buffers.md")]
63pub use uring::io_uring_clone_buffers_offset;
64
65#[doc = include_str!("../docs/io_uring_clone_buffers.md")]
66pub use uring::__io_uring_clone_buffers;
67
68#[doc = include_str!("../docs/io_uring_clone_buffers.md")]
69pub use uring::__io_uring_clone_buffers_offset;
70
71#[doc = include_str!("../docs/io_uring_close_ring_fd.md")]
72pub use uring::io_uring_close_ring_fd;
73
74#[doc = include_str!("../docs/io_uring_enable_rings.md")]
75pub use uring::io_uring_enable_rings;
76
77#[doc = include_str!("../docs/io_uring_free_buf_ring.md")]
78pub use uring::io_uring_free_buf_ring;
79
80#[doc = include_str!("../docs/io_uring_free_probe.md")]
81pub use uring::io_uring_free_probe;
82
83#[doc = include_str!("../docs/io_uring_get_events.md")]
84pub use uring::io_uring_get_events;
85
86#[doc = include_str!("../docs/io_uring_get_probe.md")]
87pub use uring::io_uring_get_probe;
88
89#[doc = include_str!("../docs/io_uring_get_probe_ring.md")]
90pub use uring::io_uring_get_probe_ring;
91
92#[doc = include_str!("../docs/io_uring_peek_batch_cqe.md")]
93pub use uring::io_uring_peek_batch_cqe;
94
95#[doc = include_str!("../docs/io_uring_queue_exit.md")]
96pub use uring::io_uring_queue_exit;
97
98#[doc = include_str!("../docs/io_uring_queue_init.md")]
99pub use uring::io_uring_queue_init;
100
101#[doc = include_str!("../docs/io_uring_queue_init_mem.md")]
102pub use uring::io_uring_queue_init_mem;
103
104#[doc = include_str!("../docs/io_uring_queue_init_params.md")]
105pub use uring::io_uring_queue_init_params;
106
107#[doc = include_str!("../docs/io_uring_queue_mmap.md")]
108pub use uring::io_uring_queue_mmap;
109
110#[doc = include_str!("../docs/io_uring_register_bpf_filter.md")]
111pub use uring::io_uring_register_bpf_filter;
112
113#[doc = include_str!("../docs/io_uring_register_bpf_filter_task.md")]
114pub use uring::io_uring_register_bpf_filter_task;
115
116#[doc = include_str!("../docs/io_uring_register_buf_ring.md")]
117pub use uring::io_uring_register_buf_ring;
118
119#[doc = include_str!("../docs/io_uring_register_buffers.md")]
120pub use uring::io_uring_register_buffers;
121
122#[doc = include_str!("../docs/io_uring_register_buffers_sparse.md")]
123pub use uring::io_uring_register_buffers_sparse;
124
125#[doc = include_str!("../docs/io_uring_register_buffers_tags.md")]
126pub use uring::io_uring_register_buffers_tags;
127
128#[doc = include_str!("../docs/io_uring_register_buffers_update_tag.md")]
129pub use uring::io_uring_register_buffers_update_tag;
130
131#[doc = include_str!("../docs/io_uring_register_clock.md")]
132pub use uring::io_uring_register_clock;
133
134#[doc = include_str!("../docs/io_uring_register_eventfd.md")]
135pub use uring::io_uring_register_eventfd;
136
137#[doc = include_str!("../docs/io_uring_register_eventfd_async.md")]
138pub use uring::io_uring_register_eventfd_async;
139
140#[doc = include_str!("../docs/io_uring_register_file_alloc_range.md")]
141pub use uring::io_uring_register_file_alloc_range;
142
143#[doc = include_str!("../docs/io_uring_register_files.md")]
144pub use uring::io_uring_register_files;
145
146#[doc = include_str!("../docs/io_uring_register_files_sparse.md")]
147pub use uring::io_uring_register_files_sparse;
148
149#[doc = include_str!("../docs/io_uring_register_files_tags.md")]
150pub use uring::io_uring_register_files_tags;
151
152#[doc = include_str!("../docs/io_uring_register_files_update.md")]
153pub use uring::io_uring_register_files_update;
154
155#[doc = include_str!("../docs/io_uring_register_files_update_tag.md")]
156pub use uring::io_uring_register_files_update_tag;
157
158#[doc = include_str!("../docs/io_uring_register_ifq.md")]
159pub use uring::io_uring_register_ifq;
160
161#[doc = include_str!("../docs/io_uring_register_iowq_max_workers.md")]
162pub use uring::io_uring_register_iowq_max_workers;
163
164#[doc = include_str!("../docs/io_uring_register_napi.md")]
165pub use uring::io_uring_register_napi;
166
167#[doc = include_str!("../docs/io_uring_register_personality.md")]
168pub use uring::io_uring_register_personality;
169
170#[doc = include_str!("../docs/io_uring_register_probe.md")]
171pub use uring::io_uring_register_probe;
172
173#[doc = include_str!("../docs/io_uring_register_query.md")]
174pub use uring::io_uring_register_query;
175
176#[doc = include_str!("../docs/io_uring_register_region.md")]
177pub use uring::io_uring_register_region;
178
179#[doc = include_str!("../docs/io_uring_register_restrictions.md")]
180pub use uring::io_uring_register_restrictions;
181
182#[doc = include_str!("../docs/io_uring_register_ring_fd.md")]
183pub use uring::io_uring_register_ring_fd;
184
185#[doc = include_str!("../docs/io_uring_register_sync_cancel.md")]
186pub use uring::io_uring_register_sync_cancel;
187
188#[doc = include_str!("../docs/io_uring_register_sync_msg.md")]
189pub use uring::io_uring_register_sync_msg;
190
191#[doc = include_str!("../docs/io_uring_register_wait_reg.md")]
192pub use uring::io_uring_register_wait_reg;
193
194#[doc = include_str!("../docs/io_uring_register_zcrx_ctrl.md")]
195pub use uring::io_uring_register_zcrx_ctrl;
196
197#[doc = include_str!("../docs/io_uring_resize_rings.md")]
198pub use uring::io_uring_resize_rings;
199
200#[doc = include_str!("../docs/io_uring_ring_dontfork.md")]
201pub use uring::io_uring_ring_dontfork;
202
203#[doc = include_str!("../docs/io_uring_setup_buf_ring.md")]
204pub use uring::io_uring_setup_buf_ring;
205
206#[doc = include_str!("../docs/io_uring_submit.md")]
207pub use uring::io_uring_submit;
208
209#[doc = include_str!("../docs/io_uring_submit_and_get_events.md")]
210pub use uring::io_uring_submit_and_get_events;
211
212#[doc = include_str!("../docs/io_uring_submit_and_wait_min_timeout.md")]
213pub use uring::io_uring_submit_and_wait_min_timeout;
214
215#[doc = include_str!("../docs/io_uring_submit_and_wait_reg.md")]
216pub use uring::io_uring_submit_and_wait_reg;
217
218#[doc = include_str!("../docs/io_uring_submit_and_wait_timeout.md")]
219pub use uring::io_uring_submit_and_wait_timeout;
220
221#[doc = include_str!("../docs/io_uring_unregister_buf_ring.md")]
222pub use uring::io_uring_unregister_buf_ring;
223
224#[doc = include_str!("../docs/io_uring_unregister_buffers.md")]
225pub use uring::io_uring_unregister_buffers;
226
227#[doc = include_str!("../docs/io_uring_unregister_eventfd.md")]
228pub use uring::io_uring_unregister_eventfd;
229
230#[doc = include_str!("../docs/io_uring_unregister_files.md")]
231pub use uring::io_uring_unregister_files;
232
233#[doc = include_str!("../docs/io_uring_unregister_iowq_aff.md")]
234pub use uring::io_uring_unregister_iowq_aff;
235
236#[doc = include_str!("../docs/io_uring_unregister_napi.md")]
237pub use uring::io_uring_unregister_napi;
238
239#[doc = include_str!("../docs/io_uring_unregister_personality.md")]
240pub use uring::io_uring_unregister_personality;
241
242#[doc = include_str!("../docs/io_uring_unregister_ring_fd.md")]
243pub use uring::io_uring_unregister_ring_fd;
244
245#[doc = include_str!("../docs/io_uring_wait_cqe_timeout.md")]
246pub use uring::io_uring_wait_cqe_timeout;
247
248#[doc = include_str!("../docs/io_uring_wait_cqes.md")]
249pub use uring::io_uring_wait_cqes;
250
251#[doc = include_str!("../docs/io_uring_wait_cqes_min_timeout.md")]
252pub use uring::io_uring_wait_cqes_min_timeout;
253
254#[cfg(feature = "gnu")]
255unsafe extern "C" {
256    #[doc = include_str!("../docs/io_uring_register_iowq_aff.md")]
257    pub unsafe fn io_uring_register_iowq_aff(ring: *mut io_uring, cpusz: usize,
258                                             mask: *const cpu_set_t);
259}
260
261pub const IOSQE_FIXED_FILE: u32 = 1 << IOSQE_FIXED_FILE_BIT;
262pub const IOSQE_IO_DRAIN: u32 = 1 << IOSQE_IO_DRAIN_BIT;
263pub const IOSQE_IO_LINK: u32 = 1 << IOSQE_IO_LINK_BIT;
264pub const IOSQE_IO_HARDLINK: u32 = 1 << IOSQE_IO_HARDLINK_BIT;
265pub const IOSQE_ASYNC: u32 = 1 << IOSQE_ASYNC_BIT;
266pub const IOSQE_BUFFER_SELECT: u32 = 1 << IOSQE_BUFFER_SELECT_BIT;
267pub const IOSQE_CQE_SKIP_SUCCESS: u32 = 1 << IOSQE_CQE_SKIP_SUCCESS_BIT;
268
269const LIBURING_UDATA_TIMEOUT: u64 = u64::MAX;
270
271trait Atomic: Copy
272{
273    unsafe fn store(p: *mut Self, val: Self, order: Ordering);
274    unsafe fn load(p: *mut Self, order: Ordering) -> Self;
275}
276
277impl Atomic for u32
278{
279    #[inline]
280    unsafe fn store(p: *mut u32, val: u32, order: Ordering)
281    {
282        AtomicU32::from_ptr(p).store(val, order);
283    }
284
285    #[inline]
286    unsafe fn load(p: *mut u32, order: Ordering) -> u32
287    {
288        AtomicU32::from_ptr(p).load(order)
289    }
290}
291
292impl Atomic for u16
293{
294    #[inline]
295    unsafe fn store(p: *mut u16, val: u16, order: Ordering)
296    {
297        AtomicU16::from_ptr(p).store(val, order);
298    }
299
300    #[inline]
301    unsafe fn load(p: *mut u16, order: Ordering) -> u16
302    {
303        AtomicU16::from_ptr(p).load(order)
304    }
305}
306
307unsafe fn io_uring_smp_store_release<T: Atomic>(p: *mut T, v: T)
308{
309    Atomic::store(p, v, Release);
310}
311
312unsafe fn io_uring_smp_load_acquire<T: Atomic>(p: *const T) -> T
313{
314    Atomic::load(p.cast_mut(), Acquire)
315}
316
317unsafe fn IO_URING_READ_ONCE<T: Atomic>(var: *const T) -> T
318{
319    Atomic::load(var.cast_mut(), Relaxed)
320}
321
322unsafe fn IO_URING_WRITE_ONCE<T: Atomic>(var: *mut T, val: T)
323{
324    Atomic::store(var, val, Relaxed);
325}
326
327/*
328 * Library interface
329 */
330
331#[must_use]
332#[inline]
333unsafe fn uring_ptr_to_u64(ptr: *const c_void) -> u64
334{
335    ptr as u64
336}
337
338#[doc = include_str!("../docs/io_uring_opcode_supported.md")]
339#[inline]
340pub unsafe fn io_uring_opcode_supported(p: *mut io_uring_probe, op: c_int) -> c_int
341{
342    if op < 0 || op > (*p).last_op.into() {
343        return 0;
344    }
345
346    i32::from((*(*p).ops.as_ptr().add(op as _)).flags & IO_URING_OP_SUPPORTED as u16 != 0)
347}
348
349/*
350 * Returns the bit shift needed to index the CQ.
351 * This shift is 1 for rings with big CQEs, and 0 for rings with normal CQEs.
352 * CQE `index` can be computed as &cq.cqes[(index & cq.ring_mask) << cqe_shift].
353 */
354#[must_use]
355#[inline]
356pub fn io_uring_cqe_shift_from_flags(flags: c_uint) -> c_uint
357{
358    u32::from(flags & IORING_SETUP_CQE32 != 0)
359}
360
361#[must_use]
362#[inline]
363pub unsafe fn io_uring_cqe_shift(ring: *const io_uring) -> c_uint
364{
365    io_uring_cqe_shift_from_flags((*ring).flags)
366}
367
368#[doc = include_str!("../docs/io_uring_cqe_nr.md")]
369#[must_use]
370#[inline]
371pub unsafe fn io_uring_cqe_nr(cqe: *const io_uring_cqe) -> c_uint
372{
373    let shift = i32::from((*cqe).flags & IORING_CQE_F_32 != 0);
374    1 << shift
375}
376
377#[must_use]
378#[inline]
379pub unsafe fn io_uring_cqe_iter_init(ring: *const io_uring) -> io_uring_cqe_iter
380{
381    io_uring_cqe_iter { cqes: (*ring).cq.cqes,
382                        mask: (*ring).cq.ring_mask,
383                        shift: io_uring_cqe_shift(ring),
384                        head: *(*ring).cq.khead,
385                        /* Acquire ordering ensures tail is loaded before any CQEs */
386                        tail: io_uring_smp_load_acquire((*ring).cq.ktail) }
387}
388
389#[inline]
390pub unsafe fn io_uring_cqe_iter_next(iter: *mut io_uring_cqe_iter, cqe: *mut *mut io_uring_cqe)
391                                     -> bool
392{
393    if (*iter).head == (*iter).tail {
394        return false;
395    }
396
397    let head = (*iter).head;
398    (*iter).head += 1;
399
400    let offset = (head & (*iter).mask) << (*iter).shift;
401    *cqe = (*iter).cqes.add(offset as usize);
402
403    if (*(*cqe)).flags & IORING_CQE_F_32 > 0 {
404        (*iter).head += 1;
405    }
406
407    true
408}
409
410#[doc = include_str!("../docs/io_uring_for_each_cqe.md")]
411pub unsafe fn io_uring_for_each_cqe<F>(ring: *mut io_uring, mut f: F)
412    where F: FnMut(*mut io_uring_cqe)
413{
414    let mut iter = io_uring_cqe_iter_init(ring);
415    let mut cqe = ptr::null_mut::<io_uring_cqe>();
416    while io_uring_cqe_iter_next(&raw mut iter, &raw mut cqe) {
417        f(cqe);
418    }
419}
420
421/*
422 * Must be called after io_uring_for_each_cqe()
423 */
424#[doc = include_str!("../docs/io_uring_cq_advance.md")]
425#[inline]
426pub unsafe fn io_uring_cq_advance(ring: *mut io_uring, nr: c_uint)
427{
428    if nr > 0 {
429        let cq = &raw mut (*ring).cq;
430
431        /*
432         * Ensure that the kernel only sees the new value of the head
433         * index after the CQEs have been read.
434         */
435        io_uring_smp_store_release((*cq).khead, *(*cq).khead + nr);
436    }
437}
438
439/*
440 * Must be called after io_uring_{peek,wait}_cqe() after the cqe has
441 * been processed by the application.
442 */
443#[doc = include_str!("../docs/io_uring_cqe_seen.md")]
444#[inline]
445pub unsafe fn io_uring_cqe_seen(ring: *mut io_uring, cqe: *mut io_uring_cqe)
446{
447    if !cqe.is_null() {
448        io_uring_cq_advance(ring, io_uring_cqe_nr(cqe));
449    }
450}
451
452/*
453 * Command prep helpers
454 */
455
456/*
457 * Associate pointer @data with the sqe, for later retrieval from the cqe
458 * at command completion time with io_uring_cqe_get_data().
459 */
460#[doc = include_str!("../docs/io_uring_sqe_set_data.md")]
461#[inline]
462pub unsafe fn io_uring_sqe_set_data(sqe: *mut io_uring_sqe, data: *mut c_void)
463{
464    (*sqe).user_data = data as u64;
465}
466
467#[doc = include_str!("../docs/io_uring_cqe_get_data.md")]
468#[must_use]
469#[inline]
470pub unsafe fn io_uring_cqe_get_data(cqe: *const io_uring_cqe) -> *mut c_void
471{
472    (*cqe).user_data as *mut c_void
473}
474
475/*
476 * Assign a 64-bit value to this sqe, which can get retrieved at completion
477 * time with io_uring_cqe_get_data64. Just like the non-64 variants, except
478 * these store a 64-bit type rather than a data pointer.
479 */
480#[doc = include_str!("../docs/io_uring_sqe_set_data64.md")]
481#[inline]
482pub unsafe fn io_uring_sqe_set_data64(sqe: *mut io_uring_sqe, data: u64)
483{
484    (*sqe).user_data = data;
485}
486
487#[doc = include_str!("../docs/io_uring_cqe_get_data.md")]
488#[must_use]
489#[inline]
490pub unsafe fn io_uring_cqe_get_data64(cqe: *const io_uring_cqe) -> u64
491{
492    (*cqe).user_data
493}
494
495#[doc = include_str!("../docs/io_uring_sqe_set_flags.md")]
496#[inline]
497pub unsafe fn io_uring_sqe_set_flags(sqe: *mut io_uring_sqe, flags: c_uint)
498{
499    (*sqe).flags = flags as u8;
500}
501
502#[doc = include_str!("../docs/io_uring_sqe_set_buf_group.md")]
503#[inline]
504pub unsafe fn io_uring_sqe_set_buf_group(sqe: *mut io_uring_sqe, bgid: c_int)
505{
506    (*sqe).__liburing_anon_4.buf_group = bgid as u16;
507}
508
509#[inline]
510unsafe fn __io_uring_set_target_fixed_file(sqe: *mut io_uring_sqe, file_index: c_uint)
511{
512    /* 0 means no fixed files, indexes should be encoded as "index + 1" */
513    (*sqe).__liburing_anon_5.file_index = file_index + 1;
514}
515
516#[inline]
517pub unsafe fn io_uring_initialize_sqe(sqe: *mut io_uring_sqe)
518{
519    (*sqe).flags = 0;
520    (*sqe).ioprio = 0;
521    (*sqe).__liburing_anon_3.rw_flags = 0;
522    (*sqe).__liburing_anon_4.buf_index = 0;
523    (*sqe).personality = 0;
524    (*sqe).__liburing_anon_5.file_index = 0;
525    (*sqe).__liburing_anon_6.__liburing_anon_1.as_mut().addr3 = 0;
526    (*sqe).__liburing_anon_6.__liburing_anon_1.as_mut().__pad2[0] = 0;
527}
528
529#[inline]
530pub unsafe fn io_uring_prep_rw(op: c_uint, sqe: *mut io_uring_sqe, fd: c_int, addr: *const c_void,
531                               len: c_uint, offset: __u64)
532{
533    (*sqe).opcode = op as u8;
534    (*sqe).fd = fd;
535    (*sqe).__liburing_anon_1.off = offset;
536    (*sqe).__liburing_anon_2.addr = addr as u64;
537    (*sqe).len = len;
538}
539
540/*
541 * io_uring_prep_splice() - Either @fd_in or @fd_out must be a pipe.
542 *
543 * - If @fd_in refers to a pipe, @off_in is ignored and must be set to -1.
544 *
545 * - If @fd_in does not refer to a pipe and @off_in is -1, then @nbytes are read
546 *   from @fd_in starting from the file offset, which is incremented by the
547 *   number of bytes read.
548 *
549 * - If @fd_in does not refer to a pipe and @off_in is not -1, then the starting
550 *   offset of @fd_in will be @off_in.
551 *
552 * This splice operation can be used to implement sendfile by splicing to an
553 * intermediate pipe first, then splice to the final destination.
554 * In fact, the implementation of sendfile in kernel uses splice internally.
555 *
556 * NOTE that even if fd_in or fd_out refers to a pipe, the splice operation
557 * can still fail with EINVAL if one of the fd doesn't explicitly support splice
558 * operation, e.g. reading from terminal is unsupported from kernel 5.7 to 5.11.
559 * Check issue #291 for more information.
560 */
561#[doc = include_str!("../docs/io_uring_prep_splice.md")]
562#[inline]
563pub unsafe fn io_uring_prep_splice(sqe: *mut io_uring_sqe, fd_in: c_int, off_in: i64,
564                                   fd_out: c_int, off_out: i64, nbytes: c_uint,
565                                   splice_flags: c_uint)
566{
567    io_uring_prep_rw(IORING_OP_SPLICE, sqe, fd_out, ptr::null_mut(), nbytes, off_out as u64);
568    (*sqe).__liburing_anon_2.splice_off_in = off_in as u64;
569    (*sqe).__liburing_anon_5.splice_fd_in = fd_in;
570    (*sqe).__liburing_anon_3.splice_flags = splice_flags;
571}
572
573#[doc = include_str!("../docs/io_uring_prep_tee.md")]
574#[inline]
575pub unsafe fn io_uring_prep_tee(sqe: *mut io_uring_sqe, fd_in: c_int, fd_out: c_int,
576                                nbytes: c_uint, splice_flags: c_uint)
577{
578    io_uring_prep_rw(IORING_OP_TEE, sqe, fd_out, ptr::null_mut(), nbytes, 0);
579    (*sqe).__liburing_anon_2.splice_off_in = 0;
580    (*sqe).__liburing_anon_5.splice_fd_in = fd_in;
581    (*sqe).__liburing_anon_3.splice_flags = splice_flags;
582}
583
584#[doc = include_str!("../docs/io_uring_prep_readv.md")]
585#[inline]
586pub unsafe fn io_uring_prep_readv(sqe: *mut io_uring_sqe, fd: c_int, iovecs: *const iovec,
587                                  nr_vecs: c_uint, offset: u64)
588{
589    io_uring_prep_rw(IORING_OP_READV, sqe, fd, iovecs.cast(), nr_vecs, offset);
590}
591
592#[doc = include_str!("../docs/io_uring_prep_readv2.md")]
593#[inline]
594pub unsafe fn io_uring_prep_readv2(sqe: *mut io_uring_sqe, fd: c_int, iovecs: *const iovec,
595                                   nr_vecs: c_uint, offset: u64, flags: c_int)
596{
597    io_uring_prep_readv(sqe, fd, iovecs, nr_vecs, offset);
598    (*sqe).__liburing_anon_3.rw_flags = flags;
599}
600
601#[doc = include_str!("../docs/io_uring_prep_read_fixed.md")]
602#[inline]
603pub unsafe fn io_uring_prep_read_fixed(sqe: *mut io_uring_sqe, fd: c_int, buf: *mut c_void,
604                                       nbytes: c_uint, offset: u64, buf_index: c_int)
605{
606    io_uring_prep_rw(IORING_OP_READ_FIXED, sqe, fd, buf, nbytes, offset);
607    (*sqe).__liburing_anon_4.buf_index = buf_index as u16;
608}
609
610#[doc = include_str!("../docs/io_uring_prep_readv_fixed.md")]
611#[inline]
612pub unsafe fn io_uring_prep_readv_fixed(sqe: *mut io_uring_sqe, fd: c_int, iovecs: *const iovec,
613                                        nr_vecs: c_uint, offset: u64, flags: c_int,
614                                        buf_index: c_int)
615{
616    io_uring_prep_readv2(sqe, fd, iovecs, nr_vecs, offset, flags);
617    (*sqe).opcode = IORING_OP_READV_FIXED as _;
618    (*sqe).__liburing_anon_4.buf_index = buf_index as u16;
619}
620
621#[doc = include_str!("../docs/io_uring_prep_writev.md")]
622#[inline]
623pub unsafe fn io_uring_prep_writev(sqe: *mut io_uring_sqe, fd: c_int, iovecs: *const iovec,
624                                   nr_vecs: c_uint, offset: u64)
625{
626    io_uring_prep_rw(IORING_OP_WRITEV, sqe, fd, iovecs.cast(), nr_vecs, offset);
627}
628
629#[doc = include_str!("../docs/io_uring_prep_writev2.md")]
630#[inline]
631pub unsafe fn io_uring_prep_writev2(sqe: *mut io_uring_sqe, fd: c_int, iovecs: *const iovec,
632                                    nr_vecs: c_uint, offset: u64, flags: c_int)
633{
634    io_uring_prep_writev(sqe, fd, iovecs, nr_vecs, offset);
635    (*sqe).__liburing_anon_3.rw_flags = flags;
636}
637
638#[doc = include_str!("../docs/io_uring_prep_write_fixed.md")]
639#[inline]
640pub unsafe fn io_uring_prep_write_fixed(sqe: *mut io_uring_sqe, fd: c_int, buf: *const c_void,
641                                        nbytes: c_uint, offset: u64, buf_index: c_int)
642{
643    io_uring_prep_rw(IORING_OP_WRITE_FIXED, sqe, fd, buf, nbytes, offset);
644    (*sqe).__liburing_anon_4.buf_index = buf_index as u16;
645}
646
647#[doc = include_str!("../docs/io_uring_prep_writev_fixed.md")]
648#[inline]
649pub unsafe fn io_uring_prep_writev_fixed(sqe: *mut io_uring_sqe, fd: c_int, iovecs: *const iovec,
650                                         nr_vecs: c_uint, offset: u64, flags: c_int,
651                                         buf_index: c_int)
652{
653    io_uring_prep_writev2(sqe, fd, iovecs, nr_vecs, offset, flags);
654    (*sqe).opcode = IORING_OP_WRITEV_FIXED as _;
655    (*sqe).__liburing_anon_4.buf_index = buf_index as u16;
656}
657
658#[doc = include_str!("../docs/io_uring_prep_recvmsg.md")]
659#[inline]
660pub unsafe fn io_uring_prep_recvmsg(sqe: *mut io_uring_sqe, fd: c_int, msg: *mut msghdr,
661                                    flags: c_uint)
662{
663    io_uring_prep_rw(IORING_OP_RECVMSG, sqe, fd, msg.cast(), 1, 0);
664    (*sqe).__liburing_anon_3.msg_flags = flags;
665}
666
667#[doc = include_str!("../docs/io_uring_prep_recvmsg_multishot.md")]
668#[inline]
669pub unsafe fn io_uring_prep_recvmsg_multishot(sqe: *mut io_uring_sqe, fd: c_int, msg: *mut msghdr,
670                                              flags: c_uint)
671{
672    io_uring_prep_recvmsg(sqe, fd, msg, flags);
673    (*sqe).ioprio |= IORING_RECV_MULTISHOT as u16;
674}
675
676#[doc = include_str!("../docs/io_uring_prep_sendmsg.md")]
677#[inline]
678pub unsafe fn io_uring_prep_sendmsg(sqe: *mut io_uring_sqe, fd: c_int, msg: *const msghdr,
679                                    flags: c_uint)
680{
681    io_uring_prep_rw(IORING_OP_SENDMSG, sqe, fd, msg.cast(), 1, 0);
682    (*sqe).__liburing_anon_3.msg_flags = flags;
683}
684
685#[must_use]
686#[inline]
687fn __io_uring_prep_poll_mask(poll_mask: c_uint) -> c_uint
688{
689    poll_mask.to_le()
690}
691
692#[doc = include_str!("../docs/io_uring_prep_poll_add.md")]
693#[inline]
694pub unsafe fn io_uring_prep_poll_add(sqe: *mut io_uring_sqe, fd: c_int, poll_mask: c_uint)
695{
696    io_uring_prep_rw(IORING_OP_POLL_ADD, sqe, fd, ptr::null_mut(), 0, 0);
697    (*sqe).__liburing_anon_3.poll32_events = __io_uring_prep_poll_mask(poll_mask);
698}
699
700#[doc = include_str!("../docs/io_uring_prep_poll_multishot.md")]
701#[inline]
702pub unsafe fn io_uring_prep_poll_multishot(sqe: *mut io_uring_sqe, fd: c_int, poll_mask: c_uint)
703{
704    io_uring_prep_poll_add(sqe, fd, poll_mask);
705    (*sqe).len = IORING_POLL_ADD_MULTI;
706}
707
708#[doc = include_str!("../docs/io_uring_prep_poll_remove.md")]
709#[inline]
710pub unsafe fn io_uring_prep_poll_remove(sqe: *mut io_uring_sqe, user_data: u64)
711{
712    io_uring_prep_rw(IORING_OP_POLL_REMOVE, sqe, -1, ptr::null_mut(), 0, 0);
713    (*sqe).__liburing_anon_2.addr = user_data;
714}
715
716#[doc = include_str!("../docs/io_uring_prep_poll_update.md")]
717#[inline]
718pub unsafe fn io_uring_prep_poll_update(sqe: *mut io_uring_sqe, old_user_data: u64,
719                                        new_user_data: u64, poll_mask: c_uint, flags: c_uint)
720{
721    io_uring_prep_rw(IORING_OP_POLL_REMOVE, sqe, -1, ptr::null_mut(), flags, new_user_data);
722    (*sqe).__liburing_anon_2.addr = old_user_data;
723    (*sqe).__liburing_anon_3.poll32_events = __io_uring_prep_poll_mask(poll_mask);
724}
725
726#[doc = include_str!("../docs/io_uring_prep_fsync.md")]
727#[inline]
728pub unsafe fn io_uring_prep_fsync(sqe: *mut io_uring_sqe, fd: c_int, fsync_flags: c_uint)
729{
730    io_uring_prep_rw(IORING_OP_FSYNC, sqe, fd, ptr::null_mut(), 0, 0);
731    (*sqe).__liburing_anon_3.fsync_flags = fsync_flags;
732}
733
734#[doc = include_str!("../docs/io_uring_prep_nop.md")]
735#[inline]
736pub unsafe fn io_uring_prep_nop(sqe: *mut io_uring_sqe)
737{
738    io_uring_prep_rw(IORING_OP_NOP, sqe, -1, ptr::null_mut(), 0, 0);
739}
740
741#[doc = include_str!("../docs/io_uring_prep_nop128.md")]
742#[inline]
743pub unsafe fn io_uring_prep_nop128(sqe: *mut io_uring_sqe)
744{
745    io_uring_prep_rw(IORING_OP_NOP128, sqe, -1, ptr::null_mut(), 0, 0);
746}
747
748#[doc = include_str!("../docs/io_uring_prep_timeout.md")]
749#[inline]
750pub unsafe fn io_uring_prep_timeout(sqe: *mut io_uring_sqe, ts: *const __kernel_timespec,
751                                    count: c_uint, flags: c_uint)
752{
753    io_uring_prep_rw(IORING_OP_TIMEOUT, sqe, -1, ts.cast(), 1, count.into());
754    (*sqe).__liburing_anon_3.timeout_flags = flags;
755}
756
757#[doc = include_str!("../docs/io_uring_prep_timeout_remove.md")]
758#[inline]
759pub unsafe fn io_uring_prep_timeout_remove(sqe: *mut io_uring_sqe, user_data: __u64, flags: c_uint)
760{
761    io_uring_prep_rw(IORING_OP_TIMEOUT_REMOVE, sqe, -1, ptr::null_mut(), 0, 0);
762    (*sqe).__liburing_anon_2.addr = user_data;
763    (*sqe).__liburing_anon_3.timeout_flags = flags;
764}
765
766#[doc = include_str!("../docs/io_uring_prep_timeout_update.md")]
767#[inline]
768pub unsafe fn io_uring_prep_timeout_update(sqe: *mut io_uring_sqe, ts: *const __kernel_timespec,
769                                           user_data: __u64, flags: c_uint)
770{
771    io_uring_prep_rw(IORING_OP_TIMEOUT_REMOVE, sqe, -1, ptr::null_mut(), 0, ts as u64);
772    (*sqe).__liburing_anon_2.addr = user_data;
773    (*sqe).__liburing_anon_3.timeout_flags = flags | IORING_TIMEOUT_UPDATE;
774}
775
776#[doc = include_str!("../docs/io_uring_prep_accept.md")]
777#[inline]
778pub unsafe fn io_uring_prep_accept(sqe: *mut io_uring_sqe, fd: c_int, addr: *mut sockaddr,
779                                   addrlen: *mut socklen_t, flags: c_int)
780{
781    io_uring_prep_rw(IORING_OP_ACCEPT, sqe, fd, addr.cast(), 0, uring_ptr_to_u64(addrlen.cast()));
782    (*sqe).__liburing_anon_3.accept_flags = flags as u32;
783}
784
785/* accept directly into the fixed file table */
786#[doc = include_str!("../docs/io_uring_prep_accept_direct.md")]
787#[inline]
788pub unsafe fn io_uring_prep_accept_direct(sqe: *mut io_uring_sqe, fd: c_int, addr: *mut sockaddr,
789                                          addrlen: *mut socklen_t, flags: c_int,
790                                          mut file_index: c_uint)
791{
792    io_uring_prep_accept(sqe, fd, addr, addrlen, flags);
793    /* offset by 1 for allocation */
794    if file_index == IORING_FILE_INDEX_ALLOC as _ {
795        file_index -= 1;
796    }
797    __io_uring_set_target_fixed_file(sqe, file_index);
798}
799
800#[doc = include_str!("../docs/io_uring_prep_multishot_accept.md")]
801#[inline]
802pub unsafe fn io_uring_prep_multishot_accept(sqe: *mut io_uring_sqe, fd: c_int,
803                                             addr: *mut sockaddr, addrlen: *mut socklen_t,
804                                             flags: c_int)
805{
806    io_uring_prep_accept(sqe, fd, addr, addrlen, flags);
807    (*sqe).ioprio |= IORING_ACCEPT_MULTISHOT as u16;
808}
809
810/* multishot accept directly into the fixed file table */
811#[doc = include_str!("../docs/io_uring_prep_multishot_accept_direct.md")]
812#[inline]
813pub unsafe fn io_uring_prep_multishot_accept_direct(sqe: *mut io_uring_sqe, fd: c_int,
814                                                    addr: *mut sockaddr, addrlen: *mut socklen_t,
815                                                    flags: c_int)
816{
817    io_uring_prep_multishot_accept(sqe, fd, addr, addrlen, flags);
818    __io_uring_set_target_fixed_file(sqe, (IORING_FILE_INDEX_ALLOC - 1) as u32);
819}
820
821#[doc = include_str!("../docs/io_uring_prep_cancel64.md")]
822#[inline]
823pub unsafe fn io_uring_prep_cancel64(sqe: *mut io_uring_sqe, user_data: u64, flags: c_int)
824{
825    io_uring_prep_rw(IORING_OP_ASYNC_CANCEL, sqe, -1, ptr::null_mut(), 0, 0);
826    (*sqe).__liburing_anon_2.addr = user_data;
827    (*sqe).__liburing_anon_3.cancel_flags = flags as u32;
828}
829
830#[doc = include_str!("../docs/io_uring_prep_cancel.md")]
831#[inline]
832pub unsafe fn io_uring_prep_cancel(sqe: *mut io_uring_sqe, user_data: *const c_void, flags: c_int)
833{
834    io_uring_prep_cancel64(sqe, user_data as usize as u64, flags);
835}
836
837#[doc = include_str!("../docs/io_uring_prep_cancel_fd.md")]
838#[inline]
839pub unsafe fn io_uring_prep_cancel_fd(sqe: *mut io_uring_sqe, fd: c_int, flags: c_uint)
840{
841    io_uring_prep_rw(IORING_OP_ASYNC_CANCEL, sqe, fd, ptr::null_mut(), 0, 0);
842    (*sqe).__liburing_anon_3.cancel_flags = flags | IORING_ASYNC_CANCEL_FD;
843}
844
845#[doc = include_str!("../docs/io_uring_prep_link_timeout.md")]
846#[inline]
847pub unsafe fn io_uring_prep_link_timeout(sqe: *mut io_uring_sqe, ts: *const __kernel_timespec,
848                                         flags: c_uint)
849{
850    io_uring_prep_rw(IORING_OP_LINK_TIMEOUT, sqe, -1, ts.cast(), 1, 0);
851    (*sqe).__liburing_anon_3.timeout_flags = flags;
852}
853
854#[doc = include_str!("../docs/io_uring_prep_connect.md")]
855#[inline]
856pub unsafe fn io_uring_prep_connect(sqe: *mut io_uring_sqe, fd: c_int, addr: *const sockaddr,
857                                    addrlen: socklen_t)
858{
859    io_uring_prep_rw(IORING_OP_CONNECT, sqe, fd, addr.cast(), 0, addrlen.into());
860}
861
862#[doc = include_str!("../docs/io_uring_prep_bind.md")]
863#[inline]
864pub unsafe fn io_uring_prep_bind(sqe: *mut io_uring_sqe, fd: c_int, addr: *const sockaddr,
865                                 addrlen: socklen_t)
866{
867    io_uring_prep_rw(IORING_OP_BIND, sqe, fd, addr.cast(), 0, addrlen.into());
868}
869
870#[doc = include_str!("../docs/io_uring_prep_listen.md")]
871#[inline]
872pub unsafe fn io_uring_prep_listen(sqe: *mut io_uring_sqe, fd: c_int, backlog: c_int)
873{
874    io_uring_prep_rw(IORING_OP_LISTEN, sqe, fd, ptr::null_mut(), backlog as _, 0);
875}
876
877#[doc = include_str!("../docs/io_uring_prep_epoll_wait.md")]
878#[inline]
879pub unsafe fn io_uring_prep_epoll_wait(sqe: *mut io_uring_sqe, fd: c_int,
880                                       events: *mut epoll_event, maxevents: c_int, flags: c_uint)
881{
882    io_uring_prep_rw(IORING_OP_EPOLL_WAIT, sqe, fd, events.cast(), maxevents as _, 0);
883    (*sqe).__liburing_anon_3.rw_flags = flags as _;
884}
885
886#[doc = include_str!("../docs/io_uring_prep_files_update.md")]
887#[inline]
888pub unsafe fn io_uring_prep_files_update(sqe: *mut io_uring_sqe, fds: *mut c_int, nr_fds: c_uint,
889                                         offset: c_int)
890{
891    io_uring_prep_rw(IORING_OP_FILES_UPDATE, sqe, -1, fds.cast(), nr_fds, offset as u64);
892}
893
894#[doc = include_str!("../docs/io_uring_prep_fallocate.md")]
895#[inline]
896pub unsafe fn io_uring_prep_fallocate(sqe: *mut io_uring_sqe, fd: c_int, mode: c_int, offset: u64,
897                                      len: u64)
898{
899    io_uring_prep_rw(IORING_OP_FALLOCATE, sqe, fd, ptr::null_mut(), mode as c_uint, offset);
900    (*sqe).__liburing_anon_2.addr = len;
901}
902
903#[doc = include_str!("../docs/io_uring_prep_openat.md")]
904#[inline]
905pub unsafe fn io_uring_prep_openat(sqe: *mut io_uring_sqe, dfd: c_int, path: *const c_char,
906                                   flags: c_int, mode: mode_t)
907{
908    io_uring_prep_rw(IORING_OP_OPENAT, sqe, dfd, path.cast(), mode, 0);
909    (*sqe).__liburing_anon_3.open_flags = flags as u32;
910}
911
912/* open directly into the fixed file table */
913#[doc = include_str!("../docs/io_uring_prep_openat_direct.md")]
914#[inline]
915pub unsafe fn io_uring_prep_openat_direct(sqe: *mut io_uring_sqe, dfd: c_int, path: *const c_char,
916                                          flags: c_int, mode: mode_t, mut file_index: c_uint)
917{
918    io_uring_prep_openat(sqe, dfd, path, flags, mode);
919    /* offset by 1 for allocation */
920    if file_index == IORING_FILE_INDEX_ALLOC as _ {
921        file_index -= 1;
922    }
923    __io_uring_set_target_fixed_file(sqe, file_index);
924}
925
926#[doc = include_str!("../docs/io_uring_prep_open.md")]
927#[inline]
928pub unsafe fn io_uring_prep_open(sqe: *mut io_uring_sqe, path: *const c_char, flags: c_int,
929                                 mode: mode_t)
930{
931    io_uring_prep_openat(sqe, AT_FDCWD, path, flags, mode);
932}
933
934/* open directly into the fixed file table */
935#[doc = include_str!("../docs/io_uring_prep_open_direct.md")]
936#[inline]
937pub unsafe fn io_uring_prep_open_direct(sqe: *mut io_uring_sqe, path: *const c_char, flags: c_int,
938                                        mode: mode_t, file_index: c_uint)
939{
940    io_uring_prep_openat_direct(sqe, AT_FDCWD, path, flags, mode, file_index);
941}
942
943#[doc = include_str!("../docs/io_uring_prep_close.md")]
944#[inline]
945pub unsafe fn io_uring_prep_close(sqe: *mut io_uring_sqe, fd: c_int)
946{
947    io_uring_prep_rw(IORING_OP_CLOSE, sqe, fd, ptr::null_mut(), 0, 0);
948}
949
950#[doc = include_str!("../docs/io_uring_prep_close_direct.md")]
951#[inline]
952pub unsafe fn io_uring_prep_close_direct(sqe: *mut io_uring_sqe, file_index: c_uint)
953{
954    io_uring_prep_close(sqe, 0);
955    __io_uring_set_target_fixed_file(sqe, file_index);
956}
957
958#[doc = include_str!("../docs/io_uring_prep_read.md")]
959#[inline]
960pub unsafe fn io_uring_prep_read(sqe: *mut io_uring_sqe, fd: c_int, buf: *mut c_void,
961                                 nbytes: c_uint, offset: u64)
962{
963    io_uring_prep_rw(IORING_OP_READ, sqe, fd, buf, nbytes, offset);
964}
965
966#[doc = include_str!("../docs/io_uring_prep_read_multishot.md")]
967#[inline]
968pub unsafe fn io_uring_prep_read_multishot(sqe: *mut io_uring_sqe, fd: c_int, nbytes: c_uint,
969                                           offset: u64, buf_group: c_int)
970{
971    io_uring_prep_rw(IORING_OP_READ_MULTISHOT, sqe, fd, ptr::null_mut(), nbytes, offset);
972    (*sqe).__liburing_anon_4.buf_group = buf_group as _;
973    (*sqe).flags = IOSQE_BUFFER_SELECT as _;
974}
975
976#[doc = include_str!("../docs/io_uring_prep_write.md")]
977#[inline]
978pub unsafe fn io_uring_prep_write(sqe: *mut io_uring_sqe, fd: c_int, buf: *const c_void,
979                                  nbytes: c_uint, offset: u64)
980{
981    io_uring_prep_rw(IORING_OP_WRITE, sqe, fd, buf, nbytes, offset);
982}
983
984#[doc = include_str!("../docs/io_uring_prep_statx.md")]
985#[inline]
986pub unsafe fn io_uring_prep_statx(sqe: *mut io_uring_sqe, dfd: c_int, path: *const c_char,
987                                  flags: c_int, mask: c_uint, statxbuf: *mut statx)
988{
989    io_uring_prep_rw(IORING_OP_STATX,
990                     sqe,
991                     dfd,
992                     path.cast(),
993                     mask,
994                     uring_ptr_to_u64(statxbuf.cast()));
995    (*sqe).__liburing_anon_3.statx_flags = flags as u32;
996}
997
998#[doc = include_str!("../docs/io_uring_prep_fadvise.md")]
999#[inline]
1000pub unsafe fn io_uring_prep_fadvise(sqe: *mut io_uring_sqe, fd: c_int, offset: u64, len: u32,
1001                                    advice: c_int)
1002{
1003    io_uring_prep_rw(IORING_OP_FADVISE, sqe, fd, ptr::null_mut(), len, offset);
1004    (*sqe).__liburing_anon_3.fadvise_advice = advice as u32;
1005}
1006
1007#[doc = include_str!("../docs/io_uring_prep_madvise.md")]
1008#[inline]
1009pub unsafe fn io_uring_prep_madvise(sqe: *mut io_uring_sqe, addr: *mut c_void, length: u32,
1010                                    advice: c_int)
1011{
1012    io_uring_prep_rw(IORING_OP_MADVISE, sqe, -1, addr, length, 0);
1013    (*sqe).__liburing_anon_3.fadvise_advice = advice as u32;
1014}
1015
1016#[doc = include_str!("../docs/io_uring_prep_fadvise64.md")]
1017#[inline]
1018pub unsafe fn io_uring_prep_fadvise64(sqe: *mut io_uring_sqe, fd: c_int, offset: u64, len: off_t,
1019                                      advice: c_int)
1020{
1021    io_uring_prep_rw(IORING_OP_FADVISE, sqe, fd, ptr::null_mut(), 0, offset);
1022    (*sqe).__liburing_anon_2.addr = len as _;
1023    (*sqe).__liburing_anon_3.fadvise_advice = advice as u32;
1024}
1025
1026#[doc = include_str!("../docs/io_uring_prep_madvise64.md")]
1027#[inline]
1028pub unsafe fn io_uring_prep_madvise64(sqe: *mut io_uring_sqe, addr: *mut c_void, length: off_t,
1029                                      advice: c_int)
1030{
1031    io_uring_prep_rw(IORING_OP_MADVISE, sqe, -1, addr, 0, length as _);
1032    (*sqe).__liburing_anon_3.fadvise_advice = advice as u32;
1033}
1034
1035#[doc = include_str!("../docs/io_uring_prep_send.md")]
1036#[inline]
1037pub unsafe fn io_uring_prep_send(sqe: *mut io_uring_sqe, sockfd: c_int, buf: *const c_void,
1038                                 len: usize, flags: c_int)
1039{
1040    io_uring_prep_rw(IORING_OP_SEND, sqe, sockfd, buf, len as u32, 0);
1041    (*sqe).__liburing_anon_3.msg_flags = flags as u32;
1042}
1043
1044#[doc = include_str!("../docs/io_uring_prep_send_bundle.md")]
1045#[inline]
1046pub unsafe fn io_uring_prep_send_bundle(sqe: *mut io_uring_sqe, sockfd: c_int, len: usize,
1047                                        flags: c_int)
1048{
1049    io_uring_prep_send(sqe, sockfd, ptr::null_mut(), len, flags);
1050    (*sqe).ioprio |= IORING_RECVSEND_BUNDLE as u16;
1051}
1052
1053#[doc = include_str!("../docs/io_uring_prep_send_set_addr.md")]
1054#[inline]
1055pub unsafe fn io_uring_prep_send_set_addr(sqe: *mut io_uring_sqe, dest_addr: *const sockaddr,
1056                                          addr_len: u16)
1057{
1058    (*sqe).__liburing_anon_1.addr2 = dest_addr as usize as u64;
1059    (*sqe).__liburing_anon_5.__liburing_anon_1.addr_len = addr_len;
1060}
1061
1062#[doc = include_str!("../docs/io_uring_prep_sendto.md")]
1063#[inline]
1064pub unsafe fn io_uring_prep_sendto(sqe: *mut io_uring_sqe, sockfd: c_int, buf: *const c_void,
1065                                   len: usize, flags: c_int, addr: *const sockaddr,
1066                                   addrlen: socklen_t)
1067{
1068    io_uring_prep_send(sqe, sockfd, buf, len, flags);
1069    io_uring_prep_send_set_addr(sqe, addr, addrlen as _);
1070}
1071
1072#[doc = include_str!("../docs/io_uring_prep_send_zc.md")]
1073#[inline]
1074pub unsafe fn io_uring_prep_send_zc(sqe: *mut io_uring_sqe, sockfd: c_int, buf: *const c_void,
1075                                    len: usize, flags: c_int, zc_flags: c_uint)
1076{
1077    io_uring_prep_rw(IORING_OP_SEND_ZC, sqe, sockfd, buf, len as u32, 0);
1078    (*sqe).__liburing_anon_3.msg_flags = flags as u32;
1079    (*sqe).ioprio = zc_flags as _;
1080}
1081
1082#[doc = include_str!("../docs/io_uring_prep_send_zc_fixed.md")]
1083#[inline]
1084pub unsafe fn io_uring_prep_send_zc_fixed(sqe: *mut io_uring_sqe, sockfd: c_int,
1085                                          buf: *const c_void, len: usize, flags: c_int,
1086                                          zc_flags: c_uint, buf_index: c_uint)
1087{
1088    io_uring_prep_send_zc(sqe, sockfd, buf, len, flags, zc_flags);
1089    (*sqe).ioprio |= IORING_RECVSEND_FIXED_BUF as u16;
1090    (*sqe).__liburing_anon_4.buf_index = buf_index as _;
1091}
1092
1093#[doc = include_str!("../docs/io_uring_prep_sendmsg_zc.md")]
1094#[inline]
1095pub unsafe fn io_uring_prep_sendmsg_zc(sqe: *mut io_uring_sqe, fd: c_int, msg: *const msghdr,
1096                                       flags: c_uint)
1097{
1098    io_uring_prep_sendmsg(sqe, fd, msg, flags);
1099    (*sqe).opcode = IORING_OP_SENDMSG_ZC as _;
1100}
1101
1102#[doc = include_str!("../docs/io_uring_prep_sendmsg_zc_fixed.md")]
1103#[inline]
1104pub unsafe fn io_uring_prep_sendmsg_zc_fixed(sqe: *mut io_uring_sqe, fd: c_int,
1105                                             msg: *const msghdr, flags: c_uint, buf_index: c_uint)
1106{
1107    io_uring_prep_sendmsg_zc(sqe, fd, msg, flags);
1108    (*sqe).ioprio |= IORING_RECVSEND_FIXED_BUF as u16;
1109    (*sqe).__liburing_anon_4.buf_index = buf_index as _;
1110}
1111
1112#[doc = include_str!("../docs/io_uring_prep_recv.md")]
1113#[inline]
1114pub unsafe fn io_uring_prep_recv(sqe: *mut io_uring_sqe, sockfd: c_int, buf: *mut c_void,
1115                                 len: usize, flags: c_int)
1116{
1117    io_uring_prep_rw(IORING_OP_RECV, sqe, sockfd, buf, len as u32, 0);
1118    (*sqe).__liburing_anon_3.msg_flags = flags as u32;
1119}
1120
1121#[doc = include_str!("../docs/io_uring_prep_recv_multishot.md")]
1122#[inline]
1123pub unsafe fn io_uring_prep_recv_multishot(sqe: *mut io_uring_sqe, sockfd: c_int,
1124                                           buf: *mut c_void, len: usize, flags: c_int)
1125{
1126    io_uring_prep_recv(sqe, sockfd, buf, len, flags);
1127    (*sqe).ioprio |= IORING_RECV_MULTISHOT as u16;
1128}
1129
1130#[doc = include_str!("../docs/io_uring_recvmsg_validate.md")]
1131#[inline]
1132pub unsafe fn io_uring_recvmsg_validate(buf: *mut c_void, buf_len: c_int, msgh: *mut msghdr)
1133                                        -> *mut io_uring_recvmsg_out
1134{
1135    let ulen = c_ulong::from(buf_len as c_uint);
1136    let hdr = size_of::<io_uring_recvmsg_out>() as c_ulong;
1137    let namelen = c_ulong::from((*msgh).msg_namelen);
1138    let controllen = (*msgh).msg_controllen as c_ulong;
1139
1140    if buf_len < 0 || ulen < hdr {
1141        return ptr::null_mut();
1142    }
1143    /* check each addition separately to avoid integer overflow */
1144    if namelen > ulen - hdr {
1145        return ptr::null_mut();
1146    }
1147    if controllen > ulen - hdr - namelen {
1148        return ptr::null_mut();
1149    }
1150
1151    buf.cast()
1152}
1153
1154#[doc = include_str!("../docs/io_uring_recvmsg_name.md")]
1155#[inline]
1156pub unsafe fn io_uring_recvmsg_name(o: *mut io_uring_recvmsg_out) -> *mut c_void
1157{
1158    o.add(1).cast()
1159}
1160
1161#[doc = include_str!("../docs/io_uring_recvmsg_cmsg_firsthdr.md")]
1162#[inline]
1163pub unsafe fn io_uring_recvmsg_cmsg_firsthdr(o: *mut io_uring_recvmsg_out, msgh: *mut msghdr)
1164                                             -> *mut cmsghdr
1165{
1166    if ((*o).controllen as usize) < mem::size_of::<cmsghdr>() {
1167        return ptr::null_mut();
1168    }
1169
1170    io_uring_recvmsg_name(o).cast::<u8>()
1171                            .add((*msgh).msg_namelen as _)
1172                            .cast()
1173}
1174
1175#[doc = include_str!("../docs/io_uring_recvmsg_cmsg_nexthdr.md")]
1176#[inline]
1177pub unsafe fn io_uring_recvmsg_cmsg_nexthdr(o: *mut io_uring_recvmsg_out, msgh: *mut msghdr,
1178                                            cmsg: *mut cmsghdr)
1179                                            -> *mut cmsghdr
1180{
1181    #[allow(non_snake_case)]
1182    fn CMSG_ALIGN(len: usize) -> usize
1183    {
1184        ((len) + mem::size_of::<usize>() - 1) & !(mem::size_of::<usize>() - 1)
1185    }
1186
1187    if ((*cmsg).cmsg_len as usize) < mem::size_of::<cmsghdr>() {
1188        return ptr::null_mut();
1189    }
1190
1191    let end = io_uring_recvmsg_cmsg_firsthdr(o, msgh).cast::<u8>()
1192                                                     .add((*o).controllen as _);
1193
1194    let cmsg = cmsg.cast::<u8>()
1195                   .add(CMSG_ALIGN((*cmsg).cmsg_len as usize))
1196                   .cast::<cmsghdr>();
1197
1198    if cmsg.add(1).cast::<u8>() > end {
1199        return ptr::null_mut();
1200    }
1201
1202    if cmsg.cast::<u8>().add(CMSG_ALIGN((*cmsg).cmsg_len as usize)) > end {
1203        return ptr::null_mut();
1204    }
1205
1206    cmsg
1207}
1208
1209#[doc = include_str!("../docs/io_uring_recvmsg_payload.md")]
1210#[inline]
1211pub unsafe fn io_uring_recvmsg_payload(o: *mut io_uring_recvmsg_out, msgh: *mut msghdr)
1212                                       -> *mut c_void
1213{
1214    io_uring_recvmsg_name(o).cast::<u8>()
1215                            .add((*msgh).msg_namelen as usize + (*msgh).msg_controllen as usize)
1216                            .cast::<c_void>()
1217}
1218
1219#[doc = include_str!("../docs/io_uring_recvmsg_payload_length.md")]
1220#[inline]
1221pub unsafe fn io_uring_recvmsg_payload_length(o: *mut io_uring_recvmsg_out, buf_len: c_int,
1222                                              msgh: *mut msghdr)
1223                                              -> c_uint
1224{
1225    if buf_len < 0 {
1226        return 0;
1227    }
1228
1229    let payload_start = io_uring_recvmsg_payload(o, msgh) as usize;
1230    let payload_end = o as usize + buf_len as usize;
1231    if payload_start >= payload_end {
1232        return 0;
1233    }
1234
1235    (payload_end - payload_start) as _
1236}
1237
1238#[doc = include_str!("../docs/io_uring_prep_openat2.md")]
1239#[inline]
1240pub unsafe fn io_uring_prep_openat2(sqe: *mut io_uring_sqe, dfd: c_int, path: *const c_char,
1241                                    how: *const open_how)
1242{
1243    io_uring_prep_rw(IORING_OP_OPENAT2 as _,
1244                     sqe,
1245                     dfd,
1246                     path.cast(),
1247                     mem::size_of::<open_how>() as u32,
1248                     how as usize as u64);
1249}
1250
1251/* open directly into the fixed file table */
1252#[doc = include_str!("../docs/io_uring_prep_openat2_direct.md")]
1253#[inline]
1254pub unsafe fn io_uring_prep_openat2_direct(sqe: *mut io_uring_sqe, dfd: c_int,
1255                                           path: *const c_char, how: *const open_how,
1256                                           mut file_index: c_uint)
1257{
1258    io_uring_prep_openat2(sqe, dfd, path, how);
1259    /* offset by 1 for allocation */
1260    if file_index == IORING_FILE_INDEX_ALLOC as _ {
1261        file_index -= 1;
1262    }
1263    __io_uring_set_target_fixed_file(sqe, file_index);
1264}
1265
1266#[doc = include_str!("../docs/io_uring_prep_epoll_ctl.md")]
1267#[inline]
1268pub unsafe fn io_uring_prep_epoll_ctl(sqe: *mut io_uring_sqe, epfd: c_int, fd: c_int, op: c_int,
1269                                      ev: *const epoll_event)
1270{
1271    io_uring_prep_rw(IORING_OP_EPOLL_CTL, sqe, epfd, ev.cast(), op as u32, u64::from(fd as u32));
1272}
1273
1274#[doc = include_str!("../docs/io_uring_prep_provide_buffers.md")]
1275#[inline]
1276pub unsafe fn io_uring_prep_provide_buffers(sqe: *mut io_uring_sqe, addr: *mut c_void, len: c_int,
1277                                            nr: c_int, bgid: c_int, bid: c_int)
1278{
1279    io_uring_prep_rw(IORING_OP_PROVIDE_BUFFERS, sqe, nr, addr, len as u32, bid as u64);
1280    (*sqe).__liburing_anon_4.buf_group = bgid as u16;
1281}
1282
1283#[doc = include_str!("../docs/io_uring_prep_remove_buffers.md")]
1284#[inline]
1285pub unsafe fn io_uring_prep_remove_buffers(sqe: *mut io_uring_sqe, nr: c_int, bgid: c_int)
1286{
1287    io_uring_prep_rw(IORING_OP_REMOVE_BUFFERS, sqe, nr, ptr::null_mut(), 0, 0);
1288    (*sqe).__liburing_anon_4.buf_group = bgid as u16;
1289}
1290
1291#[doc = include_str!("../docs/io_uring_prep_shutdown.md")]
1292#[inline]
1293pub unsafe fn io_uring_prep_shutdown(sqe: *mut io_uring_sqe, fd: c_int, how: c_int)
1294{
1295    io_uring_prep_rw(IORING_OP_SHUTDOWN, sqe, fd, ptr::null_mut(), how as u32, 0);
1296}
1297
1298#[doc = include_str!("../docs/io_uring_prep_unlinkat.md")]
1299#[inline]
1300pub unsafe fn io_uring_prep_unlinkat(sqe: *mut io_uring_sqe, dfd: c_int, path: *const c_char,
1301                                     flags: c_int)
1302{
1303    io_uring_prep_rw(IORING_OP_UNLINKAT, sqe, dfd, path.cast(), 0, 0);
1304    (*sqe).__liburing_anon_3.unlink_flags = flags as u32;
1305}
1306
1307#[doc = include_str!("../docs/io_uring_prep_unlink.md")]
1308#[inline]
1309pub unsafe fn io_uring_prep_unlink(sqe: *mut io_uring_sqe, path: *const c_char, flags: c_int)
1310{
1311    io_uring_prep_unlinkat(sqe, AT_FDCWD, path, flags);
1312}
1313
1314#[doc = include_str!("../docs/io_uring_prep_renameat.md")]
1315#[inline]
1316pub unsafe fn io_uring_prep_renameat(sqe: *mut io_uring_sqe, olddfd: c_int,
1317                                     oldpath: *const c_char, newdfd: c_int,
1318                                     newpath: *const c_char, flags: c_uint)
1319{
1320    io_uring_prep_rw(IORING_OP_RENAMEAT,
1321                     sqe,
1322                     olddfd,
1323                     oldpath.cast(),
1324                     newdfd as u32,
1325                     newpath as usize as u64);
1326    (*sqe).__liburing_anon_3.rename_flags = flags;
1327}
1328
1329#[doc = include_str!("../docs/io_uring_prep_rename.md")]
1330#[inline]
1331pub unsafe fn io_uring_prep_rename(sqe: *mut io_uring_sqe, oldpath: *const c_char,
1332                                   newpath: *const c_char)
1333{
1334    io_uring_prep_renameat(sqe, AT_FDCWD, oldpath, AT_FDCWD, newpath, 0);
1335}
1336
1337#[doc = include_str!("../docs/io_uring_prep_sync_file_range.md")]
1338#[inline]
1339pub unsafe fn io_uring_prep_sync_file_range(sqe: *mut io_uring_sqe, fd: c_int, len: c_uint,
1340                                            offset: u64, flags: c_int)
1341{
1342    io_uring_prep_rw(IORING_OP_SYNC_FILE_RANGE, sqe, fd, ptr::null_mut(), len, offset);
1343    (*sqe).__liburing_anon_3.sync_range_flags = flags as u32;
1344}
1345
1346#[doc = include_str!("../docs/io_uring_prep_mkdirat.md")]
1347#[inline]
1348pub unsafe fn io_uring_prep_mkdirat(sqe: *mut io_uring_sqe, dfd: c_int, path: *const c_char,
1349                                    mode: mode_t)
1350{
1351    io_uring_prep_rw(IORING_OP_MKDIRAT, sqe, dfd, path.cast(), mode, 0);
1352}
1353
1354#[doc = include_str!("../docs/io_uring_prep_mkdir.md")]
1355#[inline]
1356pub unsafe fn io_uring_prep_mkdir(sqe: *mut io_uring_sqe, path: *const c_char, mode: mode_t)
1357{
1358    io_uring_prep_mkdirat(sqe, AT_FDCWD, path, mode);
1359}
1360
1361#[doc = include_str!("../docs/io_uring_prep_symlinkat.md")]
1362#[inline]
1363pub unsafe fn io_uring_prep_symlinkat(sqe: *mut io_uring_sqe, target: *const c_char,
1364                                      newdirfd: c_int, linkpath: *const c_char)
1365{
1366    io_uring_prep_rw(IORING_OP_SYMLINKAT,
1367                     sqe,
1368                     newdirfd,
1369                     target.cast(),
1370                     0,
1371                     linkpath as usize as u64);
1372}
1373#[doc = include_str!("../docs/io_uring_prep_symlink.md")]
1374#[inline]
1375pub unsafe fn io_uring_prep_symlink(sqe: *mut io_uring_sqe, target: *const c_char,
1376                                    linkpath: *const c_char)
1377{
1378    io_uring_prep_symlinkat(sqe, target, AT_FDCWD, linkpath);
1379}
1380
1381#[doc = include_str!("../docs/io_uring_prep_linkat.md")]
1382#[inline]
1383pub unsafe fn io_uring_prep_linkat(sqe: *mut io_uring_sqe, olddfd: c_int, oldpath: *const c_char,
1384                                   newdfd: c_int, newpath: *const c_char, flags: c_int)
1385{
1386    io_uring_prep_rw(IORING_OP_LINKAT,
1387                     sqe,
1388                     olddfd,
1389                     oldpath.cast(),
1390                     newdfd as u32,
1391                     newpath as usize as u64);
1392    (*sqe).__liburing_anon_3.hardlink_flags = flags as u32;
1393}
1394
1395#[doc = include_str!("../docs/io_uring_prep_link.md")]
1396#[inline]
1397pub unsafe fn io_uring_prep_link(sqe: *mut io_uring_sqe, oldpath: *const c_char,
1398                                 newpath: *const c_char, flags: c_int)
1399{
1400    io_uring_prep_linkat(sqe, AT_FDCWD, oldpath, AT_FDCWD, newpath, flags);
1401}
1402
1403#[doc = include_str!("../docs/io_uring_prep_msg_ring_cqe_flags.md")]
1404#[inline]
1405pub unsafe fn io_uring_prep_msg_ring_cqe_flags(sqe: *mut io_uring_sqe, fd: c_int, len: c_uint,
1406                                               data: u64, flags: c_uint, cqe_flags: c_uint)
1407{
1408    io_uring_prep_rw(IORING_OP_MSG_RING, sqe, fd, ptr::null_mut(), len, data);
1409    (*sqe).__liburing_anon_3.msg_ring_flags = IORING_MSG_RING_FLAGS_PASS | flags;
1410    (*sqe).__liburing_anon_5.file_index = cqe_flags;
1411}
1412
1413#[doc = include_str!("../docs/io_uring_prep_msg_ring.md")]
1414#[inline]
1415pub unsafe fn io_uring_prep_msg_ring(sqe: *mut io_uring_sqe, fd: c_int, len: c_uint, data: u64,
1416                                     flags: c_uint)
1417{
1418    io_uring_prep_rw(IORING_OP_MSG_RING, sqe, fd, ptr::null_mut(), len, data);
1419    (*sqe).__liburing_anon_3.msg_ring_flags = IORING_MSG_RING_FLAGS_PASS | flags;
1420}
1421
1422#[doc = include_str!("../docs/io_uring_prep_msg_ring_fd.md")]
1423#[inline]
1424pub unsafe fn io_uring_prep_msg_ring_fd(sqe: *mut io_uring_sqe, fd: c_int, source_fd: c_int,
1425                                        mut target_fd: c_int, data: u64, flags: c_uint)
1426{
1427    io_uring_prep_rw(IORING_OP_MSG_RING,
1428                     sqe,
1429                     fd,
1430                     IORING_MSG_SEND_FD as usize as *const c_void,
1431                     0,
1432                     data);
1433    (*sqe).__liburing_anon_6.__liburing_anon_1.as_mut().addr3 = source_fd as _;
1434    /* offset by 1 for allocation */
1435    if target_fd == IORING_FILE_INDEX_ALLOC as _ {
1436        target_fd -= 1;
1437    }
1438    __io_uring_set_target_fixed_file(sqe, target_fd as _);
1439    (*sqe).__liburing_anon_3.msg_ring_flags = flags;
1440}
1441
1442#[doc = include_str!("../docs/io_uring_prep_msg_ring_fd_alloc.md")]
1443#[inline]
1444pub unsafe fn io_uring_prep_msg_ring_fd_alloc(sqe: *mut io_uring_sqe, fd: c_int, source_fd: c_int,
1445                                              data: u64, flags: c_uint)
1446{
1447    io_uring_prep_msg_ring_fd(sqe, fd, source_fd, IORING_FILE_INDEX_ALLOC, data, flags);
1448}
1449
1450#[doc = include_str!("../docs/io_uring_prep_getxattr.md")]
1451#[inline]
1452pub unsafe fn io_uring_prep_getxattr(sqe: *mut io_uring_sqe, name: *const c_char,
1453                                     value: *mut c_char, path: *const c_char, len: c_uint)
1454{
1455    io_uring_prep_rw(IORING_OP_GETXATTR, sqe, 0, name.cast(), len, value as usize as u64);
1456    (*sqe).__liburing_anon_6.__liburing_anon_1.as_mut().addr3 = path as usize as u64;
1457
1458    (*sqe).__liburing_anon_3.xattr_flags = 0;
1459}
1460
1461#[doc = include_str!("../docs/io_uring_prep_setxattr.md")]
1462#[inline]
1463pub unsafe fn io_uring_prep_setxattr(sqe: *mut io_uring_sqe, name: *const c_char,
1464                                     value: *const c_char, path: *const c_char, flags: c_int,
1465                                     len: c_uint)
1466{
1467    io_uring_prep_rw(IORING_OP_SETXATTR, sqe, 0, name.cast(), len, value as usize as u64);
1468    (*sqe).__liburing_anon_6.__liburing_anon_1.as_mut().addr3 = path as usize as u64;
1469    (*sqe).__liburing_anon_3.xattr_flags = flags as _;
1470}
1471
1472#[doc = include_str!("../docs/io_uring_prep_fgetxattr.md")]
1473#[inline]
1474pub unsafe fn io_uring_prep_fgetxattr(sqe: *mut io_uring_sqe, fd: c_int, name: *const c_char,
1475                                      value: *mut c_char, len: c_uint)
1476{
1477    io_uring_prep_rw(IORING_OP_FGETXATTR, sqe, fd, name.cast(), len, value as usize as u64);
1478    (*sqe).__liburing_anon_3.xattr_flags = 0;
1479}
1480
1481#[doc = include_str!("../docs/io_uring_prep_fsetxattr.md")]
1482#[inline]
1483pub unsafe fn io_uring_prep_fsetxattr(sqe: *mut io_uring_sqe, fd: c_int, name: *const c_char,
1484                                      value: *mut c_char, flags: c_int, len: c_uint)
1485{
1486    io_uring_prep_rw(IORING_OP_FSETXATTR, sqe, fd, name.cast(), len, value as usize as u64);
1487    (*sqe).__liburing_anon_3.xattr_flags = flags as _;
1488}
1489
1490#[doc = include_str!("../docs/io_uring_prep_socket.md")]
1491#[inline]
1492pub unsafe fn io_uring_prep_socket(sqe: *mut io_uring_sqe, domain: c_int, r#type: c_int,
1493                                   protocol: c_int, flags: c_uint)
1494{
1495    io_uring_prep_rw(IORING_OP_SOCKET,
1496                     sqe,
1497                     domain,
1498                     ptr::null_mut(),
1499                     protocol as u32,
1500                     r#type as u64);
1501    (*sqe).__liburing_anon_3.rw_flags = flags as i32;
1502}
1503
1504#[doc = include_str!("../docs/io_uring_prep_socket_direct.md")]
1505#[inline]
1506pub unsafe fn io_uring_prep_socket_direct(sqe: *mut io_uring_sqe, domain: c_int, r#type: c_int,
1507                                          protocol: c_int, mut file_index: c_uint, flags: c_uint)
1508{
1509    io_uring_prep_rw(IORING_OP_SOCKET,
1510                     sqe,
1511                     domain,
1512                     ptr::null_mut(),
1513                     protocol as u32,
1514                     r#type as u64);
1515    (*sqe).__liburing_anon_3.rw_flags = flags as i32;
1516    /* offset by 1 for allocation */
1517    if file_index == IORING_FILE_INDEX_ALLOC as _ {
1518        file_index -= 1;
1519    }
1520    __io_uring_set_target_fixed_file(sqe, file_index);
1521}
1522
1523#[doc = include_str!("../docs/io_uring_prep_socket_direct_alloc.md")]
1524#[inline]
1525pub unsafe fn io_uring_prep_socket_direct_alloc(sqe: *mut io_uring_sqe, domain: c_int,
1526                                                r#type: c_int, protocol: c_int, flags: c_uint)
1527{
1528    io_uring_prep_rw(IORING_OP_SOCKET,
1529                     sqe,
1530                     domain,
1531                     ptr::null_mut(),
1532                     protocol as u32,
1533                     r#type as u64);
1534    (*sqe).__liburing_anon_3.rw_flags = flags as i32;
1535    __io_uring_set_target_fixed_file(sqe, (IORING_FILE_INDEX_ALLOC - 1) as _);
1536}
1537
1538#[inline]
1539unsafe fn __io_uring_prep_uring_cmd(sqe: *mut io_uring_sqe, op: c_int, cmd_op: u32, fd: c_int)
1540{
1541    (*sqe).opcode = op as _;
1542    (*sqe).fd = fd;
1543    (*sqe).__liburing_anon_1.__liburing_anon_1.cmd_op = cmd_op;
1544    (*sqe).__liburing_anon_1.__liburing_anon_1.__pad1 = 0;
1545    (*sqe).__liburing_anon_2.addr = 0;
1546    (*sqe).len = 0;
1547}
1548
1549#[doc = include_str!("../docs/io_uring_prep_uring_cmd.md")]
1550#[inline]
1551pub unsafe fn io_uring_prep_uring_cmd(sqe: *mut io_uring_sqe, cmd_op: c_int, fd: c_int)
1552{
1553    __io_uring_prep_uring_cmd(sqe, IORING_OP_URING_CMD as _, cmd_op as _, fd);
1554}
1555
1556#[doc = include_str!("../docs/io_uring_prep_uring_cmd128.md")]
1557#[inline]
1558pub unsafe fn io_uring_prep_uring_cmd128(sqe: *mut io_uring_sqe, cmd_op: c_int, fd: c_int)
1559{
1560    __io_uring_prep_uring_cmd(sqe, IORING_OP_URING_CMD128 as _, cmd_op as _, fd);
1561}
1562
1563/*
1564 * Prepare commands for sockets
1565 */
1566#[doc = include_str!("../docs/io_uring_prep_cmd_sock.md")]
1567#[inline]
1568pub unsafe fn io_uring_prep_cmd_sock(sqe: *mut io_uring_sqe, cmd_op: c_int, fd: c_int,
1569                                     level: c_int, optname: c_int, optval: *mut c_void,
1570                                     optlen: c_int)
1571{
1572    io_uring_prep_uring_cmd(sqe, cmd_op as _, fd);
1573
1574    *(*sqe).__liburing_anon_6.optval.as_mut() = optval as usize as _;
1575    (*sqe).__liburing_anon_2.__liburing_anon_1.optname = optname as _;
1576    (*sqe).__liburing_anon_5.optlen = optlen as _;
1577    (*sqe).__liburing_anon_1.__liburing_anon_1.cmd_op = cmd_op as _;
1578    (*sqe).__liburing_anon_2.__liburing_anon_1.level = level as _;
1579}
1580
1581#[doc = include_str!("../docs/io_uring_prep_cmd_getsockname.md")]
1582#[inline]
1583pub unsafe fn io_uring_prep_cmd_getsockname(sqe: *mut io_uring_sqe, fd: c_int,
1584                                            sockaddr: *mut sockaddr, sockaddr_len: *mut socklen_t,
1585                                            peer: c_int)
1586{
1587    io_uring_prep_uring_cmd(sqe, SOCKET_URING_OP_GETSOCKNAME as _, fd);
1588
1589    (*sqe).__liburing_anon_2.addr = sockaddr as _;
1590    (*sqe).__liburing_anon_6.__liburing_anon_1.as_mut().addr3 = sockaddr_len as _;
1591    (*sqe).__liburing_anon_5.optlen = peer as _;
1592}
1593
1594#[doc = include_str!("../docs/io_uring_prep_waitid.md")]
1595#[inline]
1596pub unsafe fn io_uring_prep_waitid(sqe: *mut io_uring_sqe, idtype: idtype_t, id: id_t,
1597                                   infop: *mut siginfo_t, options: c_int, flags: c_uint)
1598{
1599    io_uring_prep_rw(IORING_OP_WAITID, sqe, id as _, ptr::null_mut(), idtype, 0);
1600    (*sqe).__liburing_anon_3.waitid_flags = flags;
1601    (*sqe).__liburing_anon_5.file_index = options as _;
1602    (*sqe).__liburing_anon_1.addr2 = infop as usize as u64;
1603}
1604
1605#[doc = include_str!("../docs/io_uring_prep_futex_wake.md")]
1606#[inline]
1607pub unsafe fn io_uring_prep_futex_wake(sqe: *mut io_uring_sqe, futex: *const u32, val: u64,
1608                                       mask: u64, futex_flags: u32, flags: c_uint)
1609{
1610    io_uring_prep_rw(IORING_OP_FUTEX_WAKE, sqe, futex_flags as _, futex.cast(), 0, val);
1611    (*sqe).__liburing_anon_3.futex_flags = flags;
1612    (*sqe).__liburing_anon_6.__liburing_anon_1.as_mut().addr3 = mask;
1613}
1614
1615#[doc = include_str!("../docs/io_uring_prep_futex_wait.md")]
1616#[inline]
1617pub unsafe fn io_uring_prep_futex_wait(sqe: *mut io_uring_sqe, futex: *const u32, val: u64,
1618                                       mask: u64, futex_flags: u32, flags: c_uint)
1619{
1620    io_uring_prep_rw(IORING_OP_FUTEX_WAIT, sqe, futex_flags as _, futex.cast(), 0, val);
1621    (*sqe).__liburing_anon_3.futex_flags = flags;
1622    (*sqe).__liburing_anon_6.__liburing_anon_1.as_mut().addr3 = mask;
1623}
1624
1625#[doc = include_str!("../docs/io_uring_prep_futex_waitv.md")]
1626#[inline]
1627pub unsafe fn io_uring_prep_futex_waitv(sqe: *mut io_uring_sqe, futex: *const futex_waitv,
1628                                        nr_futex: u32, flags: c_uint)
1629{
1630    io_uring_prep_rw(IORING_OP_FUTEX_WAITV, sqe, 0, futex.cast(), nr_futex, 0);
1631    (*sqe).__liburing_anon_3.futex_flags = flags;
1632}
1633
1634#[doc = include_str!("../docs/io_uring_prep_fixed_fd_install.md")]
1635#[inline]
1636pub unsafe fn io_uring_prep_fixed_fd_install(sqe: *mut io_uring_sqe, fd: c_int, flags: c_uint)
1637{
1638    io_uring_prep_rw(IORING_OP_FIXED_FD_INSTALL, sqe, fd, ptr::null_mut(), 0, 0);
1639
1640    (*sqe).flags = IOSQE_FIXED_FILE as _;
1641    (*sqe).__liburing_anon_3.install_fd_flags = flags;
1642}
1643
1644#[doc = include_str!("../docs/io_uring_prep_ftruncate.md")]
1645#[inline]
1646pub unsafe fn io_uring_prep_ftruncate(sqe: *mut io_uring_sqe, fd: c_int, len: c_longlong)
1647{
1648    io_uring_prep_rw(IORING_OP_FTRUNCATE, sqe, fd, ptr::null_mut(), 0, len as _);
1649}
1650
1651#[doc = include_str!("../docs/io_uring_prep_cmd_discard.md")]
1652#[inline]
1653pub unsafe fn io_uring_prep_cmd_discard(sqe: *mut io_uring_sqe, fd: c_int, offset: u64, nbytes: u64)
1654{
1655    // TODO: really someday fix this
1656    // We need bindgen to actually evaluate this macro's value during generation.
1657    // No idea if hard-coding this value like this is viable in practice.
1658    io_uring_prep_uring_cmd(sqe, ((0x12) << 8) as _ /* BLOCK_URING_CMD_DISCARD */, fd);
1659
1660    (*sqe).__liburing_anon_2.addr = offset;
1661    (*sqe).__liburing_anon_6.__liburing_anon_1.as_mut().addr3 = nbytes;
1662}
1663
1664#[doc = include_str!("../docs/io_uring_prep_pipe.md")]
1665#[inline]
1666pub unsafe fn io_uring_prep_pipe(sqe: *mut io_uring_sqe, fds: *mut c_int, pipe_flags: c_int)
1667{
1668    io_uring_prep_rw(IORING_OP_PIPE, sqe, 0, fds as *const _, 0, 0);
1669    (*sqe).__liburing_anon_3.pipe_flags = pipe_flags as u32;
1670}
1671
1672/* setup pipe directly into the fixed file table */
1673#[doc = include_str!("../docs/io_uring_prep_pipe_direct.md")]
1674#[inline]
1675pub unsafe fn io_uring_prep_pipe_direct(sqe: *mut io_uring_sqe, fds: *mut c_int,
1676                                        pipe_flags: c_int, mut file_index: c_uint)
1677{
1678    io_uring_prep_pipe(sqe, fds, pipe_flags);
1679    /* offset by 1 for allocation */
1680    if file_index == IORING_FILE_INDEX_ALLOC as u32 {
1681        file_index -= 1;
1682    }
1683    __io_uring_set_target_fixed_file(sqe, file_index);
1684}
1685
1686/* Read the kernel's SQ head index with appropriate memory ordering */
1687#[inline]
1688pub unsafe fn io_uring_load_sq_head(ring: *mut io_uring) -> c_uint
1689{
1690    /*
1691     * Without acquire ordering, we could overwrite a SQE before the kernel
1692     * finished reading it. We don't need the acquire ordering for
1693     * non-SQPOLL since then we drive updates.
1694     */
1695    if (*ring).flags & IORING_SETUP_SQPOLL > 0 {
1696        return io_uring_smp_load_acquire((*ring).sq.khead);
1697    }
1698
1699    *(*ring).sq.khead
1700}
1701
1702/*
1703 * Returns number of unconsumed (if SQPOLL) or unsubmitted entries exist in
1704 * the SQ ring
1705 */
1706#[doc = include_str!("../docs/io_uring_sq_ready.md")]
1707#[inline]
1708pub unsafe fn io_uring_sq_ready(ring: *mut io_uring) -> c_uint
1709{
1710    (*ring).sq.sqe_tail - io_uring_load_sq_head(ring)
1711}
1712
1713/*
1714 * Returns how much space is left in the SQ ring.
1715 */
1716#[doc = include_str!("../docs/io_uring_sq_space_left.md")]
1717#[inline]
1718pub unsafe fn io_uring_sq_space_left(ring: *mut io_uring) -> c_uint
1719{
1720    (*ring).sq.ring_entries - io_uring_sq_ready(ring)
1721}
1722
1723/*
1724 * Returns the bit shift needed to index the SQ.
1725 * This shift is 1 for rings with big SQEs, and 0 for rings with normal SQEs.
1726 * SQE `index` can be computed as &sq.sqes[(index & sq.ring_mask) << sqe_shift].
1727 */
1728#[must_use]
1729#[inline]
1730pub fn io_uring_sqe_shift_from_flags(flags: c_uint) -> c_uint
1731{
1732    u32::from(flags & IORING_SETUP_SQE128 != 0)
1733}
1734
1735#[inline]
1736pub unsafe fn io_uring_sqe_shift(ring: *mut io_uring) -> c_uint
1737{
1738    io_uring_sqe_shift_from_flags((*ring).flags)
1739}
1740
1741/*
1742 * Only applicable when using SQPOLL - allows the caller to wait for space
1743 * to free up in the SQ ring, which happens when the kernel side thread has
1744 * consumed one or more entries. If the SQ ring is currently non-full, no
1745 * action is taken. Note: may return -EINVAL if the kernel doesn't support
1746 * this feature.
1747 */
1748#[doc = include_str!("../docs/io_uring_sqring_wait.md")]
1749#[inline]
1750pub unsafe fn io_uring_sqring_wait(ring: *mut io_uring) -> c_int
1751{
1752    if (*ring).flags & IORING_SETUP_SQPOLL == 0 {
1753        return 0;
1754    }
1755    if io_uring_sq_space_left(ring) > 0 {
1756        return 0;
1757    }
1758
1759    __io_uring_sqring_wait(ring)
1760}
1761
1762/*
1763 * Returns how many unconsumed entries are ready in the CQ ring
1764 */
1765#[doc = include_str!("../docs/io_uring_cq_ready.md")]
1766#[inline]
1767pub unsafe fn io_uring_cq_ready(ring: *mut io_uring) -> c_uint
1768{
1769    io_uring_smp_load_acquire((*ring).cq.ktail) - *(*ring).cq.khead
1770}
1771
1772/*
1773 * Returns true if there are overflow entries waiting to be flushed onto
1774 * the CQ ring
1775 */
1776#[doc = include_str!("../docs/io_uring_cq_has_overflow.md")]
1777#[inline]
1778pub unsafe fn io_uring_cq_has_overflow(ring: *mut io_uring) -> bool
1779{
1780    IO_URING_READ_ONCE((*ring).sq.kflags) & IORING_SQ_CQ_OVERFLOW > 0
1781}
1782
1783/*
1784 * Returns true if the eventfd notification is currently enabled
1785 */
1786#[doc = include_str!("../docs/io_uring_cq_eventfd_enabled.md")]
1787#[inline]
1788pub unsafe fn io_uring_cq_eventfd_enabled(ring: *mut io_uring) -> bool
1789{
1790    if (*ring).cq.kflags.is_null() {
1791        return true;
1792    }
1793    (*(*ring).cq.kflags & IORING_CQ_EVENTFD_DISABLED) == 0
1794}
1795
1796/*
1797 * Toggle eventfd notification on or off, if an eventfd is registered with
1798 * the ring.
1799 */
1800#[doc = include_str!("../docs/io_uring_cq_eventfd_toggle.md")]
1801#[inline]
1802pub unsafe fn io_uring_cq_eventfd_toggle(ring: *mut io_uring, enabled: bool) -> c_int
1803{
1804    if enabled == io_uring_cq_eventfd_enabled(ring) {
1805        return 0;
1806    }
1807
1808    if (*ring).cq.kflags.is_null() {
1809        return -(EOPNOTSUPP as c_int);
1810    }
1811
1812    let mut flags = *(*ring).cq.kflags;
1813
1814    if enabled {
1815        flags &= !IORING_CQ_EVENTFD_DISABLED;
1816    } else {
1817        flags |= IORING_CQ_EVENTFD_DISABLED;
1818    }
1819
1820    IO_URING_WRITE_ONCE((*ring).cq.kflags, flags);
1821
1822    0
1823}
1824
1825/*
1826 * Return an IO completion, waiting for 'wait_nr' completions if one isn't
1827 * readily available. Returns 0 with cqe_ptr filled in on success, -errno on
1828 * failure.
1829 */
1830#[doc = include_str!("../docs/io_uring_wait_cqe_nr.md")]
1831#[inline]
1832pub unsafe fn io_uring_wait_cqe_nr(ring: *mut io_uring, cqe_ptr: *mut *mut io_uring_cqe,
1833                                   wait_nr: c_uint)
1834                                   -> c_int
1835{
1836    __io_uring_get_cqe(ring, cqe_ptr, 0, wait_nr, ptr::null_mut())
1837}
1838
1839#[inline]
1840unsafe fn io_uring_skip_cqe(ring: *mut io_uring, cqe: *mut io_uring_cqe, err: *mut c_int) -> bool
1841{
1842    'out: {
1843        if (*cqe).flags & IORING_CQE_F_SKIP != 0 {
1844            break 'out;
1845        }
1846
1847        if (*ring).features & IORING_FEAT_EXT_ARG != 0 {
1848            return false;
1849        }
1850
1851        if (*cqe).user_data != LIBURING_UDATA_TIMEOUT {
1852            return false;
1853        }
1854
1855        if (*cqe).res < 0 {
1856            *err = (*cqe).res;
1857        }
1858    }
1859
1860    io_uring_cq_advance(ring, io_uring_cqe_nr(cqe));
1861    *err == 0
1862}
1863
1864/*
1865 * Internal helper, don't use directly in applications. Use one of the
1866 * "official" versions of this, io_uring_peek_cqe(), io_uring_wait_cqe(),
1867 * or io_uring_wait_cqes*().
1868 */
1869#[inline]
1870unsafe fn __io_uring_peek_cqe(ring: *mut io_uring, cqe_ptr: *mut *mut io_uring_cqe,
1871                              nr_available: *mut c_uint)
1872                              -> c_int
1873{
1874    let mut cqe;
1875    let mut err = 0;
1876
1877    let mut available;
1878    let mask = (*ring).cq.ring_mask;
1879    let shift = io_uring_cqe_shift(ring);
1880
1881    loop {
1882        let tail = io_uring_smp_load_acquire((*ring).cq.ktail);
1883
1884        /*
1885         * The acquire ordering on the tail load pairs with the kernel
1886         * side publishing CQEs, and guarantees the contents of any
1887         * entry in [head, tail). The CQ head is only ever written by
1888         * the application, so a plain load is sufficient.
1889         */
1890        let head = *((*ring).cq.khead);
1891
1892        cqe = ptr::null_mut();
1893        available = tail - head;
1894        if available == 0 {
1895            break;
1896        }
1897
1898        cqe = &raw mut *(*ring).cq.cqes.add(((head & mask) << shift) as usize);
1899        if !io_uring_skip_cqe(ring, cqe, &raw mut err) {
1900            /*
1901             * If an error was set, the CQE was an internal
1902             * timeout and has already been consumed - don't
1903             * return a pointer to it.
1904             */
1905            if err != 0 {
1906                cqe = ptr::null_mut();
1907            }
1908            break;
1909        }
1910    }
1911
1912    *cqe_ptr = cqe;
1913    if !nr_available.is_null() {
1914        *nr_available = available;
1915    }
1916    err
1917}
1918
1919/*
1920 * Return an IO completion, if one is readily available. Returns 0 with
1921 * cqe_ptr filled in on success, -errno on failure.
1922 */
1923#[doc = include_str!("../docs/io_uring_peek_cqe.md")]
1924#[inline]
1925pub unsafe fn io_uring_peek_cqe(ring: *mut io_uring, cqe_ptr: *mut *mut io_uring_cqe) -> c_int
1926{
1927    if __io_uring_peek_cqe(ring, cqe_ptr, ptr::null_mut()) == 0 {
1928        if !(*cqe_ptr).is_null() {
1929            return 0;
1930        }
1931
1932        /*
1933         * If the CQ is empty and there's nothing the kernel could
1934         * flush to it (no IOPOLL completions to reap, no overflown
1935         * CQEs, no pending task work), avoid the round trip into
1936         * the full get_cqe machinery.
1937         */
1938        if ((*ring).flags & IORING_SETUP_IOPOLL) == 0
1939           && (IO_URING_READ_ONCE((*ring).sq.kflags) & (IORING_SQ_CQ_OVERFLOW | IORING_SQ_TASKRUN))
1940              == 0
1941        {
1942            return -(EAGAIN as c_int);
1943        }
1944    }
1945
1946    io_uring_wait_cqe_nr(ring, cqe_ptr, 0)
1947}
1948
1949/*
1950 * Return an IO completion, waiting for it if necessary. Returns 0 with
1951 * cqe_ptr filled in on success, -errno on failure.
1952 */
1953#[doc = include_str!("../docs/io_uring_wait_cqe.md")]
1954#[inline]
1955pub unsafe fn io_uring_wait_cqe(ring: *mut io_uring, cqe_ptr: *mut *mut io_uring_cqe) -> c_int
1956{
1957    if __io_uring_peek_cqe(ring, cqe_ptr, ptr::null_mut()) == 0 && !(*cqe_ptr).is_null() {
1958        return 0;
1959    }
1960
1961    io_uring_wait_cqe_nr(ring, cqe_ptr, 1)
1962}
1963
1964/*
1965 * Return an sqe to fill. Application must later call io_uring_submit()
1966 * when it's ready to tell the kernel about it. The caller may call this
1967 * function multiple times before calling io_uring_submit().
1968 *
1969 * Returns a vacant sqe, or NULL if we're full.
1970 */
1971#[inline]
1972unsafe fn _io_uring_get_sqe(ring: *mut io_uring) -> *mut io_uring_sqe
1973{
1974    let sq = &raw mut (*ring).sq;
1975
1976    let head = io_uring_load_sq_head(ring);
1977    let tail = (*sq).sqe_tail;
1978
1979    if tail - head >= (*sq).ring_entries {
1980        return ptr::null_mut();
1981    }
1982
1983    let offset = (tail & (*sq).ring_mask) << io_uring_sqe_shift(ring);
1984    let sqe = (*sq).sqes.add(offset as usize);
1985    (*sq).sqe_tail = tail + 1;
1986    io_uring_initialize_sqe(sqe);
1987    sqe
1988}
1989
1990/*
1991 * Return the appropriate mask for a buffer ring of size 'ring_entries'
1992 */
1993#[doc = include_str!("../docs/io_uring_buf_ring_mask.md")]
1994#[must_use]
1995#[inline]
1996pub fn io_uring_buf_ring_mask(ring_entries: u32) -> c_int
1997{
1998    (ring_entries - 1) as _
1999}
2000
2001#[doc = include_str!("../docs/io_uring_buf_ring_init.md")]
2002#[inline]
2003pub unsafe fn io_uring_buf_ring_init(br: *mut io_uring_buf_ring)
2004{
2005    (*br).__liburing_anon_1.__liburing_anon_1.as_mut().tail = 0;
2006}
2007
2008/*
2009 * Assign 'buf' with the addr/len/buffer ID supplied
2010 */
2011#[doc = include_str!("../docs/io_uring_buf_ring_add.md")]
2012#[inline]
2013pub unsafe fn io_uring_buf_ring_add(br: *mut io_uring_buf_ring, addr: *mut c_void, len: c_uint,
2014                                    bid: c_ushort, mask: c_int, buf_offset: c_int)
2015{
2016    let tail = (*br).__liburing_anon_1.__liburing_anon_1.as_ref().tail;
2017    let buf = (*br).__liburing_anon_1
2018                   .bufs
2019                   .as_mut()
2020                   .as_mut_ptr()
2021                   .add(((i32::from(tail) + buf_offset) & mask) as usize);
2022
2023    (*buf).addr = addr as usize as u64;
2024    (*buf).len = len;
2025    (*buf).bid = bid;
2026}
2027
2028/*
2029 * Make 'count' new buffers visible to the kernel. Called after
2030 * io_uring_buf_ring_add() has been called 'count' times to fill in new
2031 * buffers.
2032 */
2033#[doc = include_str!("../docs/io_uring_buf_ring_advance.md")]
2034#[inline]
2035pub unsafe fn io_uring_buf_ring_advance(br: *mut io_uring_buf_ring, count: c_int)
2036{
2037    let tail = (*br).__liburing_anon_1.__liburing_anon_1.as_ref().tail;
2038    let new_tail = tail.wrapping_add(count as u16);
2039
2040    io_uring_smp_store_release(&raw mut (*br).__liburing_anon_1.__liburing_anon_1.as_mut().tail,
2041                               new_tail);
2042}
2043
2044#[doc = include_str!("../docs/io_uring_buf_ring_cq_advance.md")]
2045#[inline]
2046pub unsafe fn __io_uring_buf_ring_cq_advance(ring: *mut io_uring, br: *mut io_uring_buf_ring,
2047                                             cq_count: i32, buf_count: c_int)
2048{
2049    io_uring_buf_ring_advance(br, buf_count);
2050    io_uring_cq_advance(ring, cq_count as _);
2051}
2052
2053/*
2054 * Make 'count' new buffers visible to the kernel while at the same time
2055 * advancing the CQ ring seen entries. This can be used when the application
2056 * is using ring provided buffers and returns buffers while processing CQEs,
2057 * avoiding an extra atomic when needing to increment both the CQ ring and
2058 * the ring buffer index at the same time.
2059 */
2060#[doc = include_str!("../docs/io_uring_buf_ring_cq_advance.md")]
2061#[inline]
2062pub unsafe fn io_uring_buf_ring_cq_advance(ring: *mut io_uring, br: *mut io_uring_buf_ring,
2063                                           count: c_int)
2064{
2065    __io_uring_buf_ring_cq_advance(ring, br, count, count);
2066}
2067
2068#[doc = include_str!("../docs/io_uring_buf_ring_available.md")]
2069#[inline]
2070pub unsafe fn io_uring_buf_ring_available(ring: *mut io_uring, br: *mut io_uring_buf_ring,
2071                                          bgid: c_ushort)
2072                                          -> c_int
2073{
2074    let mut head = 0;
2075    let ret = io_uring_buf_ring_head(ring, bgid.into(), &raw mut head);
2076    if ret > 0 {
2077        return ret;
2078    }
2079    c_int::from((*br).__liburing_anon_1.__liburing_anon_1.as_mut().tail - head)
2080}
2081
2082#[doc = include_str!("../docs/io_uring_get_sqe.md")]
2083#[inline]
2084pub unsafe fn io_uring_get_sqe(ring: *mut io_uring) -> *mut io_uring_sqe
2085{
2086    _io_uring_get_sqe(ring)
2087}
2088
2089/*
2090 * Return a 128B sqe to fill. Applications must later call io_uring_submit()
2091 * when it's ready to tell the kernel about it. The caller may call this
2092 * function multiple times before calling io_uring_submit().
2093 *
2094 * Returns a vacant 128B sqe, or NULL if we're full. If the current tail is the
2095 * last entry in the ring, this function will insert a nop + skip complete such
2096 * that the 128b entry wraps back to the beginning of the queue for a
2097 * contiguous big sq entry. It's up to the caller to use a 128b opcode in order
2098 * for the kernel to know how to advance its sq head pointer.
2099 */
2100#[doc = include_str!("../docs/io_uring_get_sqe128.md")]
2101#[inline]
2102pub unsafe fn io_uring_get_sqe128(ring: *mut io_uring) -> *mut io_uring_sqe
2103{
2104    let sq = &raw mut (*ring).sq;
2105
2106    let head = io_uring_load_sq_head(ring);
2107    let mut tail = (*sq).sqe_tail;
2108
2109    if (*ring).flags & IORING_SETUP_SQE128 != 0 {
2110        return io_uring_get_sqe(ring);
2111    }
2112
2113    if (*ring).flags & IORING_SETUP_SQE_MIXED == 0 {
2114        return ptr::null_mut();
2115    }
2116
2117    let mut sqe: *mut io_uring_sqe;
2118    if (tail + 1) & (*sq).ring_mask == 0 {
2119        if (tail + 2) - head >= (*sq).ring_entries {
2120            return ptr::null_mut();
2121        }
2122
2123        sqe = _io_uring_get_sqe(ring);
2124        io_uring_prep_nop(sqe);
2125        (*sqe).flags |= IOSQE_CQE_SKIP_SUCCESS as u8;
2126        tail = (*sq).sqe_tail;
2127    } else if (tail + 1) - head >= (*sq).ring_entries {
2128        return ptr::null_mut();
2129    }
2130
2131    sqe = &raw mut *(*sq).sqes.add((tail & (*sq).ring_mask) as usize);
2132    (*sq).sqe_tail = tail + 2;
2133    io_uring_initialize_sqe(sqe);
2134    sqe
2135}
2136
2137//-----------------------------------------------------------------------------
2138
2139impl From<Duration> for timespec
2140{
2141    #[cfg(not(any(target_arch = "powerpc", target_arch = "arm")))]
2142    #[inline]
2143    fn from(duration: Duration) -> Self
2144    {
2145        let mut ts = unsafe { zeroed::<timespec>() };
2146        ts.tv_sec = duration.as_secs() as _;
2147        ts.tv_nsec = duration.subsec_nanos().into();
2148        ts
2149    }
2150
2151    #[cfg(any(target_arch = "powerpc", target_arch = "arm"))]
2152    #[inline]
2153    fn from(duration: Duration) -> Self
2154    {
2155        let mut ts = unsafe { zeroed::<timespec>() };
2156        ts.tv_sec = duration.as_secs() as _;
2157        ts.tv_nsec = duration.subsec_nanos().try_into().unwrap();
2158        ts
2159    }
2160}
2161
2162impl From<Duration> for __kernel_timespec
2163{
2164    #[inline]
2165    fn from(duration: Duration) -> Self
2166    {
2167        let mut ts = unsafe { zeroed::<__kernel_timespec>() };
2168        ts.tv_sec = duration.as_secs() as _;
2169        ts.tv_nsec = duration.subsec_nanos().into();
2170        ts
2171    }
2172}