liburing_rs/
lib.rs

1#![allow(clippy::missing_safety_doc)]
2
3mod uring;
4
5use std::{
6    mem::{self, zeroed},
7    os::raw::{c_char, c_int, c_longlong, c_uint, c_ushort, c_void},
8    ptr,
9    sync::atomic::{
10        AtomicU16, AtomicU32,
11        Ordering::{self, Acquire, Relaxed, Release},
12    },
13    time::Duration,
14};
15
16pub use uring::*;
17
18const LIBURING_UDATA_TIMEOUT: u64 = u64::MAX;
19
20trait Atomic: Copy {
21    unsafe fn store(p: *mut Self, val: Self, order: Ordering);
22    unsafe fn load(p: *mut Self, order: Ordering) -> Self;
23}
24
25impl Atomic for u32 {
26    #[inline]
27    unsafe fn store(p: *mut u32, val: u32, order: Ordering) {
28        AtomicU32::from_ptr(p).store(val, order);
29    }
30
31    #[inline]
32    unsafe fn load(p: *mut u32, order: Ordering) -> u32 {
33        AtomicU32::from_ptr(p).load(order)
34    }
35}
36
37impl Atomic for u16 {
38    #[inline]
39    unsafe fn store(p: *mut u16, val: u16, order: Ordering) {
40        AtomicU16::from_ptr(p).store(val, order);
41    }
42
43    #[inline]
44    unsafe fn load(p: *mut u16, order: Ordering) -> u16 {
45        AtomicU16::from_ptr(p).load(order)
46    }
47}
48
49#[inline]
50unsafe fn io_uring_smp_store_release<T: Atomic>(p: *mut T, v: T) {
51    Atomic::store(p, v, Release);
52}
53
54#[inline]
55unsafe fn io_uring_smp_load_acquire<T: Atomic>(p: *const T) -> T {
56    Atomic::load(p as *mut T, Acquire)
57}
58
59#[inline]
60#[allow(non_snake_case)]
61unsafe fn IO_URING_READ_ONCE<T: Atomic>(var: *const T) -> T {
62    Atomic::load(var as *mut T, Relaxed)
63}
64
65#[inline]
66#[allow(non_snake_case)]
67unsafe fn IO_URING_WRITE_ONCE<T: Atomic>(var: *mut T, val: T) {
68    Atomic::store(var, val, Relaxed);
69}
70
71#[inline]
72unsafe fn __io_uring_peek_cqe(
73    ring: *mut io_uring,
74    cqe_ptr: *mut *mut io_uring_cqe,
75    nr_available: *mut c_uint,
76) -> c_int {
77    let mut cqe;
78    let mut err = 0;
79
80    let mut available;
81    let mask = (*ring).cq.ring_mask;
82    let shift = io_uring_cqe_shift(ring);
83
84    loop {
85        let tail = io_uring_smp_load_acquire((*ring).cq.ktail);
86        let head = *(*ring).cq.khead;
87
88        cqe = ptr::null_mut();
89        available = tail - head;
90        if available == 0 {
91            break;
92        }
93
94        cqe = &raw mut *(*ring).cq.cqes.add(((head & mask) << shift) as usize);
95        if ((*ring).features & IORING_FEAT_EXT_ARG) == 0
96            && (*cqe).user_data == LIBURING_UDATA_TIMEOUT
97        {
98            if (*cqe).res < 0 {
99                err = (*cqe).res;
100            }
101            io_uring_cq_advance(ring, 1);
102            if err == 0 {
103                continue;
104            }
105            cqe = ptr::null_mut();
106        }
107
108        break;
109    }
110
111    *cqe_ptr = cqe;
112    if !nr_available.is_null() {
113        *nr_available = available;
114    }
115    err
116}
117
118#[inline]
119#[no_mangle]
120pub unsafe extern "C" fn io_uring_cqe_shift_from_flags(flags: c_uint) -> c_uint {
121    if flags & IORING_SETUP_CQE32 > 0 {
122        1
123    } else {
124        0
125    }
126}
127
128#[inline]
129#[no_mangle]
130pub unsafe extern "C" fn io_uring_cqe_shift(ring: *mut io_uring) -> c_uint {
131    io_uring_cqe_shift_from_flags((*ring).flags)
132}
133
134#[inline]
135#[no_mangle]
136pub unsafe extern "C" fn io_uring_cqe_iter_init(ring: *mut io_uring) -> io_uring_cqe_iter {
137    io_uring_cqe_iter {
138        cqes: (*ring).cq.cqes,
139        mask: (*ring).cq.ring_mask,
140        shift: io_uring_cqe_shift(ring),
141        head: *(*ring).cq.khead,
142        tail: io_uring_smp_load_acquire((*ring).cq.ktail),
143    }
144}
145
146#[inline]
147#[no_mangle]
148pub unsafe extern "C" fn io_uring_cqe_iter_next(
149    iter: *mut io_uring_cqe_iter,
150    cqe: *mut *mut io_uring_cqe,
151) -> bool {
152    if (*iter).head == (*iter).tail {
153        return false;
154    }
155
156    let head = (*iter).head;
157    (*iter).head += 1;
158
159    let offset = (head & (*iter).mask) << (*iter).shift;
160    *cqe = (*iter).cqes.add(offset as usize);
161
162    true
163}
164
165#[inline]
166#[no_mangle]
167pub unsafe extern "C" fn io_uring_peek_cqe(
168    ring: *mut io_uring,
169    cqe_ptr: *mut *mut io_uring_cqe,
170) -> c_int {
171    if __io_uring_peek_cqe(ring, cqe_ptr, ptr::null_mut()) == 0 && !(*cqe_ptr).is_null() {
172        return 0;
173    }
174
175    io_uring_wait_cqe_nr(ring, cqe_ptr, 0)
176}
177
178#[inline]
179#[no_mangle]
180pub unsafe extern "C" fn io_uring_opcode_supported(p: *mut io_uring_probe, op: c_int) -> c_int {
181    if op > (*p).last_op as _ {
182        return 0;
183    }
184
185    if (*(*p).ops.as_ptr().add(op as _)).flags & IO_URING_OP_SUPPORTED as u16 != 0 {
186        1
187    } else {
188        0
189    }
190}
191
192#[inline]
193#[no_mangle]
194pub unsafe extern "C" fn io_uring_cq_advance(ring: *mut io_uring, nr: c_uint) {
195    if nr > 0 {
196        let cq = &raw mut (*ring).cq;
197
198        /*
199         * Ensure that the kernel only sees the new value of the head
200         * index after the CQEs have been read.
201         */
202        io_uring_smp_store_release((*cq).khead, *(*cq).khead + nr);
203    }
204}
205
206#[inline]
207#[no_mangle]
208pub unsafe extern "C" fn io_uring_cqe_seen(ring: *mut io_uring, cqe: *mut io_uring_cqe) {
209    if !cqe.is_null() {
210        io_uring_cq_advance(ring, 1);
211    }
212}
213
214#[inline]
215#[no_mangle]
216pub unsafe extern "C" fn io_uring_buf_ring_mask(ring_entries: u32) -> c_int {
217    (ring_entries - 1) as _
218}
219
220#[inline]
221#[no_mangle]
222pub unsafe extern "C" fn io_uring_buf_ring_add(
223    br: *mut io_uring_buf_ring,
224    addr: *mut c_void,
225    len: c_uint,
226    bid: c_ushort,
227    mask: c_int,
228    buf_offset: c_int,
229) {
230    let tail = (*br).__liburing_anon_1.__liburing_anon_1.as_ref().tail;
231    let buf = (*br)
232        .__liburing_anon_1
233        .bufs
234        .as_mut()
235        .as_mut_ptr()
236        .add(((tail as i32 + buf_offset) & mask) as usize);
237
238    (*buf).addr = addr as usize as u64;
239    (*buf).len = len;
240    (*buf).bid = bid;
241}
242
243#[inline]
244#[no_mangle]
245pub unsafe extern "C" fn io_uring_buf_ring_advance(br: *mut io_uring_buf_ring, count: c_int) {
246    let tail = (*br).__liburing_anon_1.__liburing_anon_1.as_ref().tail;
247    let new_tail = tail.wrapping_add(count as u16);
248
249    io_uring_smp_store_release(
250        &mut (*br).__liburing_anon_1.__liburing_anon_1.as_mut().tail,
251        new_tail,
252    );
253}
254
255#[inline]
256#[no_mangle]
257pub unsafe extern "C" fn io_uring_buf_ring_available(
258    ring: *mut io_uring,
259    br: *mut io_uring_buf_ring,
260    bgid: c_ushort,
261) -> c_int {
262    let mut head = 0;
263    let ret = io_uring_buf_ring_head(ring, bgid as _, &raw mut head);
264    if ret > 0 {
265        return ret;
266    }
267    ((*br).__liburing_anon_1.__liburing_anon_1.as_mut().tail - head) as c_int
268}
269
270#[inline]
271unsafe fn io_uring_initialize_sqe(sqe: *mut io_uring_sqe) {
272    (*sqe).flags = 0;
273    (*sqe).ioprio = 0;
274    (*sqe).__liburing_anon_3.rw_flags = 0;
275    (*sqe).__liburing_anon_4.buf_index = 0;
276    (*sqe).personality = 0;
277    (*sqe).__liburing_anon_5.file_index = 0;
278    (*sqe).__liburing_anon_6.__liburing_anon_1.as_mut().addr3 = 0;
279    (*sqe).__liburing_anon_6.__liburing_anon_1.as_mut().__pad2[0] = 0;
280}
281
282#[inline]
283unsafe fn _io_uring_get_sqe(ring: *mut io_uring) -> *mut io_uring_sqe {
284    let sq = &raw mut (*ring).sq;
285
286    let head = io_uring_load_sq_head(ring);
287    let tail = (*sq).sqe_tail;
288
289    if tail - head >= (*sq).ring_entries {
290        return ptr::null_mut();
291    }
292
293    let offset = (tail & (*sq).ring_mask) << io_uring_sqe_shift(ring);
294    let sqe = (*sq).sqes.add(offset as usize);
295    (*sq).sqe_tail = tail + 1;
296    io_uring_initialize_sqe(sqe);
297    sqe
298}
299
300#[inline]
301#[no_mangle]
302pub unsafe extern "C" fn io_uring_get_sqe(ring: *mut io_uring) -> *mut io_uring_sqe {
303    _io_uring_get_sqe(ring)
304}
305
306#[inline]
307#[no_mangle]
308pub unsafe extern "C" fn io_uring_sqe_set_data(sqe: *mut io_uring_sqe, data: *mut c_void) {
309    (*sqe).user_data = data as u64;
310}
311
312#[inline]
313#[no_mangle]
314pub unsafe extern "C" fn io_uring_sqe_set_data64(sqe: *mut io_uring_sqe, data: u64) {
315    (*sqe).user_data = data;
316}
317
318#[inline]
319#[no_mangle]
320pub unsafe extern "C" fn io_uring_sqe_set_flags(sqe: *mut io_uring_sqe, flags: c_uint) {
321    (*sqe).flags = flags as u8;
322}
323
324#[inline]
325#[no_mangle]
326pub unsafe extern "C" fn io_uring_sqe_set_buf_group(sqe: *mut io_uring_sqe, bgid: c_int) {
327    (*sqe).__liburing_anon_4.buf_group = bgid as u16;
328}
329
330#[inline]
331#[no_mangle]
332unsafe fn __io_uring_set_target_fixed_file(sqe: *mut io_uring_sqe, file_index: c_uint) {
333    (*sqe).__liburing_anon_5.file_index = file_index + 1;
334}
335
336#[inline]
337#[no_mangle]
338pub unsafe extern "C" fn io_uring_cqe_get_data(cqe: *const io_uring_cqe) -> *mut c_void {
339    (*cqe).user_data as *mut c_void
340}
341
342#[inline]
343#[no_mangle]
344pub unsafe extern "C" fn io_uring_wait_cqe_nr(
345    ring: *mut io_uring,
346    cqe_ptr: *mut *mut io_uring_cqe,
347    wait_nr: c_uint,
348) -> c_int {
349    __io_uring_get_cqe(ring, cqe_ptr, 0, wait_nr, ptr::null_mut())
350}
351
352#[inline]
353#[no_mangle]
354pub unsafe extern "C" fn io_uring_wait_cqe(
355    ring: *mut io_uring,
356    cqe_ptr: *mut *mut io_uring_cqe,
357) -> c_int {
358    if __io_uring_peek_cqe(ring, cqe_ptr, ptr::null_mut()) == 0 && !(*cqe_ptr).is_null() {
359        return 0;
360    }
361
362    io_uring_wait_cqe_nr(ring, cqe_ptr, 1)
363}
364
365#[inline]
366#[no_mangle]
367pub unsafe extern "C" fn io_uring_cq_ready(ring: *mut io_uring) -> c_uint {
368    io_uring_smp_load_acquire((*ring).cq.ktail) - *(*ring).cq.khead
369}
370
371#[inline]
372#[no_mangle]
373pub unsafe extern "C" fn io_uring_cq_has_overflow(ring: *mut io_uring) -> bool {
374    IO_URING_READ_ONCE((*ring).sq.kflags) & IORING_SQ_CQ_OVERFLOW > 0
375}
376
377#[inline]
378#[no_mangle]
379pub unsafe extern "C" fn io_uring_prep_rw(
380    op: c_int,
381    sqe: *mut io_uring_sqe,
382    fd: c_int,
383    addr: *const c_void,
384    len: c_uint,
385    offset: __u64,
386) {
387    (*sqe).opcode = op as u8;
388    (*sqe).fd = fd;
389    (*sqe).__liburing_anon_1.off = offset;
390    (*sqe).__liburing_anon_2.addr = addr as u64;
391    (*sqe).len = len;
392}
393
394#[inline]
395#[no_mangle]
396pub unsafe extern "C" fn io_uring_prep_read(
397    sqe: *mut io_uring_sqe,
398    fd: c_int,
399    buf: *mut c_void,
400    nbytes: c_uint,
401    offset: u64,
402) {
403    io_uring_prep_rw(
404        io_uring_op_IORING_OP_READ as _,
405        sqe,
406        fd,
407        buf,
408        nbytes,
409        offset,
410    );
411}
412
413#[inline]
414#[no_mangle]
415pub unsafe extern "C" fn io_uring_prep_readv(
416    sqe: *mut io_uring_sqe,
417    fd: c_int,
418    iovecs: *const iovec,
419    nr_vecs: c_uint,
420    offset: u64,
421) {
422    io_uring_prep_rw(
423        io_uring_op_IORING_OP_READV as _,
424        sqe,
425        fd,
426        iovecs.cast(),
427        nr_vecs,
428        offset,
429    );
430}
431
432#[inline]
433#[no_mangle]
434pub unsafe extern "C" fn io_uring_prep_read_fixed(
435    sqe: *mut io_uring_sqe,
436    fd: c_int,
437    buf: *mut c_void,
438    nbytes: c_uint,
439    offset: u64,
440    buf_index: c_int,
441) {
442    io_uring_prep_rw(
443        io_uring_op_IORING_OP_READ_FIXED as _,
444        sqe,
445        fd,
446        buf,
447        nbytes,
448        offset,
449    );
450    (*sqe).__liburing_anon_4.buf_index = buf_index as u16;
451}
452
453#[inline]
454#[no_mangle]
455pub unsafe extern "C" fn io_uring_prep_read_multishot(
456    sqe: *mut io_uring_sqe,
457    fd: c_int,
458    nbytes: c_uint,
459    offset: u64,
460    buf_group: c_int,
461) {
462    io_uring_prep_rw(
463        io_uring_op_IORING_OP_READ_MULTISHOT as _,
464        sqe,
465        fd,
466        ptr::null_mut(),
467        nbytes,
468        offset,
469    );
470    (*sqe).__liburing_anon_4.buf_group = buf_group as _;
471    (*sqe).flags = IOSQE_BUFFER_SELECT as _;
472}
473
474#[inline]
475#[no_mangle]
476pub unsafe extern "C" fn io_uring_prep_recv(
477    sqe: *mut io_uring_sqe,
478    sockfd: c_int,
479    buf: *mut c_void,
480    len: usize,
481    flags: c_int,
482) {
483    io_uring_prep_rw(
484        io_uring_op_IORING_OP_RECV as _,
485        sqe,
486        sockfd,
487        buf,
488        len as u32,
489        0,
490    );
491    (*sqe).__liburing_anon_3.msg_flags = flags as u32;
492}
493
494#[inline]
495#[no_mangle]
496pub unsafe extern "C" fn io_uring_prep_recv_multishot(
497    sqe: *mut io_uring_sqe,
498    sockfd: c_int,
499    buf: *mut c_void,
500    len: usize,
501    flags: c_int,
502) {
503    io_uring_prep_recv(sqe, sockfd, buf, len, flags);
504    (*sqe).ioprio |= IORING_RECV_MULTISHOT as u16;
505}
506
507#[inline]
508#[no_mangle]
509pub unsafe extern "C" fn io_uring_prep_recvmsg(
510    sqe: *mut io_uring_sqe,
511    fd: c_int,
512    msg: *mut msghdr,
513    flags: c_uint,
514) {
515    io_uring_prep_rw(
516        io_uring_op_IORING_OP_RECVMSG as _,
517        sqe,
518        fd,
519        msg.cast(),
520        1,
521        0,
522    );
523    (*sqe).__liburing_anon_3.msg_flags = flags;
524}
525
526#[inline]
527#[no_mangle]
528pub unsafe extern "C" fn io_uring_prep_recvmsg_multishot(
529    sqe: *mut io_uring_sqe,
530    fd: c_int,
531    msg: *mut msghdr,
532    flags: c_uint,
533) {
534    io_uring_prep_recvmsg(sqe, fd, msg, flags);
535    (*sqe).ioprio |= IORING_RECV_MULTISHOT as u16;
536}
537
538#[inline]
539#[no_mangle]
540pub unsafe extern "C" fn io_uring_recvmsg_validate(
541    buf: *mut c_void,
542    buf_len: c_int,
543    msgh: *mut msghdr,
544) -> *mut io_uring_recvmsg_out {
545    let header = (*msgh).msg_controllen
546        + (*msgh).msg_namelen as usize
547        + mem::size_of::<io_uring_recvmsg_out>();
548
549    if buf_len < 0 || (buf_len as usize) < header {
550        return ptr::null_mut();
551    }
552
553    buf.cast()
554}
555
556#[inline]
557#[no_mangle]
558pub unsafe extern "C" fn io_uring_recvmsg_name(o: *mut io_uring_recvmsg_out) -> *mut c_void {
559    o.add(1).cast()
560}
561
562#[inline]
563#[no_mangle]
564pub unsafe extern "C" fn io_uring_recvmsg_cmsg_firsthdr(
565    o: *mut io_uring_recvmsg_out,
566    msgh: *mut msghdr,
567) -> *mut cmsghdr {
568    if ((*o).controllen as usize) < mem::size_of::<cmsghdr>() {
569        return ptr::null_mut();
570    }
571
572    io_uring_recvmsg_name(o)
573        .cast::<u8>()
574        .add((*msgh).msg_namelen as _)
575        .cast()
576}
577
578#[inline]
579#[no_mangle]
580pub unsafe extern "C" fn io_uring_recvmsg_cmsg_nexthdr(
581    o: *mut io_uring_recvmsg_out,
582    msgh: *mut msghdr,
583    cmsg: *mut cmsghdr,
584) -> *mut cmsghdr {
585    #[allow(non_snake_case)]
586    fn CMSG_ALIGN(len: usize) -> usize {
587        ((len) + mem::size_of::<usize>() - 1) & !(mem::size_of::<usize>() - 1)
588    }
589
590    if (*cmsg).cmsg_len < mem::size_of::<cmsghdr>() {
591        return ptr::null_mut();
592    }
593
594    let end = io_uring_recvmsg_cmsg_firsthdr(o, msgh)
595        .cast::<u8>()
596        .add((*o).controllen as _);
597
598    let cmsg = cmsg
599        .cast::<u8>()
600        .add(CMSG_ALIGN((*cmsg).cmsg_len))
601        .cast::<cmsghdr>();
602
603    if cmsg.add(1).cast::<u8>() > end {
604        return ptr::null_mut();
605    }
606
607    if cmsg.cast::<u8>().add(CMSG_ALIGN((*cmsg).cmsg_len)) > end {
608        return ptr::null_mut();
609    }
610
611    cmsg
612}
613
614#[inline]
615#[no_mangle]
616pub unsafe extern "C" fn io_uring_recvmsg_payload(
617    o: *mut io_uring_recvmsg_out,
618    msgh: *mut msghdr,
619) -> *mut c_void {
620    io_uring_recvmsg_name(o)
621        .cast::<u8>()
622        .add((*msgh).msg_namelen as usize + (*msgh).msg_controllen)
623        .cast::<c_void>()
624}
625
626#[inline]
627#[no_mangle]
628pub unsafe extern "C" fn io_uring_recvmsg_payload_length(
629    o: *mut io_uring_recvmsg_out,
630    buf_len: c_int,
631    msgh: *mut msghdr,
632) -> c_uint {
633    let payload_start = io_uring_recvmsg_payload(o, msgh) as usize;
634    let payload_end = o as usize + buf_len as usize;
635    (payload_end - payload_start) as _
636}
637
638#[inline]
639#[no_mangle]
640pub unsafe extern "C" fn io_uring_prep_writev(
641    sqe: *mut io_uring_sqe,
642    fd: c_int,
643    iovecs: *const iovec,
644    nr_vecs: c_uint,
645    offset: u64,
646) {
647    io_uring_prep_rw(
648        io_uring_op_IORING_OP_WRITEV as _,
649        sqe,
650        fd,
651        iovecs.cast(),
652        nr_vecs,
653        offset,
654    );
655}
656
657#[inline]
658#[no_mangle]
659pub unsafe extern "C" fn io_uring_prep_write_fixed(
660    sqe: *mut io_uring_sqe,
661    fd: c_int,
662    buf: *const c_void,
663    nbytes: c_uint,
664    offset: u64,
665    buf_index: c_int,
666) {
667    io_uring_prep_rw(
668        io_uring_op_IORING_OP_WRITE_FIXED as _,
669        sqe,
670        fd,
671        buf,
672        nbytes,
673        offset,
674    );
675    (*sqe).__liburing_anon_4.buf_index = buf_index as u16;
676}
677
678#[inline]
679#[no_mangle]
680pub unsafe extern "C" fn io_uring_prep_provide_buffers(
681    sqe: *mut io_uring_sqe,
682    addr: *mut c_void,
683    len: c_int,
684    nr: c_int,
685    bgid: c_int,
686    bid: c_int,
687) {
688    io_uring_prep_rw(
689        io_uring_op_IORING_OP_PROVIDE_BUFFERS as _,
690        sqe,
691        nr,
692        addr,
693        len as u32,
694        bid as u64,
695    );
696    (*sqe).__liburing_anon_4.buf_group = bgid as u16;
697}
698
699#[inline]
700#[no_mangle]
701pub unsafe extern "C" fn io_uring_prep_remove_buffers(
702    sqe: *mut io_uring_sqe,
703    nr: c_int,
704    bgid: c_int,
705) {
706    io_uring_prep_rw(
707        io_uring_op_IORING_OP_REMOVE_BUFFERS as _,
708        sqe,
709        nr,
710        ptr::null_mut(),
711        0,
712        0,
713    );
714    (*sqe).__liburing_anon_4.buf_group = bgid as u16;
715}
716
717#[inline]
718#[no_mangle]
719pub unsafe extern "C" fn io_uring_prep_write(
720    sqe: *mut io_uring_sqe,
721    fd: c_int,
722    buf: *const c_void,
723    nbytes: c_uint,
724    offset: u64,
725) {
726    io_uring_prep_rw(
727        io_uring_op_IORING_OP_WRITE as _,
728        sqe,
729        fd,
730        buf,
731        nbytes,
732        offset,
733    );
734}
735
736#[inline]
737unsafe fn __io_uring_prep_poll_mask(poll_mask: c_uint) -> c_uint {
738    poll_mask.to_le()
739}
740
741#[inline]
742#[no_mangle]
743pub unsafe extern "C" fn io_uring_prep_poll_add(
744    sqe: *mut io_uring_sqe,
745    fd: c_int,
746    poll_mask: c_uint,
747) {
748    io_uring_prep_rw(
749        io_uring_op_IORING_OP_POLL_ADD as _,
750        sqe,
751        fd,
752        ptr::null_mut(),
753        0,
754        0,
755    );
756    (*sqe).__liburing_anon_3.poll32_events = __io_uring_prep_poll_mask(poll_mask);
757}
758
759#[inline]
760#[no_mangle]
761pub unsafe extern "C" fn io_uring_prep_poll_remove(sqe: *mut io_uring_sqe, user_data: u64) {
762    io_uring_prep_rw(
763        io_uring_op_IORING_OP_POLL_REMOVE as _,
764        sqe,
765        -1,
766        ptr::null_mut(),
767        0,
768        0,
769    );
770    (*sqe).__liburing_anon_2.addr = user_data;
771}
772
773#[inline]
774#[no_mangle]
775pub unsafe extern "C" fn io_uring_prep_poll_update(
776    sqe: *mut io_uring_sqe,
777    old_user_data: u64,
778    new_user_data: u64,
779    poll_mask: c_uint,
780    flags: c_uint,
781) {
782    io_uring_prep_rw(
783        io_uring_op_IORING_OP_POLL_REMOVE as _,
784        sqe,
785        -1,
786        ptr::null_mut(),
787        flags,
788        new_user_data,
789    );
790    (*sqe).__liburing_anon_2.addr = old_user_data;
791    (*sqe).__liburing_anon_3.poll32_events = __io_uring_prep_poll_mask(poll_mask);
792}
793
794#[inline]
795#[no_mangle]
796pub unsafe extern "C" fn io_uring_prep_poll_multishot(
797    sqe: *mut io_uring_sqe,
798    fd: c_int,
799    poll_mask: c_uint,
800) {
801    io_uring_prep_poll_add(sqe, fd, poll_mask);
802    (*sqe).len = IORING_POLL_ADD_MULTI;
803}
804
805#[inline]
806#[no_mangle]
807pub unsafe extern "C" fn io_uring_prep_epoll_ctl(
808    sqe: *mut io_uring_sqe,
809    epfd: c_int,
810    fd: c_int,
811    op: c_int,
812    ev: *mut epoll_event,
813) {
814    io_uring_prep_rw(
815        io_uring_op_IORING_OP_EPOLL_CTL as _,
816        sqe,
817        epfd,
818        ev.cast(),
819        op as u32,
820        fd as u32 as u64,
821    );
822}
823
824#[inline]
825#[no_mangle]
826pub unsafe extern "C" fn io_uring_prep_fsync(
827    sqe: *mut io_uring_sqe,
828    fd: c_int,
829    fsync_flags: c_uint,
830) {
831    io_uring_prep_rw(
832        io_uring_op_IORING_OP_FSYNC as _,
833        sqe,
834        fd,
835        ptr::null_mut(),
836        0,
837        0,
838    );
839    (*sqe).__liburing_anon_3.fsync_flags = fsync_flags;
840}
841
842#[inline]
843#[no_mangle]
844pub unsafe extern "C" fn io_uring_prep_msg_ring_fd(
845    sqe: *mut io_uring_sqe,
846    fd: c_int,
847    source_fd: c_int,
848    mut target_fd: c_int,
849    data: u64,
850    flags: c_uint,
851) {
852    io_uring_prep_rw(
853        io_uring_op_IORING_OP_MSG_RING as _,
854        sqe,
855        fd,
856        io_uring_msg_ring_flags_IORING_MSG_SEND_FD as usize as *const c_void,
857        0,
858        data,
859    );
860
861    (*sqe).__liburing_anon_6.__liburing_anon_1.as_mut().addr3 = source_fd as _;
862
863    if target_fd == IORING_FILE_INDEX_ALLOC as _ {
864        target_fd -= 1;
865    }
866    __io_uring_set_target_fixed_file(sqe, target_fd as _);
867    (*sqe).__liburing_anon_3.msg_ring_flags = flags;
868}
869
870#[inline]
871#[no_mangle]
872pub unsafe extern "C" fn io_uring_prep_msg_ring_fd_alloc(
873    sqe: *mut io_uring_sqe,
874    fd: c_int,
875    source_fd: c_int,
876    data: u64,
877    flags: c_uint,
878) {
879    io_uring_prep_msg_ring_fd(sqe, fd, source_fd, IORING_FILE_INDEX_ALLOC, data, flags);
880}
881
882#[inline]
883#[no_mangle]
884pub unsafe extern "C" fn io_uring_prep_openat(
885    sqe: *mut io_uring_sqe,
886    dfd: c_int,
887    path: *const c_char,
888    flags: c_int,
889    mode: mode_t,
890) {
891    io_uring_prep_rw(
892        io_uring_op_IORING_OP_OPENAT as _,
893        sqe,
894        dfd,
895        path.cast(),
896        mode,
897        0,
898    );
899    (*sqe).__liburing_anon_3.open_flags = flags as u32;
900}
901
902#[inline]
903#[no_mangle]
904pub unsafe extern "C" fn io_uring_prep_openat_direct(
905    sqe: *mut io_uring_sqe,
906    dfd: c_int,
907    path: *const c_char,
908    flags: c_int,
909    mode: mode_t,
910    mut file_index: c_uint,
911) {
912    io_uring_prep_openat(sqe, dfd, path, flags, mode);
913    if file_index == IORING_FILE_INDEX_ALLOC as _ {
914        file_index -= 1;
915    }
916    __io_uring_set_target_fixed_file(sqe, file_index);
917}
918
919#[inline]
920#[no_mangle]
921pub unsafe extern "C" fn io_uring_prep_openat2(
922    sqe: *mut io_uring_sqe,
923    dfd: c_int,
924    path: *const c_char,
925    how: *mut open_how,
926) {
927    io_uring_prep_rw(
928        io_uring_op_IORING_OP_OPENAT2 as _,
929        sqe,
930        dfd,
931        path.cast(),
932        mem::size_of::<open_how>() as u32,
933        how as usize as u64,
934    );
935}
936
937#[inline]
938#[no_mangle]
939pub unsafe extern "C" fn io_uring_prep_openat2_direct(
940    sqe: *mut io_uring_sqe,
941    dfd: c_int,
942    path: *const c_char,
943    how: *mut open_how,
944    mut file_index: c_uint,
945) {
946    io_uring_prep_openat2(sqe, dfd, path, how);
947    if file_index == IORING_FILE_INDEX_ALLOC as _ {
948        file_index -= 1;
949    }
950    __io_uring_set_target_fixed_file(sqe, file_index);
951}
952
953#[inline]
954#[no_mangle]
955pub unsafe extern "C" fn io_uring_prep_files_update(
956    sqe: *mut io_uring_sqe,
957    fds: *mut c_int,
958    nr_fds: c_uint,
959    offset: c_int,
960) {
961    io_uring_prep_rw(
962        io_uring_op_IORING_OP_FILES_UPDATE as _,
963        sqe,
964        -1,
965        fds.cast(),
966        nr_fds,
967        offset as u64,
968    );
969}
970
971#[inline]
972#[no_mangle]
973pub unsafe extern "C" fn io_uring_prep_fallocate(
974    sqe: *mut io_uring_sqe,
975    fd: c_int,
976    mode: c_int,
977    offset: u64,
978    len: u64,
979) {
980    io_uring_prep_rw(
981        io_uring_op_IORING_OP_FALLOCATE as _,
982        sqe,
983        fd,
984        ptr::null_mut(),
985        mode as c_uint,
986        offset,
987    );
988    (*sqe).__liburing_anon_2.addr = len;
989}
990
991#[inline]
992#[no_mangle]
993pub unsafe extern "C" fn io_uring_prep_unlinkat(
994    sqe: *mut io_uring_sqe,
995    dfd: c_int,
996    path: *const c_char,
997    flags: c_int,
998) {
999    io_uring_prep_rw(
1000        io_uring_op_IORING_OP_UNLINKAT as _,
1001        sqe,
1002        dfd,
1003        path.cast(),
1004        0,
1005        0,
1006    );
1007    (*sqe).__liburing_anon_3.unlink_flags = flags as u32;
1008}
1009
1010#[inline]
1011#[no_mangle]
1012pub unsafe extern "C" fn io_uring_prep_unlink(
1013    sqe: *mut io_uring_sqe,
1014    path: *const c_char,
1015    flags: c_int,
1016) {
1017    io_uring_prep_unlinkat(sqe, AT_FDCWD, path, flags);
1018}
1019
1020#[inline]
1021#[no_mangle]
1022pub unsafe extern "C" fn io_uring_prep_getxattr(
1023    sqe: *mut io_uring_sqe,
1024    name: *const c_char,
1025    value: *mut c_char,
1026    path: *const c_char,
1027    len: c_uint,
1028) {
1029    io_uring_prep_rw(
1030        io_uring_op_IORING_OP_GETXATTR as _,
1031        sqe,
1032        0,
1033        name.cast(),
1034        len,
1035        value as usize as u64,
1036    );
1037    (*sqe).__liburing_anon_6.__liburing_anon_1.as_mut().addr3 = path as usize as u64;
1038
1039    (*sqe).__liburing_anon_3.xattr_flags = 0;
1040}
1041
1042#[inline]
1043#[no_mangle]
1044pub unsafe extern "C" fn io_uring_prep_setxattr(
1045    sqe: *mut io_uring_sqe,
1046    name: *const c_char,
1047    value: *const c_char,
1048    path: *const c_char,
1049    flags: c_int,
1050    len: c_uint,
1051) {
1052    io_uring_prep_rw(
1053        io_uring_op_IORING_OP_SETXATTR as _,
1054        sqe,
1055        0,
1056        name.cast(),
1057        len,
1058        value as usize as u64,
1059    );
1060    (*sqe).__liburing_anon_6.__liburing_anon_1.as_mut().addr3 = path as usize as u64;
1061    (*sqe).__liburing_anon_3.xattr_flags = flags as _;
1062}
1063
1064#[inline]
1065#[no_mangle]
1066pub unsafe extern "C" fn io_uring_prep_fgetxattr(
1067    sqe: *mut io_uring_sqe,
1068    fd: c_int,
1069    name: *const c_char,
1070    value: *mut c_char,
1071    len: c_uint,
1072) {
1073    io_uring_prep_rw(
1074        io_uring_op_IORING_OP_FGETXATTR as _,
1075        sqe,
1076        fd,
1077        name.cast(),
1078        len,
1079        value as usize as u64,
1080    );
1081    (*sqe).__liburing_anon_3.xattr_flags = 0;
1082}
1083
1084#[inline]
1085#[no_mangle]
1086pub unsafe extern "C" fn io_uring_prep_fsetxattr(
1087    sqe: *mut io_uring_sqe,
1088    fd: c_int,
1089    name: *const c_char,
1090    value: *mut c_char,
1091    flags: c_int,
1092    len: c_uint,
1093) {
1094    io_uring_prep_rw(
1095        io_uring_op_IORING_OP_FSETXATTR as _,
1096        sqe,
1097        fd,
1098        name.cast(),
1099        len,
1100        value as usize as u64,
1101    );
1102    (*sqe).__liburing_anon_3.xattr_flags = flags as _;
1103}
1104
1105#[inline]
1106#[no_mangle]
1107pub unsafe extern "C" fn io_uring_prep_renameat(
1108    sqe: *mut io_uring_sqe,
1109    olddfd: c_int,
1110    oldpath: *const c_char,
1111    newdfd: c_int,
1112    newpath: *const c_char,
1113    flags: c_uint,
1114) {
1115    io_uring_prep_rw(
1116        io_uring_op_IORING_OP_RENAMEAT as _,
1117        sqe,
1118        olddfd,
1119        oldpath.cast(),
1120        newdfd as u32,
1121        newpath as usize as u64,
1122    );
1123    (*sqe).__liburing_anon_3.rename_flags = flags;
1124}
1125
1126#[inline]
1127#[no_mangle]
1128pub unsafe extern "C" fn io_uring_prep_rename(
1129    sqe: *mut io_uring_sqe,
1130    oldpath: *const c_char,
1131    newpath: *const c_char,
1132) {
1133    io_uring_prep_renameat(sqe, AT_FDCWD, oldpath, AT_FDCWD, newpath, 0);
1134}
1135
1136#[inline]
1137#[no_mangle]
1138pub unsafe extern "C" fn io_uring_prep_sync_file_range(
1139    sqe: *mut io_uring_sqe,
1140    fd: c_int,
1141    len: c_uint,
1142    offset: u64,
1143    flags: c_int,
1144) {
1145    io_uring_prep_rw(
1146        io_uring_op_IORING_OP_SYNC_FILE_RANGE as _,
1147        sqe,
1148        fd,
1149        ptr::null_mut(),
1150        len,
1151        offset,
1152    );
1153    (*sqe).__liburing_anon_3.sync_range_flags = flags as u32;
1154}
1155
1156#[inline]
1157#[no_mangle]
1158pub unsafe extern "C" fn io_uring_prep_statx(
1159    sqe: *mut io_uring_sqe,
1160    dfd: c_int,
1161    path: *const c_char,
1162    flags: c_int,
1163    mask: c_uint,
1164    statxbuf: *mut statx,
1165) {
1166    io_uring_prep_rw(
1167        io_uring_op_IORING_OP_STATX as _,
1168        sqe,
1169        dfd,
1170        path.cast(),
1171        mask,
1172        statxbuf as u64,
1173    );
1174    (*sqe).__liburing_anon_3.statx_flags = flags as u32;
1175}
1176
1177#[inline]
1178#[no_mangle]
1179pub unsafe extern "C" fn io_uring_prep_fadvise(
1180    sqe: *mut io_uring_sqe,
1181    fd: c_int,
1182    offset: u64,
1183    len: u32,
1184    advice: c_int,
1185) {
1186    io_uring_prep_rw(
1187        io_uring_op_IORING_OP_FADVISE as _,
1188        sqe,
1189        fd,
1190        ptr::null_mut(),
1191        len,
1192        offset,
1193    );
1194    (*sqe).__liburing_anon_3.fadvise_advice = advice as u32;
1195}
1196
1197#[inline]
1198#[no_mangle]
1199pub unsafe extern "C" fn io_uring_prep_madvise(
1200    sqe: *mut io_uring_sqe,
1201    addr: *mut c_void,
1202    length: u32,
1203    advice: c_int,
1204) {
1205    io_uring_prep_rw(io_uring_op_IORING_OP_MADVISE as _, sqe, -1, addr, length, 0);
1206    (*sqe).__liburing_anon_3.fadvise_advice = advice as u32;
1207}
1208
1209#[inline]
1210#[no_mangle]
1211pub unsafe extern "C" fn io_uring_prep_nop(sqe: *mut io_uring_sqe) {
1212    io_uring_prep_rw(
1213        io_uring_op_IORING_OP_NOP as _,
1214        sqe,
1215        -1,
1216        ptr::null_mut(),
1217        0,
1218        0,
1219    );
1220}
1221
1222#[inline]
1223#[no_mangle]
1224pub unsafe extern "C" fn io_uring_prep_fixed_fd_install(
1225    sqe: *mut io_uring_sqe,
1226    fd: c_int,
1227    flags: c_uint,
1228) {
1229    io_uring_prep_rw(
1230        io_uring_op_IORING_OP_FIXED_FD_INSTALL as _,
1231        sqe,
1232        fd,
1233        ptr::null_mut(),
1234        0,
1235        0,
1236    );
1237
1238    (*sqe).flags = IOSQE_FIXED_FILE as _;
1239    (*sqe).__liburing_anon_3.install_fd_flags = flags;
1240}
1241
1242#[inline]
1243#[no_mangle]
1244pub unsafe extern "C" fn io_uring_prep_ftruncate(
1245    sqe: *mut io_uring_sqe,
1246    fd: c_int,
1247    len: c_longlong,
1248) {
1249    io_uring_prep_rw(
1250        io_uring_op_IORING_OP_FTRUNCATE as _,
1251        sqe,
1252        fd,
1253        ptr::null_mut(),
1254        0,
1255        len as _,
1256    );
1257}
1258
1259#[inline]
1260#[no_mangle]
1261pub unsafe extern "C" fn io_uring_prep_close(sqe: *mut io_uring_sqe, fd: c_int) {
1262    io_uring_prep_rw(
1263        io_uring_op_IORING_OP_CLOSE as _,
1264        sqe,
1265        fd,
1266        ptr::null_mut(),
1267        0,
1268        0,
1269    );
1270}
1271
1272#[inline]
1273#[no_mangle]
1274pub unsafe extern "C" fn io_uring_prep_close_direct(sqe: *mut io_uring_sqe, file_index: c_uint) {
1275    io_uring_prep_close(sqe, 0);
1276    __io_uring_set_target_fixed_file(sqe, file_index);
1277}
1278
1279#[inline]
1280#[no_mangle]
1281pub unsafe extern "C" fn io_uring_prep_cancel(
1282    sqe: *mut io_uring_sqe,
1283    user_data: *mut c_void,
1284    flags: c_int,
1285) {
1286    io_uring_prep_cancel64(sqe, user_data as usize as u64, flags);
1287}
1288
1289#[inline]
1290#[no_mangle]
1291pub unsafe extern "C" fn io_uring_prep_cancel_fd(sqe: *mut io_uring_sqe, fd: c_int, flags: c_uint) {
1292    io_uring_prep_rw(
1293        io_uring_op_IORING_OP_ASYNC_CANCEL as _,
1294        sqe,
1295        fd,
1296        ptr::null_mut(),
1297        0,
1298        0,
1299    );
1300    (*sqe).__liburing_anon_3.cancel_flags = flags | IORING_ASYNC_CANCEL_FD;
1301}
1302
1303#[inline]
1304#[no_mangle]
1305pub unsafe extern "C" fn io_uring_prep_cancel64(
1306    sqe: *mut io_uring_sqe,
1307    user_data: u64,
1308    flags: c_int,
1309) {
1310    io_uring_prep_rw(
1311        io_uring_op_IORING_OP_ASYNC_CANCEL as _,
1312        sqe,
1313        -1,
1314        ptr::null_mut(),
1315        0,
1316        0,
1317    );
1318    (*sqe).__liburing_anon_2.addr = user_data;
1319    (*sqe).__liburing_anon_3.cancel_flags = flags as u32;
1320}
1321
1322#[inline]
1323#[no_mangle]
1324pub unsafe extern "C" fn io_uring_prep_link_timeout(
1325    sqe: *mut io_uring_sqe,
1326    ts: *mut __kernel_timespec,
1327    flags: c_uint,
1328) {
1329    io_uring_prep_rw(
1330        io_uring_op_IORING_OP_LINK_TIMEOUT as _,
1331        sqe,
1332        -1,
1333        ts.cast(),
1334        1,
1335        0,
1336    );
1337    (*sqe).__liburing_anon_3.timeout_flags = flags;
1338}
1339
1340#[inline]
1341#[no_mangle]
1342pub unsafe extern "C" fn io_uring_prep_timeout(
1343    sqe: *mut io_uring_sqe,
1344    ts: *mut __kernel_timespec,
1345    count: c_uint,
1346    flags: c_uint,
1347) {
1348    io_uring_prep_rw(
1349        io_uring_op_IORING_OP_TIMEOUT as c_int,
1350        sqe,
1351        -1,
1352        ts.cast(),
1353        1,
1354        count as __u64,
1355    );
1356    (*sqe).__liburing_anon_3.timeout_flags = flags;
1357}
1358
1359#[inline]
1360#[no_mangle]
1361pub unsafe extern "C" fn io_uring_prep_timeout_remove(
1362    sqe: *mut io_uring_sqe,
1363    user_data: __u64,
1364    flags: c_uint,
1365) {
1366    io_uring_prep_rw(
1367        io_uring_op_IORING_OP_TIMEOUT_REMOVE as c_int,
1368        sqe,
1369        -1,
1370        ptr::null_mut(),
1371        0,
1372        0,
1373    );
1374    (*sqe).__liburing_anon_2.addr = user_data;
1375    (*sqe).__liburing_anon_3.timeout_flags = flags;
1376}
1377
1378#[inline]
1379#[no_mangle]
1380pub unsafe extern "C" fn io_uring_prep_timeout_update(
1381    sqe: *mut io_uring_sqe,
1382    ts: *mut __kernel_timespec,
1383    user_data: __u64,
1384    flags: c_uint,
1385) {
1386    io_uring_prep_rw(
1387        io_uring_op_IORING_OP_TIMEOUT_REMOVE as c_int,
1388        sqe,
1389        -1,
1390        ptr::null_mut(),
1391        0,
1392        ts as u64,
1393    );
1394    (*sqe).__liburing_anon_2.addr = user_data;
1395    (*sqe).__liburing_anon_3.timeout_flags = flags | IORING_TIMEOUT_UPDATE;
1396}
1397
1398#[inline]
1399#[no_mangle]
1400pub unsafe extern "C" fn io_uring_prep_accept(
1401    sqe: *mut io_uring_sqe,
1402    fd: c_int,
1403    addr: *mut sockaddr,
1404    addrlen: *mut socklen_t,
1405    flags: c_int,
1406) {
1407    io_uring_prep_rw(
1408        io_uring_op_IORING_OP_ACCEPT as _,
1409        sqe,
1410        fd,
1411        addr.cast(),
1412        0,
1413        addrlen as u64,
1414    );
1415    (*sqe).__liburing_anon_3.accept_flags = flags as u32;
1416}
1417
1418#[inline]
1419#[no_mangle]
1420pub unsafe extern "C" fn io_uring_prep_accept_direct(
1421    sqe: *mut io_uring_sqe,
1422    fd: c_int,
1423    addr: *mut sockaddr,
1424    addrlen: *mut socklen_t,
1425    flags: c_int,
1426    mut file_index: c_uint,
1427) {
1428    io_uring_prep_accept(sqe, fd, addr, addrlen, flags);
1429
1430    if file_index == IORING_FILE_INDEX_ALLOC as _ {
1431        file_index -= 1;
1432    }
1433    __io_uring_set_target_fixed_file(sqe, file_index);
1434}
1435
1436#[inline]
1437#[no_mangle]
1438pub unsafe extern "C" fn io_uring_prep_multishot_accept(
1439    sqe: *mut io_uring_sqe,
1440    fd: c_int,
1441    addr: *mut sockaddr,
1442    addrlen: *mut socklen_t,
1443    flags: c_int,
1444) {
1445    io_uring_prep_accept(sqe, fd, addr, addrlen, flags);
1446    (*sqe).ioprio |= IORING_ACCEPT_MULTISHOT as u16;
1447}
1448
1449#[inline]
1450#[no_mangle]
1451pub unsafe extern "C" fn io_uring_prep_multishot_accept_direct(
1452    sqe: *mut io_uring_sqe,
1453    fd: c_int,
1454    addr: *mut sockaddr,
1455    addrlen: *mut socklen_t,
1456    flags: c_int,
1457) {
1458    io_uring_prep_multishot_accept(sqe, fd, addr, addrlen, flags);
1459    __io_uring_set_target_fixed_file(sqe, (IORING_FILE_INDEX_ALLOC - 1) as u32);
1460}
1461
1462#[inline]
1463#[no_mangle]
1464pub unsafe extern "C" fn io_uring_prep_connect(
1465    sqe: *mut io_uring_sqe,
1466    fd: c_int,
1467    addr: *const sockaddr,
1468    addrlen: socklen_t,
1469) {
1470    io_uring_prep_rw(
1471        io_uring_op_IORING_OP_CONNECT as _,
1472        sqe,
1473        fd,
1474        addr.cast(),
1475        0,
1476        addrlen as u64,
1477    );
1478}
1479
1480#[inline]
1481#[no_mangle]
1482pub unsafe extern "C" fn io_uring_prep_socket(
1483    sqe: *mut io_uring_sqe,
1484    domain: c_int,
1485    r#type: c_int,
1486    protocol: c_int,
1487    flags: c_uint,
1488) {
1489    io_uring_prep_rw(
1490        io_uring_op_IORING_OP_SOCKET as _,
1491        sqe,
1492        domain,
1493        ptr::null_mut(),
1494        protocol as u32,
1495        r#type as u64,
1496    );
1497    (*sqe).__liburing_anon_3.rw_flags = flags as i32;
1498}
1499
1500#[inline]
1501#[no_mangle]
1502pub unsafe extern "C" fn io_uring_prep_socket_direct(
1503    sqe: *mut io_uring_sqe,
1504    domain: c_int,
1505    r#type: c_int,
1506    protocol: c_int,
1507    mut file_index: c_uint,
1508    flags: c_uint,
1509) {
1510    io_uring_prep_rw(
1511        io_uring_op_IORING_OP_SOCKET as _,
1512        sqe,
1513        domain,
1514        ptr::null_mut(),
1515        protocol as u32,
1516        r#type as u64,
1517    );
1518    (*sqe).__liburing_anon_3.rw_flags = flags as i32;
1519    if file_index == IORING_FILE_INDEX_ALLOC as _ {
1520        file_index -= 1;
1521    }
1522    __io_uring_set_target_fixed_file(sqe, file_index);
1523}
1524
1525#[inline]
1526#[no_mangle]
1527pub unsafe extern "C" fn io_uring_prep_socket_direct_alloc(
1528    sqe: *mut io_uring_sqe,
1529    domain: c_int,
1530    r#type: c_int,
1531    protocol: c_int,
1532    flags: c_uint,
1533) {
1534    io_uring_prep_rw(
1535        io_uring_op_IORING_OP_SOCKET as _,
1536        sqe,
1537        domain,
1538        ptr::null_mut(),
1539        protocol as u32,
1540        r#type as u64,
1541    );
1542    (*sqe).__liburing_anon_3.rw_flags = flags as i32;
1543    __io_uring_set_target_fixed_file(sqe, (IORING_FILE_INDEX_ALLOC - 1) as _);
1544}
1545
1546#[inline]
1547#[no_mangle]
1548pub unsafe extern "C" fn io_uring_prep_shutdown(sqe: *mut io_uring_sqe, fd: c_int, how: c_int) {
1549    io_uring_prep_rw(
1550        io_uring_op_IORING_OP_SHUTDOWN as _,
1551        sqe,
1552        fd,
1553        ptr::null_mut(),
1554        how as u32,
1555        0,
1556    );
1557}
1558
1559#[inline]
1560#[no_mangle]
1561pub unsafe extern "C" fn io_uring_prep_cmd_sock(
1562    sqe: *mut io_uring_sqe,
1563    cmd_op: c_int,
1564    fd: c_int,
1565    level: c_int,
1566    optname: c_int,
1567    optval: *mut c_void,
1568    optlen: c_int,
1569) {
1570    io_uring_prep_rw(
1571        io_uring_op_IORING_OP_URING_CMD as _,
1572        sqe,
1573        fd,
1574        ptr::null_mut(),
1575        0,
1576        0,
1577    );
1578
1579    *(*sqe).__liburing_anon_6.optval.as_mut() = optval as usize as _;
1580    (*sqe).__liburing_anon_2.__liburing_anon_1.optname = optname as _;
1581    (*sqe).__liburing_anon_5.optlen = optlen as _;
1582    (*sqe).__liburing_anon_1.__liburing_anon_1.cmd_op = cmd_op as _;
1583    (*sqe).__liburing_anon_2.__liburing_anon_1.level = level as _;
1584}
1585
1586#[inline]
1587#[no_mangle]
1588pub unsafe extern "C" fn io_uring_prep_bind(
1589    sqe: *mut io_uring_sqe,
1590    fd: c_int,
1591    addr: *mut sockaddr,
1592    addrlen: socklen_t,
1593) {
1594    io_uring_prep_rw(
1595        io_uring_op_IORING_OP_BIND as _,
1596        sqe,
1597        fd,
1598        addr.cast(),
1599        0,
1600        addrlen as _,
1601    );
1602}
1603
1604#[inline]
1605#[no_mangle]
1606pub unsafe extern "C" fn io_uring_prep_listen(sqe: *mut io_uring_sqe, fd: c_int, backlog: c_int) {
1607    io_uring_prep_rw(
1608        io_uring_op_IORING_OP_LISTEN as _,
1609        sqe,
1610        fd,
1611        ptr::null_mut(),
1612        backlog as _,
1613        0,
1614    );
1615}
1616
1617#[inline]
1618#[no_mangle]
1619pub unsafe extern "C" fn io_uring_prep_send(
1620    sqe: *mut io_uring_sqe,
1621    sockfd: c_int,
1622    buf: *const c_void,
1623    len: usize,
1624    flags: c_int,
1625) {
1626    io_uring_prep_rw(
1627        io_uring_op_IORING_OP_SEND as _,
1628        sqe,
1629        sockfd,
1630        buf,
1631        len as u32,
1632        0,
1633    );
1634    (*sqe).__liburing_anon_3.msg_flags = flags as u32;
1635}
1636
1637#[inline]
1638#[no_mangle]
1639pub unsafe extern "C" fn io_uring_prep_send_zc(
1640    sqe: *mut io_uring_sqe,
1641    sockfd: c_int,
1642    buf: *const c_void,
1643    len: usize,
1644    flags: c_int,
1645    zc_flags: c_uint,
1646) {
1647    io_uring_prep_rw(
1648        io_uring_op_IORING_OP_SEND_ZC as _,
1649        sqe,
1650        sockfd,
1651        buf,
1652        len as u32,
1653        0,
1654    );
1655    (*sqe).__liburing_anon_3.msg_flags = flags as u32;
1656    (*sqe).ioprio = zc_flags as _;
1657}
1658
1659#[inline]
1660#[no_mangle]
1661pub unsafe extern "C" fn io_uring_prep_send_bundle(
1662    sqe: *mut io_uring_sqe,
1663    sockfd: c_int,
1664    len: usize,
1665    flags: c_int,
1666) {
1667    io_uring_prep_send(sqe, sockfd, ptr::null_mut(), len, flags);
1668    (*sqe).ioprio |= IORING_RECVSEND_BUNDLE as u16;
1669}
1670
1671#[inline]
1672#[no_mangle]
1673pub unsafe extern "C" fn io_uring_prep_send_set_addr(
1674    sqe: *mut io_uring_sqe,
1675    dest_addr: *const sockaddr,
1676    addr_len: u16,
1677) {
1678    (*sqe).__liburing_anon_1.addr2 = dest_addr as usize as u64;
1679    (*sqe).__liburing_anon_5.__liburing_anon_1.addr_len = addr_len;
1680}
1681
1682#[inline]
1683#[no_mangle]
1684pub unsafe extern "C" fn io_uring_prep_sendmsg(
1685    sqe: *mut io_uring_sqe,
1686    fd: c_int,
1687    msg: *const msghdr,
1688    flags: c_uint,
1689) {
1690    io_uring_prep_rw(
1691        io_uring_op_IORING_OP_SENDMSG as _,
1692        sqe,
1693        fd,
1694        msg.cast(),
1695        1,
1696        0,
1697    );
1698    (*sqe).__liburing_anon_3.msg_flags = flags;
1699}
1700
1701#[inline]
1702#[no_mangle]
1703pub unsafe extern "C" fn io_uring_prep_sendmsg_zc(
1704    sqe: *mut io_uring_sqe,
1705    fd: c_int,
1706    msg: *const msghdr,
1707    flags: c_uint,
1708) {
1709    io_uring_prep_sendmsg(sqe, fd, msg, flags);
1710    (*sqe).opcode = io_uring_op_IORING_OP_SENDMSG_ZC as _;
1711}
1712
1713#[inline]
1714#[no_mangle]
1715pub unsafe extern "C" fn io_uring_load_sq_head(ring: *mut io_uring) -> c_uint {
1716    if (*ring).flags & IORING_SETUP_SQPOLL > 0 {
1717        return io_uring_smp_load_acquire((*ring).sq.khead);
1718    }
1719
1720    *(*ring).sq.khead
1721}
1722
1723#[inline]
1724#[no_mangle]
1725pub unsafe extern "C" fn io_uring_sq_ready(ring: *mut io_uring) -> c_uint {
1726    (*ring).sq.sqe_tail - io_uring_load_sq_head(ring)
1727}
1728
1729#[inline]
1730#[no_mangle]
1731pub unsafe extern "C" fn io_uring_sq_space_left(ring: *mut io_uring) -> c_uint {
1732    (*ring).sq.ring_entries - io_uring_sq_ready(ring)
1733}
1734
1735#[inline]
1736#[no_mangle]
1737pub unsafe extern "C" fn io_uring_sqe_shift_from_flags(flags: c_uint) -> c_uint {
1738    if flags & IORING_SETUP_SQE128 > 0 {
1739        1
1740    } else {
1741        0
1742    }
1743}
1744
1745#[inline]
1746#[no_mangle]
1747pub unsafe extern "C" fn io_uring_sqe_shift(ring: *mut io_uring) -> c_uint {
1748    io_uring_sqe_shift_from_flags((*ring).flags)
1749}
1750
1751#[inline]
1752#[no_mangle]
1753pub unsafe extern "C" fn io_uring_cq_eventfd_enabled(ring: *mut io_uring) -> bool {
1754    if (*ring).cq.kflags.is_null() {
1755        return true;
1756    }
1757    (*(*ring).cq.kflags & IORING_CQ_EVENTFD_DISABLED) == 0
1758}
1759
1760#[inline]
1761#[no_mangle]
1762pub unsafe extern "C" fn io_uring_cq_eventfd_toggle(ring: *mut io_uring, enabled: bool) -> c_int {
1763    if enabled == io_uring_cq_eventfd_enabled(ring) {
1764        return 0;
1765    }
1766
1767    if (*ring).cq.kflags.is_null() {
1768        return -(EOPNOTSUPP as c_int);
1769    }
1770
1771    let mut flags = *(*ring).cq.kflags;
1772
1773    if enabled {
1774        flags &= !IORING_CQ_EVENTFD_DISABLED;
1775    } else {
1776        flags |= IORING_CQ_EVENTFD_DISABLED;
1777    }
1778
1779    IO_URING_WRITE_ONCE((*ring).cq.kflags, flags);
1780
1781    0
1782}
1783
1784#[inline]
1785#[no_mangle]
1786pub unsafe extern "C" fn io_uring_prep_cmd_discard(
1787    sqe: *mut io_uring_sqe,
1788    fd: c_int,
1789    offset: u64,
1790    nbytes: u64,
1791) {
1792    io_uring_prep_rw(
1793        io_uring_op_IORING_OP_URING_CMD as _,
1794        sqe,
1795        fd,
1796        ptr::null_mut(),
1797        0,
1798        0,
1799    );
1800
1801    // TODO: really someday fix this
1802    // We need bindgen to actually evaluate this macro's value during generation.
1803    // No idea is hard-coding this value like this is viable in practice.
1804    (*sqe).__liburing_anon_1.__liburing_anon_1.cmd_op = (0x12) << 8; // BLOCK_URING_CMD_DISCARD;
1805    (*sqe).__liburing_anon_2.addr = offset;
1806    (*sqe).__liburing_anon_6.__liburing_anon_1.as_mut().addr3 = nbytes;
1807}
1808
1809#[inline]
1810#[no_mangle]
1811pub unsafe extern "C" fn io_uring_prep_linkat(
1812    sqe: *mut io_uring_sqe,
1813    olddfd: c_int,
1814    oldpath: *const c_char,
1815    newdfd: c_int,
1816    newpath: *const c_char,
1817    flags: c_int,
1818) {
1819    io_uring_prep_rw(
1820        io_uring_op_IORING_OP_LINKAT as _,
1821        sqe,
1822        olddfd,
1823        oldpath.cast(),
1824        newdfd as u32,
1825        newpath as usize as u64,
1826    );
1827    (*sqe).__liburing_anon_3.hardlink_flags = flags as u32;
1828}
1829
1830#[inline]
1831#[no_mangle]
1832pub unsafe extern "C" fn io_uring_prep_futex_wake(
1833    sqe: *mut io_uring_sqe,
1834    futex: *mut u32,
1835    val: u64,
1836    mask: u64,
1837    futex_flags: u32,
1838    flags: c_uint,
1839) {
1840    io_uring_prep_rw(
1841        io_uring_op_IORING_OP_FUTEX_WAKE as _,
1842        sqe,
1843        futex_flags as _,
1844        futex.cast(),
1845        0,
1846        val,
1847    );
1848    (*sqe).__liburing_anon_3.futex_flags = flags;
1849    (*sqe).__liburing_anon_6.__liburing_anon_1.as_mut().addr3 = mask;
1850}
1851
1852#[inline]
1853#[no_mangle]
1854pub unsafe extern "C" fn io_uring_prep_waitid(
1855    sqe: *mut io_uring_sqe,
1856    idtype: idtype_t,
1857    id: id_t,
1858    infop: *mut siginfo_t,
1859    options: c_int,
1860    flags: c_uint,
1861) {
1862    io_uring_prep_rw(
1863        io_uring_op_IORING_OP_WAITID as _,
1864        sqe,
1865        id as _,
1866        ptr::null_mut(),
1867        idtype,
1868        0,
1869    );
1870    (*sqe).__liburing_anon_3.waitid_flags = flags;
1871    (*sqe).__liburing_anon_5.file_index = options as _;
1872    (*sqe).__liburing_anon_1.addr2 = infop as usize as u64;
1873}
1874
1875#[inline]
1876#[no_mangle]
1877pub unsafe extern "C" fn io_uring_prep_futex_wait(
1878    sqe: *mut io_uring_sqe,
1879    futex: *mut u32,
1880    val: u64,
1881    mask: u64,
1882    futex_flags: u32,
1883    flags: c_uint,
1884) {
1885    io_uring_prep_rw(
1886        io_uring_op_IORING_OP_FUTEX_WAIT as _,
1887        sqe,
1888        futex_flags as _,
1889        futex.cast(),
1890        0,
1891        val,
1892    );
1893    (*sqe).__liburing_anon_3.futex_flags = flags;
1894    (*sqe).__liburing_anon_6.__liburing_anon_1.as_mut().addr3 = mask;
1895}
1896
1897#[inline]
1898#[no_mangle]
1899pub unsafe extern "C" fn io_uring_prep_futex_waitv(
1900    sqe: *mut io_uring_sqe,
1901    futex: *mut futex_waitv,
1902    nr_futex: u32,
1903    flags: c_uint,
1904) {
1905    io_uring_prep_rw(
1906        io_uring_op_IORING_OP_FUTEX_WAITV as _,
1907        sqe,
1908        0,
1909        futex.cast(),
1910        nr_futex,
1911        0,
1912    );
1913    (*sqe).__liburing_anon_3.futex_flags = flags;
1914}
1915
1916#[inline]
1917#[no_mangle]
1918pub unsafe extern "C" fn io_uring_prep_mkdirat(
1919    sqe: *mut io_uring_sqe,
1920    dfd: c_int,
1921    path: *const c_char,
1922    mode: mode_t,
1923) {
1924    io_uring_prep_rw(
1925        io_uring_op_IORING_OP_MKDIRAT as _,
1926        sqe,
1927        dfd,
1928        path.cast(),
1929        mode,
1930        0,
1931    );
1932}
1933
1934#[inline]
1935#[no_mangle]
1936pub unsafe extern "C" fn io_uring_prep_msg_ring_cqe_flags(
1937    sqe: *mut io_uring_sqe,
1938    fd: c_int,
1939    len: c_uint,
1940    data: u64,
1941    flags: c_uint,
1942    cqe_flags: c_uint,
1943) {
1944    io_uring_prep_rw(
1945        io_uring_op_IORING_OP_MSG_RING as _,
1946        sqe,
1947        fd,
1948        ptr::null_mut(),
1949        len,
1950        data,
1951    );
1952    (*sqe).__liburing_anon_3.msg_ring_flags = IORING_MSG_RING_FLAGS_PASS | flags;
1953    (*sqe).__liburing_anon_5.file_index = cqe_flags;
1954}
1955
1956#[inline]
1957#[no_mangle]
1958pub unsafe extern "C" fn io_uring_prep_msg_ring(
1959    sqe: *mut io_uring_sqe,
1960    fd: c_int,
1961    len: c_uint,
1962    data: u64,
1963    flags: c_uint,
1964) {
1965    io_uring_prep_rw(
1966        io_uring_op_IORING_OP_MSG_RING as _,
1967        sqe,
1968        fd,
1969        ptr::null_mut(),
1970        len,
1971        data,
1972    );
1973    (*sqe).__liburing_anon_3.msg_ring_flags = IORING_MSG_RING_FLAGS_PASS | flags;
1974}
1975
1976#[inline]
1977#[no_mangle]
1978pub unsafe extern "C" fn io_uring_prep_splice(
1979    sqe: *mut io_uring_sqe,
1980    fd_in: c_int,
1981    off_in: i64,
1982    fd_out: c_int,
1983    off_out: i64,
1984    nbytes: c_uint,
1985    splice_flags: c_uint,
1986) {
1987    io_uring_prep_rw(
1988        io_uring_op_IORING_OP_SPLICE as _,
1989        sqe,
1990        fd_out,
1991        ptr::null_mut(),
1992        nbytes,
1993        off_out as u64,
1994    );
1995    (*sqe).__liburing_anon_2.splice_off_in = off_in as u64;
1996    (*sqe).__liburing_anon_5.splice_fd_in = fd_in;
1997    (*sqe).__liburing_anon_3.splice_flags = splice_flags;
1998}
1999
2000#[inline]
2001#[no_mangle]
2002pub unsafe extern "C" fn io_uring_prep_symlinkat(
2003    sqe: *mut io_uring_sqe,
2004    target: *const c_char,
2005    newdirfd: c_int,
2006    linkpath: *const c_char,
2007) {
2008    io_uring_prep_rw(
2009        io_uring_op_IORING_OP_SYMLINKAT as _,
2010        sqe,
2011        newdirfd,
2012        target.cast(),
2013        0,
2014        linkpath as usize as u64,
2015    );
2016}
2017
2018#[inline]
2019#[no_mangle]
2020pub unsafe extern "C" fn io_uring_sqring_wait(ring: *mut io_uring) -> c_int {
2021    if (*ring).flags & IORING_SETUP_SQPOLL == 0 {
2022        return 0;
2023    }
2024    if io_uring_sq_space_left(ring) > 0 {
2025        return 0;
2026    }
2027
2028    __io_uring_sqring_wait(ring)
2029}
2030
2031impl From<Duration> for timespec {
2032    fn from(duration: Duration) -> Self {
2033        let mut ts = unsafe { zeroed::<timespec>() };
2034        ts.tv_sec = duration.as_secs() as time_t;
2035        ts.tv_nsec = duration.subsec_nanos() as _;
2036        ts
2037    }
2038}