]>
Commit | Line | Data |
---|---|---|
064997fb FG |
1 | //! Linux [io_uring]. |
2 | //! | |
3 | //! This API is very low-level. The main adaptations it makes from the raw | |
4 | //! Linux io_uring API are the use of appropriately-sized `bitflags`, `enum`, | |
5 | //! `Result`, `OwnedFd`, `AsFd`, `RawFd`, and `*mut c_void` in place of plain | |
6 | //! integers. | |
7 | //! | |
8 | //! # Safety | |
9 | //! | |
10 | //! io_uring operates on raw pointers and raw file descriptors. Rustix does not | |
11 | //! attempt to provide a safe API for these, because the abstraction level is | |
12 | //! too low for this to be practical. Safety should be introduced in | |
13 | //! higher-level abstraction layers. | |
14 | //! | |
15 | //! # References | |
16 | //! - [Linux] | |
17 | //! | |
18 | //! [Linux]: https://man.archlinux.org/man/io_uring.7.en | |
19 | //! [io_uring]: https://en.wikipedia.org/wiki/Io_uring | |
20 | #![allow(unsafe_code)] | |
21 | ||
6522a427 EL |
22 | use crate::fd::{AsFd, BorrowedFd, OwnedFd, RawFd}; |
23 | use crate::{backend, io}; | |
064997fb FG |
24 | use core::ffi::c_void; |
25 | use core::ptr::null_mut; | |
26 | use linux_raw_sys::general as sys; | |
27 | ||
28 | /// `io_uring_setup(entries, params)`—Setup a context for performing | |
29 | /// asynchronous I/O. | |
30 | /// | |
31 | /// # References | |
32 | /// - [Linux] | |
33 | /// | |
34 | /// [Linux]: https://man.archlinux.org/man/io_uring_setup.2.en | |
35 | #[inline] | |
36 | pub fn io_uring_setup(entries: u32, params: &mut io_uring_params) -> io::Result<OwnedFd> { | |
6522a427 | 37 | backend::io_uring::syscalls::io_uring_setup(entries, params) |
064997fb FG |
38 | } |
39 | ||
40 | /// `io_uring_register(fd, opcode, arg, nr_args)`—Register files or user | |
41 | /// buffers for asynchronous I/O. | |
42 | /// | |
43 | /// # Safety | |
44 | /// | |
45 | /// io_uring operates on raw pointers and raw file descriptors. Users are | |
46 | /// responsible for ensuring that memory and resources are only accessed in | |
47 | /// valid ways. | |
48 | /// | |
49 | /// # References | |
50 | /// - [Linux] | |
51 | /// | |
52 | /// [Linux]: https://man.archlinux.org/man/io_uring_register.2.en | |
53 | #[inline] | |
54 | pub unsafe fn io_uring_register<Fd: AsFd>( | |
55 | fd: Fd, | |
56 | opcode: IoringRegisterOp, | |
57 | arg: *const c_void, | |
58 | nr_args: u32, | |
59 | ) -> io::Result<()> { | |
6522a427 | 60 | backend::io_uring::syscalls::io_uring_register(fd.as_fd(), opcode, arg, nr_args) |
064997fb FG |
61 | } |
62 | ||
63 | /// `io_uring_enter(fd, to_submit, min_complete, flags, arg, size)`—Initiate | |
64 | /// and/or complete asynchronous I/O. | |
65 | /// | |
66 | /// # Safety | |
67 | /// | |
68 | /// io_uring operates on raw pointers and raw file descriptors. Users are | |
69 | /// responsible for ensuring that memory and resources are only accessed in | |
70 | /// valid ways. | |
71 | /// | |
72 | /// # References | |
73 | /// - [Linux] | |
74 | /// | |
75 | /// [Linux]: https://man.archlinux.org/man/io_uring_enter.2.en | |
76 | #[inline] | |
77 | pub unsafe fn io_uring_enter<Fd: AsFd>( | |
78 | fd: Fd, | |
79 | to_submit: u32, | |
80 | min_complete: u32, | |
81 | flags: IoringEnterFlags, | |
82 | arg: *const c_void, | |
83 | size: usize, | |
84 | ) -> io::Result<u32> { | |
6522a427 EL |
85 | backend::io_uring::syscalls::io_uring_enter( |
86 | fd.as_fd(), | |
87 | to_submit, | |
88 | min_complete, | |
89 | flags, | |
90 | arg, | |
91 | size, | |
92 | ) | |
064997fb FG |
93 | } |
94 | ||
95 | bitflags::bitflags! { | |
96 | /// `IORING_ENTER_*` flags for use with [`io_uring_enter`]. | |
97 | #[derive(Default)] | |
98 | pub struct IoringEnterFlags: u32 { | |
99 | /// `IORING_ENTER_GETEVENTS` | |
100 | const GETEVENTS = sys::IORING_ENTER_GETEVENTS; | |
101 | ||
102 | /// `IORING_ENTER_SQ_WAKEUP` | |
103 | const SQ_WAKEUP = sys::IORING_ENTER_SQ_WAKEUP; | |
104 | ||
105 | /// `IORING_ENTER_SQ_WAIT` | |
106 | const SQ_WAIT = sys::IORING_ENTER_SQ_WAIT; | |
107 | ||
108 | /// `IORING_ENTER_EXT_ARG` | |
109 | const EXT_ARG = sys::IORING_ENTER_EXT_ARG; | |
110 | } | |
111 | } | |
112 | ||
113 | /// `IORING_REGISTER_*` and `IORING_UNREGISTER_*` constants for use with | |
114 | /// [`io_uring_register`]. | |
115 | #[derive(Debug, Clone, Copy, Eq, PartialEq, Hash)] | |
116 | #[repr(u8)] | |
117 | #[non_exhaustive] | |
118 | pub enum IoringRegisterOp { | |
119 | /// `IORING_REGISTER_BUFFERS` | |
120 | RegisterBuffers = sys::IORING_REGISTER_BUFFERS as _, | |
121 | ||
122 | /// `IORING_UNREGISTER_BUFFERS` | |
123 | UnregisterBuffers = sys::IORING_UNREGISTER_BUFFERS as _, | |
124 | ||
125 | /// `IORING_REGISTER_FILES` | |
126 | RegisterFiles = sys::IORING_REGISTER_FILES as _, | |
127 | ||
128 | /// `IORING_UNREGISTER_FILES` | |
129 | UnregisterFiles = sys::IORING_UNREGISTER_FILES as _, | |
130 | ||
131 | /// `IORING_REGISTER_EVENTFD` | |
132 | RegisterEventfd = sys::IORING_REGISTER_EVENTFD as _, | |
133 | ||
134 | /// `IORING_UNREGISTER_EVENTFD` | |
135 | UnregisterEventfd = sys::IORING_UNREGISTER_EVENTFD as _, | |
136 | ||
137 | /// `IORING_REGISTER_FILES_UPDATE` | |
138 | RegisterFilesUpdate = sys::IORING_REGISTER_FILES_UPDATE as _, | |
139 | ||
140 | /// `IORING_REGISTER_EVENTFD_ASYNC` | |
141 | RegisterEventfdAsync = sys::IORING_REGISTER_EVENTFD_ASYNC as _, | |
142 | ||
143 | /// `IORING_REGISTER_PROBE` | |
144 | RegisterProbe = sys::IORING_REGISTER_PROBE as _, | |
145 | ||
146 | /// `IORING_REGISTER_PERSONALITY` | |
147 | RegisterPersonality = sys::IORING_REGISTER_PERSONALITY as _, | |
148 | ||
149 | /// `IORING_UNREGISTER_PERSONALITY` | |
150 | UnregisterPersonality = sys::IORING_UNREGISTER_PERSONALITY as _, | |
151 | ||
152 | /// `IORING_REGISTER_RESTRICTIONS` | |
153 | RegisterRestrictions = sys::IORING_REGISTER_RESTRICTIONS as _, | |
154 | ||
155 | /// `IORING_REGISTER_ENABLE_RINGS` | |
156 | RegisterEnableRings = sys::IORING_REGISTER_ENABLE_RINGS as _, | |
157 | ||
158 | /// `IORING_REGISTER_BUFFERS2` | |
159 | RegisterBuffers2 = sys::IORING_REGISTER_BUFFERS2 as _, | |
160 | ||
161 | /// `IORING_REGISTER_BUFFERS_UPDATE` | |
162 | RegisterBuffersUpdate = sys::IORING_REGISTER_BUFFERS_UPDATE as _, | |
163 | ||
164 | /// `IORING_REGISTER_FILES2` | |
165 | RegisterFiles2 = sys::IORING_REGISTER_FILES2 as _, | |
166 | ||
167 | /// `IORING_REGISTER_FILES_SKIP` | |
168 | RegisterFilesSkip = sys::IORING_REGISTER_FILES_SKIP as _, | |
169 | ||
170 | /// `IORING_REGISTER_FILES_UPDATE2` | |
171 | RegisterFilesUpdate2 = sys::IORING_REGISTER_FILES_UPDATE2 as _, | |
172 | ||
173 | /// `IORING_REGISTER_IOWQ_AFF` | |
174 | RegisterIowqAff = sys::IORING_REGISTER_IOWQ_AFF as _, | |
175 | ||
176 | /// `IORING_UNREGISTER_IOWQ_AFF` | |
177 | UnregisterIowqAff = sys::IORING_UNREGISTER_IOWQ_AFF as _, | |
178 | ||
179 | /// `IORING_REGISTER_IOWQ_MAX_WORKERS` | |
180 | RegisterIowqMaxWorkers = sys::IORING_REGISTER_IOWQ_MAX_WORKERS as _, | |
181 | } | |
182 | ||
183 | /// `IORING_OP_*` constants for use with [`io_uring_sqe`]. | |
184 | #[derive(Debug, Clone, Copy, Eq, PartialEq, Hash)] | |
185 | #[repr(u8)] | |
186 | #[non_exhaustive] | |
187 | pub enum IoringOp { | |
188 | /// `IORING_OP_NOP` | |
189 | Nop = sys::IORING_OP_NOP as _, | |
190 | ||
191 | /// `IORING_OP_ACCEPT` | |
192 | Accept = sys::IORING_OP_ACCEPT as _, | |
193 | ||
194 | /// `IORING_OP_ASYNC_CANCEL` | |
195 | AsyncCancel = sys::IORING_OP_ASYNC_CANCEL as _, | |
196 | ||
197 | /// `IORING_OP_CLOSE` | |
198 | Close = sys::IORING_OP_CLOSE as _, | |
199 | ||
200 | /// `IORING_OP_CONNECT` | |
201 | Connect = sys::IORING_OP_CONNECT as _, | |
202 | ||
203 | /// `IORING_OP_EPOLL_CTL` | |
204 | EpollCtl = sys::IORING_OP_EPOLL_CTL as _, | |
205 | ||
206 | /// `IORING_OP_FADVISE` | |
207 | Fadvise = sys::IORING_OP_FADVISE as _, | |
208 | ||
209 | /// `IORING_OP_FALLOCATE` | |
210 | Fallocate = sys::IORING_OP_FALLOCATE as _, | |
211 | ||
212 | /// `IORING_OP_FILES_UPDATE` | |
213 | FilesUpdate = sys::IORING_OP_FILES_UPDATE as _, | |
214 | ||
215 | /// `IORING_OP_FSYNC` | |
216 | Fsync = sys::IORING_OP_FSYNC as _, | |
217 | ||
218 | /// `IORING_OP_LINKAT` | |
219 | Linkat = sys::IORING_OP_LINKAT as _, | |
220 | ||
221 | /// `IORING_OP_LINK_TIMEOUT` | |
222 | LinkTimeout = sys::IORING_OP_LINK_TIMEOUT as _, | |
223 | ||
224 | /// `IORING_OP_MADVISE` | |
225 | Madvise = sys::IORING_OP_MADVISE as _, | |
226 | ||
227 | /// `IORING_OP_MKDIRAT` | |
228 | Mkdirat = sys::IORING_OP_MKDIRAT as _, | |
229 | ||
230 | /// `IORING_OP_OPENAT` | |
231 | Openat = sys::IORING_OP_OPENAT as _, | |
232 | ||
233 | /// `IORING_OP_OPENAT2` | |
234 | Openat2 = sys::IORING_OP_OPENAT2 as _, | |
235 | ||
236 | /// `IORING_OP_POLL_ADD` | |
237 | PollAdd = sys::IORING_OP_POLL_ADD as _, | |
238 | ||
239 | /// `IORING_OP_POLL_REMOVE` | |
240 | PollRemove = sys::IORING_OP_POLL_REMOVE as _, | |
241 | ||
242 | /// `IORING_OP_PROVIDE_BUFFERS` | |
243 | ProvideBuffers = sys::IORING_OP_PROVIDE_BUFFERS as _, | |
244 | ||
245 | /// `IORING_OP_READ` | |
246 | Read = sys::IORING_OP_READ as _, | |
247 | ||
248 | /// `IORING_OP_READV` | |
249 | Readv = sys::IORING_OP_READV as _, | |
250 | ||
251 | /// `IORING_OP_READ_FIXED` | |
252 | ReadFixed = sys::IORING_OP_READ_FIXED as _, | |
253 | ||
254 | /// `IORING_OP_RECV` | |
255 | Recv = sys::IORING_OP_RECV as _, | |
256 | ||
257 | /// `IORING_OP_RECVMSG` | |
258 | Recvmsg = sys::IORING_OP_RECVMSG as _, | |
259 | ||
260 | /// `IORING_OP_REMOVE_BUFFERS` | |
261 | RemoveBuffers = sys::IORING_OP_REMOVE_BUFFERS as _, | |
262 | ||
263 | /// `IORING_OP_RENAMEAT` | |
264 | Renameat = sys::IORING_OP_RENAMEAT as _, | |
265 | ||
266 | /// `IORING_OP_SEND` | |
267 | Send = sys::IORING_OP_SEND as _, | |
268 | ||
269 | /// `IORING_OP_SENDMSG` | |
270 | Sendmsg = sys::IORING_OP_SENDMSG as _, | |
271 | ||
272 | /// `IORING_OP_SHUTDOWN` | |
273 | Shutdown = sys::IORING_OP_SHUTDOWN as _, | |
274 | ||
275 | /// `IORING_OP_SPLICE` | |
276 | Splice = sys::IORING_OP_SPLICE as _, | |
277 | ||
278 | /// `IORING_OP_STATX` | |
279 | Statx = sys::IORING_OP_STATX as _, | |
280 | ||
281 | /// `IORING_OP_SYMLINKAT` | |
282 | Symlinkat = sys::IORING_OP_SYMLINKAT as _, | |
283 | ||
284 | /// `IORING_OP_SYNC_FILE_RANGE` | |
285 | SyncFileRange = sys::IORING_OP_SYNC_FILE_RANGE as _, | |
286 | ||
287 | /// `IORING_OP_TEE` | |
288 | Tee = sys::IORING_OP_TEE as _, | |
289 | ||
290 | /// `IORING_OP_TIMEOUT` | |
291 | Timeout = sys::IORING_OP_TIMEOUT as _, | |
292 | ||
293 | /// `IORING_OP_TIMEOUT_REMOVE` | |
294 | TimeoutRemove = sys::IORING_OP_TIMEOUT_REMOVE as _, | |
295 | ||
296 | /// `IORING_OP_UNLINKAT` | |
297 | Unlinkat = sys::IORING_OP_UNLINKAT as _, | |
298 | ||
299 | /// `IORING_OP_WRITE` | |
300 | Write = sys::IORING_OP_WRITE as _, | |
301 | ||
302 | /// `IORING_OP_WRITEV` | |
303 | Writev = sys::IORING_OP_WRITEV as _, | |
304 | ||
305 | /// `IORING_OP_WRITE_FIXED` | |
306 | WriteFixed = sys::IORING_OP_WRITE_FIXED as _, | |
307 | } | |
308 | ||
309 | impl Default for IoringOp { | |
310 | #[inline] | |
311 | fn default() -> Self { | |
312 | Self::Nop | |
313 | } | |
314 | } | |
315 | ||
316 | /// `IORING_RESTRICTION_*` constants for use with [`io_uring_restriction`]. | |
317 | #[derive(Debug, Clone, Copy, Eq, PartialEq, Hash)] | |
318 | #[repr(u16)] | |
319 | #[non_exhaustive] | |
320 | pub enum IoringRestrictionOp { | |
321 | /// `IORING_RESTRICTION_REGISTER_OP` | |
322 | RegisterOp = sys::IORING_RESTRICTION_REGISTER_OP as _, | |
323 | ||
324 | /// `IORING_RESTRICTION_SQE_FLAGS_ALLOWED` | |
325 | SqeFlagsAllowed = sys::IORING_RESTRICTION_SQE_FLAGS_ALLOWED as _, | |
326 | ||
327 | /// `IORING_RESTRICTION_SQE_FLAGS_REQUIRED` | |
328 | SqeFlagsRequired = sys::IORING_RESTRICTION_SQE_FLAGS_REQUIRED as _, | |
329 | ||
330 | /// `IORING_RESTRICTION_SQE_OP` | |
331 | SqeOp = sys::IORING_RESTRICTION_SQE_OP as _, | |
332 | } | |
333 | ||
334 | impl Default for IoringRestrictionOp { | |
335 | #[inline] | |
336 | fn default() -> Self { | |
337 | Self::RegisterOp | |
338 | } | |
339 | } | |
340 | ||
341 | bitflags::bitflags! { | |
342 | /// `IORING_SETUP_*` flags for use with [`io_uring_params`]. | |
343 | #[derive(Default)] | |
344 | pub struct IoringSetupFlags: u32 { | |
345 | /// `IORING_SETUP_ATTACH_WQ` | |
346 | const ATTACH_WQ = sys::IORING_SETUP_ATTACH_WQ; | |
347 | ||
348 | /// `IORING_SETUP_CLAMP` | |
349 | const CLAMP = sys::IORING_SETUP_CLAMP; | |
350 | ||
351 | /// `IORING_SETUP_CQSIZE` | |
352 | const CQSIZE = sys::IORING_SETUP_CQSIZE; | |
353 | ||
354 | /// `IORING_SETUP_IOPOLL` | |
355 | const IOPOLL = sys::IORING_SETUP_IOPOLL; | |
356 | ||
357 | /// `IORING_SETUP_R_DISABLED` | |
358 | const R_DISABLED = sys::IORING_SETUP_R_DISABLED; | |
359 | ||
360 | /// `IORING_SETUP_SQPOLL` | |
361 | const SQPOLL = sys::IORING_SETUP_SQPOLL; | |
362 | ||
363 | /// `IORING_SETUP_SQ_AFF` | |
364 | const SQ_AFF = sys::IORING_SETUP_SQ_AFF; | |
365 | } | |
366 | } | |
367 | ||
368 | bitflags::bitflags! { | |
369 | /// `IOSQE_*` flags for use with [`io_uring_sqe`]. | |
370 | #[derive(Default)] | |
371 | pub struct IoringSqeFlags: u8 { | |
372 | /// `1 << IOSQE_ASYNC_BIT` | |
373 | const ASYNC = 1 << sys::IOSQE_ASYNC_BIT as u8; | |
374 | ||
375 | /// `1 << IOSQE_BUFFER_SELECT_BIT` | |
376 | const BUFFER_SELECT = 1 << sys::IOSQE_BUFFER_SELECT_BIT as u8; | |
377 | ||
378 | /// `1 << IOSQE_FIXED_FILE_BIT` | |
379 | const FIXED_FILE = 1 << sys::IOSQE_FIXED_FILE_BIT as u8; | |
380 | ||
381 | /// 1 << `IOSQE_IO_DRAIN_BIT` | |
382 | const IO_DRAIN = 1 << sys::IOSQE_IO_DRAIN_BIT as u8; | |
383 | ||
384 | /// `1 << IOSQE_IO_HARDLINK_BIT` | |
385 | const IO_HARDLINK = 1 << sys::IOSQE_IO_HARDLINK_BIT as u8; | |
386 | ||
387 | /// `1 << IOSQE_IO_LINK_BIT` | |
388 | const IO_LINK = 1 << sys::IOSQE_IO_LINK_BIT as u8; | |
389 | } | |
390 | } | |
391 | ||
392 | bitflags::bitflags! { | |
393 | /// `IORING_CQE_F_*` flags for use with [`io_uring_cqe`]. | |
394 | #[derive(Default)] | |
395 | pub struct IoringCqeFlags: u32 { | |
396 | /// `IORING_CQE_F_BUFFER` | |
397 | const BUFFER = sys::IORING_CQE_F_BUFFER as _; | |
398 | ||
399 | /// `IORING_CQE_F_MORE` | |
400 | const MORE = sys::IORING_CQE_F_MORE as _; | |
401 | } | |
402 | } | |
403 | ||
404 | bitflags::bitflags! { | |
405 | /// `IORING_FSYNC_*` flags for use with [`io_uring_sqe`]. | |
406 | #[derive(Default)] | |
407 | pub struct IoringFsyncFlags: u32 { | |
408 | /// `IORING_FSYNC_DATASYNC` | |
409 | const DATASYNC = sys::IORING_FSYNC_DATASYNC; | |
410 | } | |
411 | } | |
412 | ||
413 | bitflags::bitflags! { | |
414 | /// `IORING_TIMEOUT_*` and `IORING_LINK_TIMEOUT_UPDATE` flags for use with | |
415 | /// [`io_uring_sqe`]. | |
416 | #[derive(Default)] | |
417 | pub struct IoringTimeoutFlags: u32 { | |
418 | /// `IORING_TIMEOUT_ABS` | |
419 | const ABS = sys::IORING_TIMEOUT_ABS; | |
420 | ||
421 | /// `IORING_TIMEOUT_UPDATE` | |
422 | const UPDATE = sys::IORING_TIMEOUT_UPDATE; | |
423 | ||
424 | /// `IORING_TIMEOUT_BOOTTIME` | |
425 | const BOOTTIME = sys::IORING_TIMEOUT_BOOTTIME; | |
426 | ||
427 | /// `IORING_TIMEOUT_ETIME_SUCCESS` | |
428 | const ETIME_SUCCESS = sys::IORING_TIMEOUT_ETIME_SUCCESS; | |
429 | ||
430 | /// `IORING_TIMEOUT_REALTIME` | |
431 | const REALTIME = sys::IORING_TIMEOUT_REALTIME; | |
432 | ||
433 | /// `IORING_TIMEOUT_CLOCK_MASK` | |
434 | const CLOCK_MASK = sys::IORING_TIMEOUT_CLOCK_MASK; | |
435 | ||
436 | /// `IORING_TIMEOUT_UPDATE_MASK` | |
437 | const UPDATE_MASK = sys::IORING_TIMEOUT_UPDATE_MASK; | |
438 | ||
439 | /// `IORING_LINK_TIMEOUT_UPDATE` | |
440 | const LINK_TIMEOUT_UPDATE = sys::IORING_LINK_TIMEOUT_UPDATE; | |
441 | } | |
442 | } | |
443 | ||
444 | bitflags::bitflags! { | |
445 | /// `SPLICE_F_*` flags for use with [`io_uring_sqe`]. | |
446 | #[derive(Default)] | |
447 | pub struct SpliceFlags: u32 { | |
448 | /// `SPLICE_F_FD_IN_FIXED` | |
449 | const FD_IN_FIXED = sys::SPLICE_F_FD_IN_FIXED; | |
450 | } | |
451 | } | |
452 | ||
453 | bitflags::bitflags! { | |
454 | /// `IORING_FEAT_*` flags for use with [`io_uring_params`]. | |
455 | #[derive(Default)] | |
456 | pub struct IoringFeatureFlags: u32 { | |
457 | /// `IORING_FEAT_CQE_SKIP` | |
458 | const CQE_SKIP = sys::IORING_FEAT_CQE_SKIP; | |
459 | ||
460 | /// `IORING_FEAT_CUR_PERSONALITY` | |
461 | const CUR_PERSONALITY = sys::IORING_FEAT_CUR_PERSONALITY; | |
462 | ||
463 | /// `IORING_FEAT_EXT_ARG` | |
464 | const EXT_ARG = sys::IORING_FEAT_EXT_ARG; | |
465 | ||
466 | /// `IORING_FEAT_FAST_POLL` | |
467 | const FAST_POLL = sys::IORING_FEAT_FAST_POLL; | |
468 | ||
469 | /// `IORING_FEAT_NATIVE_WORKERS` | |
470 | const NATIVE_WORKERS = sys::IORING_FEAT_NATIVE_WORKERS; | |
471 | ||
472 | /// `IORING_FEAT_NODROP` | |
473 | const NODROP = sys::IORING_FEAT_NODROP; | |
474 | ||
475 | /// `IORING_FEAT_POLL_32BITS` | |
476 | const POLL_32BITS = sys::IORING_FEAT_POLL_32BITS; | |
477 | ||
478 | /// `IORING_FEAT_RSRC_TAGS` | |
479 | const RSRC_TAGS = sys::IORING_FEAT_RSRC_TAGS; | |
480 | ||
481 | /// `IORING_FEAT_RW_CUR_POS` | |
482 | const RW_CUR_POS = sys::IORING_FEAT_RW_CUR_POS; | |
483 | ||
484 | /// `IORING_FEAT_SINGLE_MMAP` | |
485 | const SINGLE_MMAP = sys::IORING_FEAT_SINGLE_MMAP; | |
486 | ||
487 | /// `IORING_FEAT_SQPOLL_NONFIXED` | |
488 | const SQPOLL_NONFIXED = sys::IORING_FEAT_SQPOLL_NONFIXED; | |
489 | ||
490 | /// `IORING_FEAT_SUBMIT_STABLE` | |
491 | const SUBMIT_STABLE = sys::IORING_FEAT_SUBMIT_STABLE; | |
492 | } | |
493 | } | |
494 | ||
495 | bitflags::bitflags! { | |
496 | /// `IO_URING_OP_*` flags for use with [`io_uring_probe_op`]. | |
497 | #[derive(Default)] | |
498 | pub struct IoringOpFlags: u16 { | |
499 | /// `IO_URING_OP_SUPPORTED` | |
500 | const SUPPORTED = sys::IO_URING_OP_SUPPORTED as _; | |
501 | } | |
502 | } | |
503 | ||
504 | bitflags::bitflags! { | |
505 | /// `IORING_SQ_*` flags. | |
506 | #[derive(Default)] | |
507 | pub struct IoringSqFlags: u32 { | |
508 | /// `IORING_SQ_NEED_WAKEUP` | |
509 | const NEED_WAKEUP = sys::IORING_SQ_NEED_WAKEUP; | |
510 | ||
511 | /// `IORING_SQ_CQ_OVERFLOW` | |
512 | const CQ_OVERFLOW = sys::IORING_SQ_CQ_OVERFLOW; | |
513 | } | |
514 | } | |
515 | ||
516 | bitflags::bitflags! { | |
517 | /// `IORING_CQ_*` flags. | |
518 | #[derive(Default)] | |
519 | pub struct IoringCqFlags: u32 { | |
520 | /// `IORING_CQ_EVENTFD_DISABLED` | |
521 | const EVENTFD_DISABLED = sys::IORING_CQ_EVENTFD_DISABLED; | |
522 | } | |
523 | } | |
524 | ||
525 | bitflags::bitflags! { | |
526 | /// `IORING_POLL_*` flags. | |
527 | #[derive(Default)] | |
528 | pub struct IoringPollFlags: u32 { | |
529 | /// `IORING_POLL_ADD_MULTI` | |
530 | const ADD_MULTI = sys::IORING_POLL_ADD_MULTI; | |
531 | ||
532 | /// `IORING_POLL_UPDATE_EVENTS` | |
533 | const UPDATE_EVENTS = sys::IORING_POLL_UPDATE_EVENTS; | |
534 | ||
535 | /// `IORING_POLL_UPDATE_USER_DATA` | |
536 | const UPDATE_USER_DATA = sys::IORING_POLL_UPDATE_USER_DATA; | |
537 | } | |
538 | } | |
539 | ||
540 | #[allow(missing_docs)] | |
541 | pub const IORING_CQE_BUFFER_SHIFT: u32 = sys::IORING_CQE_BUFFER_SHIFT as _; | |
542 | ||
543 | // Re-export these as `u64`, which is the `offset` type in `rustix::io::mmap`. | |
544 | #[allow(missing_docs)] | |
545 | pub const IORING_OFF_SQ_RING: u64 = sys::IORING_OFF_SQ_RING as _; | |
546 | #[allow(missing_docs)] | |
547 | pub const IORING_OFF_CQ_RING: u64 = sys::IORING_OFF_CQ_RING as _; | |
548 | #[allow(missing_docs)] | |
549 | pub const IORING_OFF_SQES: u64 = sys::IORING_OFF_SQES as _; | |
550 | ||
551 | /// `IORING_REGISTER_FILES_SKIP` | |
552 | #[inline] | |
553 | #[doc(alias = "IORING_REGISTER_FILES_SKIP")] | |
064997fb FG |
554 | pub const fn io_uring_register_files_skip() -> BorrowedFd<'static> { |
555 | let files_skip = sys::IORING_REGISTER_FILES_SKIP as RawFd; | |
556 | ||
557 | // Safety: `IORING_REGISTER_FILES_SKIP` is a reserved value that is never | |
558 | // dynamically allocated, so it'll remain valid for the duration of | |
559 | // `'static`. | |
560 | unsafe { BorrowedFd::<'static>::borrow_raw(files_skip) } | |
561 | } | |
562 | ||
563 | /// A pointer in the io_uring API. | |
564 | /// | |
565 | /// `io_uring`'s native API represents pointers as `u64` values. In order to | |
566 | /// preserve strict-provenance, use a `*mut c_void`. On platforms where | |
567 | /// pointers are narrower than 64 bits, this requires additional padding. | |
568 | #[repr(C)] | |
569 | #[derive(Copy, Clone)] | |
570 | pub struct io_uring_ptr { | |
571 | #[cfg(all(target_pointer_width = "32", target_endian = "big"))] | |
572 | #[doc(hidden)] | |
573 | pub __pad32: u32, | |
574 | #[cfg(all(target_pointer_width = "16", target_endian = "big"))] | |
575 | #[doc(hidden)] | |
576 | pub __pad16: u16, | |
577 | ||
578 | /// The pointer value. | |
579 | pub ptr: *mut c_void, | |
580 | ||
581 | #[cfg(all(target_pointer_width = "16", target_endian = "little"))] | |
582 | #[doc(hidden)] | |
583 | pub __pad16: u16, | |
584 | #[cfg(all(target_pointer_width = "32", target_endian = "little"))] | |
585 | #[doc(hidden)] | |
586 | pub __pad32: u32, | |
587 | } | |
588 | ||
589 | impl From<*mut c_void> for io_uring_ptr { | |
590 | #[inline] | |
591 | fn from(ptr: *mut c_void) -> Self { | |
592 | Self { | |
593 | ptr, | |
594 | ||
595 | #[cfg(target_pointer_width = "16")] | |
596 | __pad16: Default::default(), | |
597 | #[cfg(any(target_pointer_width = "16", target_pointer_width = "32"))] | |
598 | __pad32: Default::default(), | |
599 | } | |
600 | } | |
601 | } | |
602 | ||
603 | impl Default for io_uring_ptr { | |
604 | #[inline] | |
605 | fn default() -> Self { | |
606 | Self::from(null_mut()) | |
607 | } | |
608 | } | |
609 | ||
610 | /// User data in the io_uring API. | |
611 | /// | |
612 | /// `io_uring`'s native API represents `user_data` fields as `u64` values. In | |
613 | /// order to preserve strict-provenance, use a union which allows users to | |
614 | /// optionally store pointers. | |
615 | #[repr(C)] | |
616 | #[derive(Copy, Clone)] | |
617 | pub union io_uring_user_data { | |
618 | /// An arbitrary `u64`. | |
619 | pub u64_: u64, | |
620 | ||
621 | /// A pointer. | |
622 | pub ptr: io_uring_ptr, | |
623 | } | |
624 | ||
625 | impl io_uring_user_data { | |
626 | /// Return the `u64` value. | |
627 | #[inline] | |
628 | pub fn u64_(self) -> u64 { | |
629 | // Safety: All the fields have the same underlying representation. | |
630 | unsafe { self.u64_ } | |
631 | } | |
632 | ||
633 | /// Create a `Self` from a `u64` value. | |
634 | #[inline] | |
635 | pub fn from_u64(u64_: u64) -> Self { | |
636 | Self { u64_ } | |
637 | } | |
638 | ||
639 | /// Return the `ptr` pointer value. | |
640 | #[inline] | |
641 | pub fn ptr(self) -> *mut c_void { | |
642 | // Safety: All the fields have the same underlying representation. | |
643 | unsafe { self.ptr }.ptr | |
644 | } | |
645 | ||
646 | /// Create a `Self` from a pointer value. | |
647 | #[inline] | |
648 | pub fn from_ptr(ptr: *mut c_void) -> Self { | |
649 | Self { | |
650 | ptr: io_uring_ptr::from(ptr), | |
651 | } | |
652 | } | |
653 | } | |
654 | ||
655 | impl Default for io_uring_user_data { | |
656 | #[inline] | |
657 | fn default() -> Self { | |
658 | let mut s = ::core::mem::MaybeUninit::<Self>::uninit(); | |
659 | // Safety: All of Linux's io_uring structs may be zero-initialized. | |
660 | unsafe { | |
661 | ::core::ptr::write_bytes(s.as_mut_ptr(), 0, 1); | |
662 | s.assume_init() | |
663 | } | |
664 | } | |
665 | } | |
666 | ||
667 | impl core::fmt::Debug for io_uring_user_data { | |
668 | fn fmt(&self, fmt: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { | |
669 | // Safety: Just format as a `u64`, since formatting doesn't preserve | |
670 | // provenance, and we don't have a discriminant. | |
671 | unsafe { self.u64_.fmt(fmt) } | |
672 | } | |
673 | } | |
674 | ||
675 | /// An io_uring Submission Queue Entry. | |
676 | #[allow(missing_docs)] | |
677 | #[repr(C)] | |
678 | #[derive(Copy, Clone, Default)] | |
679 | pub struct io_uring_sqe { | |
680 | pub opcode: IoringOp, | |
681 | pub flags: IoringSqeFlags, | |
682 | pub ioprio: u16, | |
683 | pub fd: RawFd, | |
684 | pub off_or_addr2: off_or_addr2_union, | |
685 | pub addr_or_splice_off_in: addr_or_splice_off_in_union, | |
686 | pub len: u32, | |
687 | pub op_flags: op_flags_union, | |
688 | pub user_data: io_uring_user_data, | |
689 | pub buf: buf_union, | |
690 | pub personality: u16, | |
691 | pub splice_fd_in_or_file_index: splice_fd_in_or_file_index_union, | |
692 | pub __pad2: [u64; 2], | |
693 | } | |
694 | ||
695 | #[allow(missing_docs)] | |
696 | #[repr(C)] | |
697 | #[derive(Copy, Clone)] | |
698 | pub union off_or_addr2_union { | |
699 | pub off: u64, | |
700 | pub addr2: io_uring_ptr, | |
701 | } | |
702 | ||
703 | #[allow(missing_docs)] | |
704 | #[repr(C)] | |
705 | #[derive(Copy, Clone)] | |
706 | pub union addr_or_splice_off_in_union { | |
707 | pub addr: io_uring_ptr, | |
708 | pub splice_off_in: u64, | |
709 | } | |
710 | ||
711 | #[allow(missing_docs)] | |
712 | #[repr(C)] | |
713 | #[derive(Copy, Clone)] | |
714 | pub union op_flags_union { | |
715 | pub rw_flags: crate::io::ReadWriteFlags, | |
716 | pub fsync_flags: IoringFsyncFlags, | |
717 | pub poll_events: u16, | |
718 | pub poll32_events: u32, | |
719 | pub sync_range_flags: u32, | |
720 | /// `msg_flags` is split into `send_flags` and `recv_flags`. | |
721 | #[doc(alias = "msg_flags")] | |
722 | pub send_flags: crate::net::SendFlags, | |
723 | /// `msg_flags` is split into `send_flags` and `recv_flags`. | |
724 | #[doc(alias = "msg_flags")] | |
725 | pub recv_flags: crate::net::RecvFlags, | |
726 | pub timeout_flags: IoringTimeoutFlags, | |
727 | pub accept_flags: crate::net::AcceptFlags, | |
728 | pub cancel_flags: u32, | |
729 | pub open_flags: crate::fs::AtFlags, | |
730 | pub statx_flags: crate::fs::AtFlags, | |
731 | pub fadvise_advice: crate::fs::Advice, | |
732 | pub splice_flags: SpliceFlags, | |
733 | pub rename_flags: crate::fs::RenameFlags, | |
734 | pub unlink_flags: crate::fs::AtFlags, | |
735 | pub hardlink_flags: crate::fs::AtFlags, | |
736 | } | |
737 | ||
738 | #[allow(missing_docs)] | |
739 | #[repr(C, packed)] | |
740 | #[derive(Copy, Clone)] | |
741 | pub union buf_union { | |
742 | pub buf_index: u16, | |
743 | pub buf_group: u16, | |
744 | } | |
745 | ||
746 | #[allow(missing_docs)] | |
747 | #[repr(C)] | |
748 | #[derive(Copy, Clone)] | |
749 | pub union splice_fd_in_or_file_index_union { | |
750 | pub splice_fd_in: i32, | |
751 | pub file_index: u32, | |
752 | } | |
753 | ||
754 | /// An io_uring Completion Queue Entry. | |
755 | #[allow(missing_docs)] | |
756 | #[repr(C)] | |
757 | #[derive(Debug, Copy, Clone, Default)] | |
758 | pub struct io_uring_cqe { | |
759 | pub user_data: io_uring_user_data, | |
760 | pub res: i32, | |
761 | pub flags: IoringCqeFlags, | |
762 | } | |
763 | ||
764 | #[allow(missing_docs)] | |
765 | #[repr(C)] | |
766 | #[derive(Copy, Clone, Default)] | |
767 | pub struct io_uring_restriction { | |
768 | pub opcode: IoringRestrictionOp, | |
769 | pub register_or_sqe_op_or_sqe_flags: register_or_sqe_op_or_sqe_flags_union, | |
770 | pub resv: u8, | |
771 | pub resv2: [u32; 3], | |
772 | } | |
773 | ||
774 | #[allow(missing_docs)] | |
775 | #[repr(C)] | |
776 | #[derive(Copy, Clone)] | |
777 | pub union register_or_sqe_op_or_sqe_flags_union { | |
778 | pub register_op: IoringRegisterOp, | |
779 | pub sqe_op: IoringOp, | |
780 | pub sqe_flags: IoringSqeFlags, | |
781 | } | |
782 | ||
783 | #[allow(missing_docs)] | |
784 | #[repr(C)] | |
785 | #[derive(Debug, Copy, Clone, Default)] | |
786 | pub struct io_uring_params { | |
787 | pub sq_entries: u32, | |
788 | pub cq_entries: u32, | |
789 | pub flags: IoringSetupFlags, | |
790 | pub sq_thread_cpu: u32, | |
791 | pub sq_thread_idle: u32, | |
792 | pub features: IoringFeatureFlags, | |
793 | pub wq_fd: u32, | |
794 | pub resv: [u32; 3], | |
795 | pub sq_off: io_sqring_offsets, | |
796 | pub cq_off: io_cqring_offsets, | |
797 | } | |
798 | ||
799 | #[allow(missing_docs)] | |
800 | #[repr(C)] | |
801 | #[derive(Debug, Copy, Clone, Default)] | |
802 | pub struct io_sqring_offsets { | |
803 | pub head: u32, | |
804 | pub tail: u32, | |
805 | pub ring_mask: u32, | |
806 | pub ring_entries: u32, | |
807 | pub flags: u32, | |
808 | pub dropped: u32, | |
809 | pub array: u32, | |
810 | pub resv1: u32, | |
811 | pub resv2: u64, | |
812 | } | |
813 | ||
814 | #[allow(missing_docs)] | |
815 | #[repr(C)] | |
816 | #[derive(Debug, Copy, Clone, Default)] | |
817 | pub struct io_cqring_offsets { | |
818 | pub head: u32, | |
819 | pub tail: u32, | |
820 | pub ring_mask: u32, | |
821 | pub ring_entries: u32, | |
822 | pub overflow: u32, | |
823 | pub cqes: u32, | |
824 | pub flags: u32, | |
825 | pub resv1: u32, | |
826 | pub resv2: u64, | |
827 | } | |
828 | ||
829 | #[allow(missing_docs)] | |
830 | #[repr(C)] | |
831 | #[derive(Debug, Default)] | |
832 | pub struct io_uring_probe { | |
833 | pub last_op: IoringOp, | |
834 | pub ops_len: u8, | |
835 | pub resv: u16, | |
836 | pub resv2: [u32; 3], | |
837 | pub ops: sys::__IncompleteArrayField<io_uring_probe_op>, | |
838 | } | |
839 | ||
840 | #[allow(missing_docs)] | |
841 | #[repr(C)] | |
842 | #[derive(Debug, Copy, Clone, Default)] | |
843 | pub struct io_uring_probe_op { | |
844 | pub op: IoringOp, | |
845 | pub resv: u8, | |
846 | pub flags: IoringOpFlags, | |
847 | pub resv2: u32, | |
848 | } | |
849 | ||
850 | #[allow(missing_docs)] | |
851 | #[repr(C, align(8))] | |
852 | #[derive(Debug, Copy, Clone, Default)] | |
853 | pub struct io_uring_files_update { | |
854 | pub offset: u32, | |
855 | pub resv: u32, | |
856 | pub fds: u64, | |
857 | } | |
858 | ||
859 | #[allow(missing_docs)] | |
860 | #[repr(C, align(8))] | |
861 | #[derive(Debug, Copy, Clone, Default)] | |
862 | pub struct io_uring_rsrc_register { | |
863 | pub nr: u32, | |
864 | pub resv: u32, | |
865 | pub resv2: u64, | |
866 | pub data: u64, | |
867 | pub tags: u64, | |
868 | } | |
869 | ||
870 | #[allow(missing_docs)] | |
871 | #[repr(C, align(8))] | |
872 | #[derive(Debug, Copy, Clone, Default)] | |
873 | pub struct io_uring_rsrc_update { | |
874 | pub offset: u32, | |
875 | pub resv: u32, | |
876 | pub data: u64, | |
877 | } | |
878 | ||
879 | #[allow(missing_docs)] | |
880 | #[repr(C, align(8))] | |
881 | #[derive(Debug, Copy, Clone, Default)] | |
882 | pub struct io_uring_rsrc_update2 { | |
883 | pub offset: u32, | |
884 | pub resv: u32, | |
885 | pub data: u64, | |
886 | pub tags: u64, | |
887 | pub nr: u32, | |
888 | pub resv2: u32, | |
889 | } | |
890 | ||
891 | #[allow(missing_docs)] | |
892 | #[repr(C)] | |
893 | #[derive(Debug, Copy, Clone, Default)] | |
894 | pub struct io_uring_getevents_arg { | |
895 | pub sigmask: u64, | |
896 | pub sigmask_sz: u32, | |
897 | pub pad: u32, | |
898 | pub ts: u64, | |
899 | } | |
900 | ||
901 | #[allow(missing_docs)] | |
902 | #[repr(C)] | |
903 | #[derive(Debug, Copy, Clone)] | |
904 | pub struct iovec { | |
905 | pub iov_base: *mut c_void, | |
906 | pub iov_len: usize, | |
907 | } | |
908 | ||
909 | #[allow(missing_docs)] | |
910 | #[repr(C)] | |
911 | #[derive(Debug, Copy, Clone, Default)] | |
912 | pub struct open_how { | |
913 | /// An [`OFlags`] value represented as a `u64`. | |
914 | /// | |
915 | /// [`OFlags`]: crate::fs::OFlags | |
916 | pub flags: u64, | |
917 | ||
918 | /// A [`Mode`] value represented as a `u64`. | |
919 | /// | |
920 | /// [`Mode`]: crate::fs::Mode | |
921 | pub mode: u64, | |
922 | ||
923 | pub resolve: crate::fs::ResolveFlags, | |
924 | } | |
925 | ||
926 | impl Default for off_or_addr2_union { | |
927 | #[inline] | |
928 | fn default() -> Self { | |
929 | let mut s = ::core::mem::MaybeUninit::<Self>::uninit(); | |
930 | // Safety: All of Linux's io_uring structs may be zero-initialized. | |
931 | unsafe { | |
932 | ::core::ptr::write_bytes(s.as_mut_ptr(), 0, 1); | |
933 | s.assume_init() | |
934 | } | |
935 | } | |
936 | } | |
937 | ||
938 | impl Default for addr_or_splice_off_in_union { | |
939 | #[inline] | |
940 | fn default() -> Self { | |
941 | let mut s = ::core::mem::MaybeUninit::<Self>::uninit(); | |
942 | // Safety: All of Linux's io_uring structs may be zero-initialized. | |
943 | unsafe { | |
944 | ::core::ptr::write_bytes(s.as_mut_ptr(), 0, 1); | |
945 | s.assume_init() | |
946 | } | |
947 | } | |
948 | } | |
949 | ||
950 | impl Default for op_flags_union { | |
951 | #[inline] | |
952 | fn default() -> Self { | |
953 | let mut s = ::core::mem::MaybeUninit::<Self>::uninit(); | |
954 | // Safety: All of Linux's io_uring structs may be zero-initialized. | |
955 | unsafe { | |
956 | ::core::ptr::write_bytes(s.as_mut_ptr(), 0, 1); | |
957 | s.assume_init() | |
958 | } | |
959 | } | |
960 | } | |
961 | ||
962 | impl Default for buf_union { | |
963 | #[inline] | |
964 | fn default() -> Self { | |
965 | let mut s = ::core::mem::MaybeUninit::<Self>::uninit(); | |
966 | // Safety: All of Linux's io_uring structs may be zero-initialized. | |
967 | unsafe { | |
968 | ::core::ptr::write_bytes(s.as_mut_ptr(), 0, 1); | |
969 | s.assume_init() | |
970 | } | |
971 | } | |
972 | } | |
973 | ||
974 | impl Default for splice_fd_in_or_file_index_union { | |
975 | #[inline] | |
976 | fn default() -> Self { | |
977 | let mut s = ::core::mem::MaybeUninit::<Self>::uninit(); | |
978 | // Safety: All of Linux's io_uring structs may be zero-initialized. | |
979 | unsafe { | |
980 | ::core::ptr::write_bytes(s.as_mut_ptr(), 0, 1); | |
981 | s.assume_init() | |
982 | } | |
983 | } | |
984 | } | |
985 | ||
986 | impl Default for register_or_sqe_op_or_sqe_flags_union { | |
987 | #[inline] | |
988 | fn default() -> Self { | |
989 | let mut s = ::core::mem::MaybeUninit::<Self>::uninit(); | |
990 | // Safety: All of Linux's io_uring structs may be zero-initialized. | |
991 | unsafe { | |
992 | ::core::ptr::write_bytes(s.as_mut_ptr(), 0, 1); | |
993 | s.assume_init() | |
994 | } | |
995 | } | |
996 | } | |
997 | ||
998 | /// Check that our custom structs and unions have the same layout as the | |
999 | /// kernel's versions. | |
1000 | #[test] | |
1001 | fn io_uring_layouts() { | |
1002 | use core::mem::{align_of, size_of}; | |
1003 | use memoffset::{offset_of, span_of}; | |
1004 | ||
1005 | // Check that the size and alignment of a type match the `sys` bindings. | |
1006 | macro_rules! check_type { | |
1007 | ($struct:ident) => { | |
1008 | assert_eq!( | |
1009 | (size_of::<$struct>(), align_of::<$struct>()), | |
1010 | (size_of::<sys::$struct>(), align_of::<sys::$struct>()) | |
1011 | ); | |
1012 | }; | |
1013 | } | |
1014 | ||
1015 | // The same as `check_type`, but for unions we've renamed to avoid having | |
1016 | // types like "bindgen_ty_1" in the API. | |
1017 | macro_rules! check_renamed_union { | |
1018 | ($to:ident, $from:ident) => { | |
1019 | assert_eq!( | |
1020 | (size_of::<$to>(), align_of::<$to>()), | |
1021 | (size_of::<sys::$from>(), align_of::<sys::$from>()) | |
1022 | ); | |
1023 | }; | |
1024 | } | |
1025 | ||
1026 | // Check that the field of a struct has the same offset as the | |
1027 | // corresponding field in the `sys` bindings. | |
1028 | macro_rules! check_struct_field { | |
1029 | ($struct:ident, $field:ident) => { | |
1030 | assert_eq!( | |
1031 | offset_of!($struct, $field), | |
1032 | offset_of!(sys::$struct, $field) | |
1033 | ); | |
1034 | assert_eq!(span_of!($struct, $field), span_of!(sys::$struct, $field)); | |
1035 | }; | |
1036 | } | |
1037 | ||
1038 | // The same as `check_struct_field`, but for unions we've renamed to avoid | |
1039 | // having types like "bindgen_ty_1" in the API. | |
1040 | macro_rules! check_struct_renamed_union_field { | |
1041 | ($struct:ident, $to:ident, $from:ident) => { | |
1042 | assert_eq!(offset_of!($struct, $to), offset_of!(sys::$struct, $from)); | |
1043 | assert_eq!(span_of!($struct, $to), span_of!(sys::$struct, $from)); | |
1044 | }; | |
1045 | } | |
1046 | ||
1047 | // For the common case of no renaming, check all fields of a struct. | |
1048 | macro_rules! check_struct { | |
1049 | ($name:ident, $($field:ident),*) => { | |
1050 | // Check the size and alignment. | |
1051 | check_type!($name); | |
1052 | ||
1053 | // Check that we have all the fields. | |
1054 | let _test = $name { | |
1055 | // Safety: All of io_uring's types can be zero-initialized. | |
1056 | $($field: unsafe { core::mem::zeroed() }),* | |
1057 | }; | |
1058 | ||
1059 | // Check that the fields have the right sizes and offsets. | |
1060 | $(check_struct_field!($name, $field));* | |
1061 | }; | |
1062 | } | |
1063 | ||
1064 | check_renamed_union!(off_or_addr2_union, io_uring_sqe__bindgen_ty_1); | |
1065 | check_renamed_union!(addr_or_splice_off_in_union, io_uring_sqe__bindgen_ty_2); | |
1066 | check_renamed_union!(op_flags_union, io_uring_sqe__bindgen_ty_3); | |
1067 | check_renamed_union!(buf_union, io_uring_sqe__bindgen_ty_4); | |
1068 | check_renamed_union!(splice_fd_in_or_file_index_union, io_uring_sqe__bindgen_ty_5); | |
1069 | check_renamed_union!( | |
1070 | register_or_sqe_op_or_sqe_flags_union, | |
1071 | io_uring_restriction__bindgen_ty_1 | |
1072 | ); | |
1073 | ||
1074 | check_type!(io_uring_sqe); | |
1075 | check_struct_field!(io_uring_sqe, opcode); | |
1076 | check_struct_field!(io_uring_sqe, flags); | |
1077 | check_struct_field!(io_uring_sqe, ioprio); | |
1078 | check_struct_field!(io_uring_sqe, fd); | |
1079 | check_struct_renamed_union_field!(io_uring_sqe, off_or_addr2, __bindgen_anon_1); | |
1080 | check_struct_renamed_union_field!(io_uring_sqe, addr_or_splice_off_in, __bindgen_anon_2); | |
1081 | check_struct_field!(io_uring_sqe, len); | |
1082 | check_struct_renamed_union_field!(io_uring_sqe, op_flags, __bindgen_anon_3); | |
1083 | check_struct_field!(io_uring_sqe, user_data); | |
1084 | check_struct_renamed_union_field!(io_uring_sqe, buf, __bindgen_anon_4); | |
1085 | check_struct_field!(io_uring_sqe, personality); | |
1086 | check_struct_renamed_union_field!(io_uring_sqe, splice_fd_in_or_file_index, __bindgen_anon_5); | |
1087 | check_struct_field!(io_uring_sqe, __pad2); | |
1088 | ||
1089 | check_type!(io_uring_restriction); | |
1090 | check_struct_field!(io_uring_restriction, opcode); | |
1091 | check_struct_renamed_union_field!( | |
1092 | io_uring_restriction, | |
1093 | register_or_sqe_op_or_sqe_flags, | |
1094 | __bindgen_anon_1 | |
1095 | ); | |
1096 | check_struct_field!(io_uring_restriction, resv); | |
1097 | check_struct_field!(io_uring_restriction, resv2); | |
1098 | ||
1099 | check_struct!(io_uring_cqe, user_data, res, flags); | |
1100 | check_struct!( | |
1101 | io_uring_params, | |
1102 | sq_entries, | |
1103 | cq_entries, | |
1104 | flags, | |
1105 | sq_thread_cpu, | |
1106 | sq_thread_idle, | |
1107 | features, | |
1108 | wq_fd, | |
1109 | resv, | |
1110 | sq_off, | |
1111 | cq_off | |
1112 | ); | |
1113 | check_struct!( | |
1114 | io_sqring_offsets, | |
1115 | head, | |
1116 | tail, | |
1117 | ring_mask, | |
1118 | ring_entries, | |
1119 | flags, | |
1120 | dropped, | |
1121 | array, | |
1122 | resv1, | |
1123 | resv2 | |
1124 | ); | |
1125 | check_struct!( | |
1126 | io_cqring_offsets, | |
1127 | head, | |
1128 | tail, | |
1129 | ring_mask, | |
1130 | ring_entries, | |
1131 | overflow, | |
1132 | cqes, | |
1133 | flags, | |
1134 | resv1, | |
1135 | resv2 | |
1136 | ); | |
1137 | check_struct!(io_uring_probe, last_op, ops_len, resv, resv2, ops); | |
1138 | check_struct!(io_uring_probe_op, op, resv, flags, resv2); | |
1139 | check_struct!(io_uring_files_update, offset, resv, fds); | |
1140 | check_struct!(io_uring_rsrc_register, nr, resv, resv2, data, tags); | |
1141 | check_struct!(io_uring_rsrc_update, offset, resv, data); | |
1142 | check_struct!(io_uring_rsrc_update2, offset, resv, data, tags, nr, resv2); | |
1143 | check_struct!(io_uring_getevents_arg, sigmask, sigmask_sz, pad, ts); | |
1144 | check_struct!(iovec, iov_base, iov_len); | |
1145 | check_struct!(open_how, flags, mode, resolve); | |
1146 | } |