vmm/io_uring/operation/
mod.rs1mod cqe;
7mod sqe;
8
9use std::convert::From;
10use std::fmt::{self, Debug};
11
12pub use cqe::Cqe;
13pub(crate) use sqe::Sqe;
14
15use crate::io_uring::generated::{io_uring_op, io_uring_sqe, io_uring_sqe_flags_bit};
16
17pub type FixedFd = u32;
19
20#[repr(u8)]
21#[derive(Debug, Clone, Copy)]
22#[allow(clippy::cast_possible_truncation)]
24pub enum OpCode {
26 Read = io_uring_op::IORING_OP_READ as u8,
28 Write = io_uring_op::IORING_OP_WRITE as u8,
30 Fsync = io_uring_op::IORING_OP_FSYNC as u8,
32}
33
34impl From<OpCode> for &'static str {
36 fn from(opcode: OpCode) -> Self {
37 match opcode {
38 OpCode::Read => "read",
39 OpCode::Write => "write",
40 OpCode::Fsync => "fsync",
41 }
42 }
43}
44
45pub struct Operation<T> {
48 fd: FixedFd,
49 pub(crate) opcode: OpCode,
50 pub(crate) addr: Option<usize>,
51 pub(crate) len: Option<u32>,
52 flags: u8,
53 pub(crate) offset: Option<u64>,
54 pub(crate) user_data: T,
55}
56
57impl<T> fmt::Debug for Operation<T> {
59 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
60 write!(
61 f,
62 "
63 Operation {{
64 opcode: {:?},
65 addr: {:?},
66 len: {:?},
67 offset: {:?},
68 }}
69 ",
70 self.opcode, self.addr, self.len, self.offset
71 )
72 }
73}
74
75#[allow(clippy::len_without_is_empty)]
76impl<T: Debug> Operation<T> {
77 pub fn read(fd: FixedFd, addr: usize, len: u32, offset: u64, user_data: T) -> Self {
79 Self {
80 fd,
81 opcode: OpCode::Read,
82 addr: Some(addr),
83 len: Some(len),
84 flags: 0,
85 offset: Some(offset),
86 user_data,
87 }
88 }
89
90 pub fn write(fd: FixedFd, addr: usize, len: u32, offset: u64, user_data: T) -> Self {
92 Self {
93 fd,
94 opcode: OpCode::Write,
95 addr: Some(addr),
96 len: Some(len),
97 flags: 0,
98 offset: Some(offset),
99 user_data,
100 }
101 }
102
103 pub fn fsync(fd: FixedFd, user_data: T) -> Self {
105 Self {
106 fd,
107 opcode: OpCode::Fsync,
108 addr: None,
109 len: None,
110 flags: 0,
111 offset: None,
112 user_data,
113 }
114 }
115
116 pub(crate) fn fd(&self) -> FixedFd {
117 self.fd
118 }
119
120 #[cfg(test)]
122 pub(crate) fn set_linked(&mut self) {
123 self.flags |= 1 << io_uring_sqe_flags_bit::IOSQE_IO_LINK_BIT;
124 }
125
126 pub(crate) fn into_sqe(self, slab: &mut slab::Slab<T>) -> Sqe {
129 let mut inner: io_uring_sqe = unsafe { std::mem::zeroed() };
132
133 inner.opcode = self.opcode as u8;
134 inner.fd = i32::try_from(self.fd).unwrap();
135 inner.flags = self.flags | (1 << io_uring_sqe_flags_bit::IOSQE_FIXED_FILE_BIT);
137
138 if let Some(addr) = self.addr {
139 inner.__bindgen_anon_2.addr = addr as u64;
140 }
141
142 if let Some(len) = self.len {
143 inner.len = len;
144 }
145
146 if let Some(offset) = self.offset {
147 inner.__bindgen_anon_1.off = offset;
148 }
149 inner.user_data = slab.insert(self.user_data) as u64;
150
151 Sqe::new(inner)
152 }
153}