compio_driver/sys/op/fs/
iour.rs1use io_uring::{opcode, types::*};
2use rustix::fs::{self, OFlags};
3
4use crate::{IourOpCode as OpCode, OpEntry, sys::op::*};
5
6unsafe impl<S: AsFd> OpCode for OpenFile<S> {
7 type Control = ();
8
9 fn create_entry(&mut self, _: &mut Self::Control) -> OpEntry {
10 opcode::OpenAt::new(Fd(self.dirfd.as_fd().as_raw_fd()), self.path.as_ptr())
11 .flags(self.flags.union(OFlags::CLOEXEC).bits() as _)
12 .mode(self.mode.bits())
13 .build()
14 .into()
15 }
16
17 fn call_blocking(&mut self, control: &mut Self::Control) -> io::Result<usize> {
18 self.call(control)
19 }
20
21 unsafe fn set_result(&mut self, _: &mut Self::Control, res: &io::Result<usize>, _: &Extra) {
22 if let Ok(fd) = res {
23 let fd = unsafe { OwnedFd::from_raw_fd(*fd as _) };
25 self.opened_fd = Some(fd);
26 }
27 }
28}
29
30unsafe impl OpCode for CloseFile {
31 type Control = ();
32
33 fn create_entry(&mut self, _: &mut Self::Control) -> OpEntry {
34 opcode::Close::new(Fd(self.fd.as_fd().as_raw_fd()))
35 .build()
36 .into()
37 }
38
39 fn call_blocking(&mut self, control: &mut Self::Control) -> io::Result<usize> {
40 self.call(control)
41 }
42}
43
44unsafe impl<S: AsFd> OpCode for TruncateFile<S> {
45 type Control = ();
46
47 fn create_entry(&mut self, _: &mut Self::Control) -> OpEntry {
48 opcode::Ftruncate::new(Fd(self.fd.as_fd().as_raw_fd()), self.size)
49 .build()
50 .into()
51 }
52
53 fn call_blocking(&mut self, _: &mut Self::Control) -> io::Result<usize> {
54 self.call()
55 }
56}
57
58pub struct FileStat<S> {
60 pub(crate) fd: S,
61 pub(crate) stat: fs::Statx,
62}
63
64impl<S> FileStat<S> {
65 pub fn new(fd: S) -> Self {
67 Self {
68 fd,
69 stat: unsafe { std::mem::zeroed() },
70 }
71 }
72}
73
74unsafe impl<S: AsFd> OpCode for FileStat<S> {
75 type Control = ();
76
77 fn create_entry(&mut self, _control: &mut Self::Control) -> OpEntry {
78 static EMPTY_NAME: &[u8] = b"\0";
79 opcode::Statx::new(
80 Fd(self.fd.as_fd().as_fd().as_raw_fd()),
81 EMPTY_NAME.as_ptr().cast(),
82 &raw mut self.stat as _,
83 )
84 .flags(libc::AT_EMPTY_PATH)
85 .mask(STATX_MASK.bits())
86 .build()
87 .into()
88 }
89
90 fn call_blocking(&mut self, _control: &mut Self::Control) -> io::Result<usize> {
91 self.stat = pal::statx(self.fd.as_fd(), c"", false)?;
92
93 Ok(0)
94 }
95}
96
97impl<S> IntoInner for FileStat<S> {
98 type Inner = Stat;
99
100 fn into_inner(self) -> Self::Inner {
101 statx_to_stat(self.stat)
102 }
103}
104
105pub struct PathStat<S: AsFd> {
107 pub(crate) dirfd: S,
108 pub(crate) path: CString,
109 pub(crate) stat: fs::Statx,
110 pub(crate) follow_symlink: bool,
111}
112
113impl<S: AsFd> PathStat<S> {
114 pub fn new(dirfd: S, path: CString, follow_symlink: bool) -> Self {
116 Self {
117 dirfd,
118 path,
119 stat: unsafe { std::mem::zeroed() },
120 follow_symlink,
121 }
122 }
123}
124
125unsafe impl<S: AsFd> OpCode for PathStat<S> {
126 type Control = ();
127
128 fn create_entry(&mut self, _control: &mut Self::Control) -> OpEntry {
129 let mut flags = libc::AT_EMPTY_PATH;
130 if !self.follow_symlink {
131 flags |= libc::AT_SYMLINK_NOFOLLOW;
132 }
133 opcode::Statx::new(
134 Fd(self.dirfd.as_fd().as_raw_fd()),
135 self.path.as_ptr(),
136 &raw mut self.stat as _,
137 )
138 .flags(flags)
139 .mask(STATX_MASK.bits())
140 .build()
141 .into()
142 }
143
144 fn call_blocking(&mut self, _control: &mut Self::Control) -> io::Result<usize> {
145 self.stat = statx(self.dirfd.as_fd(), &self.path, self.follow_symlink)?;
146
147 Ok(0)
148 }
149}
150
151impl<S: AsFd> IntoInner for PathStat<S> {
152 type Inner = Stat;
153
154 fn into_inner(self) -> Self::Inner {
155 statx_to_stat(self.stat)
156 }
157}
158
159unsafe impl<S: AsFd> OpCode for Sync<S> {
160 type Control = ();
161
162 fn create_entry(&mut self, _: &mut Self::Control) -> OpEntry {
163 opcode::Fsync::new(Fd(self.fd.as_fd().as_raw_fd()))
164 .flags(if self.datasync {
165 FsyncFlags::DATASYNC
166 } else {
167 FsyncFlags::empty()
168 })
169 .build()
170 .into()
171 }
172}
173
174unsafe impl<S: AsFd> OpCode for Unlink<S> {
175 type Control = ();
176
177 fn create_entry(&mut self, _: &mut Self::Control) -> OpEntry {
178 opcode::UnlinkAt::new(Fd(self.dirfd.as_fd().as_raw_fd()), self.path.as_ptr())
179 .flags(if self.dir { libc::AT_REMOVEDIR } else { 0 })
180 .build()
181 .into()
182 }
183
184 fn call_blocking(&mut self, control: &mut Self::Control) -> io::Result<usize> {
185 self.call(control)
186 }
187}
188
189unsafe impl<S: AsFd> OpCode for CreateDir<S> {
190 type Control = ();
191
192 fn create_entry(&mut self, _: &mut Self::Control) -> OpEntry {
193 opcode::MkDirAt::new(Fd(self.dirfd.as_fd().as_raw_fd()), self.path.as_ptr())
194 .mode(self.mode.bits())
195 .build()
196 .into()
197 }
198
199 fn call_blocking(&mut self, control: &mut Self::Control) -> io::Result<usize> {
200 self.call(control)
201 }
202}
203
204unsafe impl<S1: AsFd, S2: AsFd> OpCode for Rename<S1, S2> {
205 type Control = ();
206
207 fn create_entry(&mut self, _: &mut Self::Control) -> OpEntry {
208 opcode::RenameAt::new(
209 Fd(self.old_dirfd.as_fd().as_raw_fd()),
210 self.old_path.as_ptr(),
211 Fd(self.new_dirfd.as_fd().as_raw_fd()),
212 self.new_path.as_ptr(),
213 )
214 .build()
215 .into()
216 }
217
218 fn call_blocking(&mut self, control: &mut Self::Control) -> io::Result<usize> {
219 self.call(control)
220 }
221}
222
223unsafe impl<S: AsFd> OpCode for Symlink<S> {
224 type Control = ();
225
226 fn create_entry(&mut self, _: &mut Self::Control) -> OpEntry {
227 opcode::SymlinkAt::new(
228 Fd(self.dirfd.as_fd().as_raw_fd()),
229 self.source.as_ptr(),
230 self.target.as_ptr(),
231 )
232 .build()
233 .into()
234 }
235
236 fn call_blocking(&mut self, control: &mut Self::Control) -> io::Result<usize> {
237 self.call(control)
238 }
239}
240
241unsafe impl<S1: AsFd, S2: AsFd> OpCode for HardLink<S1, S2> {
242 type Control = ();
243
244 fn create_entry(&mut self, _: &mut Self::Control) -> OpEntry {
245 opcode::LinkAt::new(
246 Fd(self.source_dirfd.as_fd().as_raw_fd()),
247 self.source.as_ptr(),
248 Fd(self.target_dirfd.as_fd().as_raw_fd()),
249 self.target.as_ptr(),
250 )
251 .build()
252 .into()
253 }
254
255 fn call_blocking(&mut self, control: &mut Self::Control) -> io::Result<usize> {
256 self.call(control)
257 }
258}
259
260unsafe impl<S1: AsFd, S2: AsFd> OpCode for Splice<S1, S2> {
261 type Control = ();
262
263 fn create_entry(&mut self, _: &mut Self::Control) -> OpEntry {
264 opcode::Splice::new(
265 Fd(self.fd_in.as_fd().as_raw_fd()),
266 self.offset_in,
267 Fd(self.fd_out.as_fd().as_raw_fd()),
268 self.offset_out,
269 self.len.try_into().unwrap_or(u32::MAX),
270 )
271 .flags(self.flags.bits())
272 .build()
273 .into()
274 }
275
276 fn call_blocking(&mut self, control: &mut Self::Control) -> io::Result<usize> {
277 self.call(control)
278 }
279}