Skip to main content

kevy_uring/
layout.rs

1//! `#[repr(C)]` wire-layout structs the kernel reads/writes through the
2//! shared mmap regions. These are the io_uring ABI definitions translated
3//! from `<linux/io_uring.h>`.
4
5/// `struct io_sqring_offsets` — byte offsets of each SQ cursor inside the SQ
6/// ring mapping, returned by `io_uring_setup`.
7#[repr(C)]
8#[derive(Default)]
9pub struct IoSqringOffsets {
10    pub head: u32,
11    pub tail: u32,
12    pub ring_mask: u32,
13    pub ring_entries: u32,
14    pub flags: u32,
15    pub dropped: u32,
16    pub array: u32,
17    pub resv1: u32,
18    pub resv2: u64,
19}
20
21/// `struct io_cqring_offsets` — byte offsets of each CQ cursor inside the CQ
22/// ring mapping.
23#[repr(C)]
24#[derive(Default)]
25pub struct IoCqringOffsets {
26    pub head: u32,
27    pub tail: u32,
28    pub ring_mask: u32,
29    pub ring_entries: u32,
30    pub overflow: u32,
31    pub cqes: u32,
32    pub flags: u32,
33    pub resv1: u32,
34    pub resv2: u64,
35}
36
37/// `struct io_uring_params` — `io_uring_setup`'s in/out parameter.
38#[repr(C)]
39#[derive(Default)]
40pub struct IoUringParams {
41    pub sq_entries: u32,
42    pub cq_entries: u32,
43    pub flags: u32,
44    pub sq_thread_cpu: u32,
45    pub sq_thread_idle: u32,
46    pub features: u32,
47    pub wq_fd: u32,
48    pub resv: [u32; 3],
49    pub sq_off: IoSqringOffsets,
50    pub cq_off: IoCqringOffsets,
51}
52
53/// `struct io_uring_sqe` — the 64-byte submission entry.
54#[repr(C)]
55pub struct IoUringSqe {
56    pub opcode: u8,
57    pub flags: u8,
58    pub ioprio: u16,
59    pub fd: i32,
60    pub off: u64,
61    pub addr: u64,
62    pub len: u32,
63    pub rw_flags: u32,
64    pub user_data: u64,
65    pub buf_index: u16,
66    pub personality: u16,
67    pub splice_fd_in: i32,
68    pub addr3: u64,
69    pub __pad2: u64,
70}
71
72impl IoUringSqe {
73    /// A zeroed SQE with the common fields set. Op-specific fields (e.g.
74    /// `rw_flags` for accept flags) are tweaked by the caller afterward.
75    pub fn new(opcode: u8, fd: i32, addr: u64, len: u32, user_data: u64) -> IoUringSqe {
76        IoUringSqe {
77            opcode,
78            flags: 0,
79            ioprio: 0,
80            fd,
81            off: 0,
82            addr,
83            len,
84            rw_flags: 0,
85            user_data,
86            buf_index: 0,
87            personality: 0,
88            splice_fd_in: 0,
89            addr3: 0,
90            __pad2: 0,
91        }
92    }
93}
94
95/// `struct __kernel_timespec` — the timeout payload an `IORING_OP_TIMEOUT`
96/// SQE points at (always 64-bit fields, independent of the C `time_t` width).
97#[repr(C)]
98#[derive(Default)]
99pub struct KernelTimespec {
100    pub tv_sec: i64,
101    pub tv_nsec: i64,
102}
103
104impl KernelTimespec {
105    /// A relative timeout of `ms` milliseconds.
106    pub fn from_millis(ms: u64) -> KernelTimespec {
107        KernelTimespec {
108            tv_sec: (ms / 1000) as i64,
109            tv_nsec: ((ms % 1000) * 1_000_000) as i64,
110        }
111    }
112}
113
114/// `struct io_uring_buf_reg` — `io_uring_register(IORING_REGISTER_PBUF_RING,
115/// …)`'s argument layout.
116#[repr(C)]
117pub struct IoUringBufReg {
118    pub ring_addr: u64,
119    pub ring_entries: u32,
120    pub bgid: u16,
121    pub pad: u16,
122    pub resv: [u64; 3],
123}