Skip to main content

strat9_kernel/async_io/
ops.rs

1//! Asynchronous I/O ABI types : stable across kernel versions.
2//!
3//! Defines the [`AsyncOp`] opcode enum, [`AsyncSqe`] (submission queue entry),
4//! and [`AsyncCqe`] (completion queue event) as `#[repr(C)]` structs.
5
6/// Operation opcode submitted through the async ring.
7///
8/// **Do not reorder** existing variants : the numeric value is part of the
9/// userspace ABI and must remain stable.
10#[repr(u8)]
11#[derive(Debug, Clone, Copy, PartialEq, Eq)]
12#[allow(dead_code)]
13pub enum AsyncOp {
14    /// No-op : used for testing and ring probing.
15    Nop = 0,
16    /// VFS: read from an open file descriptor.
17    Read = 1,
18    /// VFS: write to an open file descriptor.
19    Write = 2,
20    /// VFS: open a file (async version).
21    Open = 3,
22    /// VFS: close a file descriptor.
23    Close = 4,
24    /// VFS: stat / fstat a file.
25    Stat = 5,
26
27    /// IPC: send a message to a port (non-blocking).
28    IpcSend = 10,
29    /// IPC: receive a message from a port (non-blocking).
30    IpcRecv = 11,
31    /// IPC: combined send + recv (reply channel).
32    IpcCall = 12,
33
34    /// Poll: add an fd to the epoll set.
35    PollAdd = 20,
36    /// Poll: remove an fd from the epoll set.
37    PollRemove = 21,
38
39    /// Timer: arm a timeout completion.
40    Timeout = 30,
41    /// Timer: remove a previously armed timeout.
42    TimeoutRemove = 31,
43
44    /// Network: accept a connection on a listening socket.
45    Accept = 40,
46    /// Network: connect to a remote endpoint.
47    Connect = 41,
48
49    /// Storage: read sectors from a block device (AHCI / NVMe).
50    StorageRead = 50,
51    /// Storage: write sectors to a block device.
52    StorageWrite = 51,
53
54    /// Cancel an in-flight operation by its `user_data` token.
55    Cancel = 254,
56}
57
58// =============================================================================
59// SQE : Submission Queue Entry (64 bytes, cache-line aligned)
60// =============================================================================
61
62/// A single I/O submission, written by userspace into the SQ ring.
63#[repr(C)]
64#[derive(Debug, Clone, Copy)]
65pub struct AsyncSqe {
66    /// Operation opcode ([`AsyncOp`] variant).
67    pub opcode: u8,
68    /// Flags: `FIXED_FILE`, `IO_LINK`, `IO_DRAIN`, `IO_HARDLINK`.
69    pub flags: u8,
70    /// Priority hint (ioprio class << 13 | ioprio data).
71    pub ioprio: u16,
72    /// File descriptor (VFS fd) or IPC port id.
73    pub fd: u32,
74    /// File offset (for read/write) or endpoint id (for IPC).
75    pub off: u64,
76    /// Buffer virtual address (userspace pointer : validated by kernel).
77    pub addr: u64,
78    /// Buffer length in bytes.
79    pub len: u32,
80    /// Operation-specific flags (e.g. `RW_FSYNC` for write).
81    pub op_flags: u32,
82    /// Opaque correlation token : echoed in the CQE on completion.
83    pub user_data: u64,
84    /// Personality / capability context (silo token).
85    pub personality: u16,
86    /// Padding to 64 bytes (cache-line aligned).
87    pub _pad: [u8; 22],
88}
89
90// Compile-time size check : must be exactly 64 bytes.
91const _: () = assert!(core::mem::size_of::<AsyncSqe>() == 64);
92
93// =============================================================================
94// CQE : Completion Queue Event (16 bytes)
95// =============================================================================
96
97/// A single I/O completion, written by the kernel into the CQ ring.
98#[repr(C)]
99#[derive(Debug, Clone, Copy)]
100pub struct AsyncCqe {
101    /// Opaque correlation token from the originating SQE.
102    pub user_data: u64,
103    /// Result: bytes transferred on success, or a negative errno on failure.
104    pub res: i32,
105    /// Flags: `CQE_F_BUFFER`, `CQE_F_MORE`.
106    pub flags: u32,
107}
108
109// Compile-time size check : must be exactly 16 bytes.
110const _: () = assert!(core::mem::size_of::<AsyncCqe>() == 16);
111
112// =============================================================================
113// Shared constants
114// =============================================================================
115
116/// Maximum number of in-flight operations per ring.
117pub const MAX_IN_FLIGHT: usize = 4096;
118
119/// Default SQE ring size (must be a power of two).
120pub const DEFAULT_RING_ENTRIES: u32 = 256;