1use std::{path::Path, time::Duration};
3use crate::error::{AsyncFusexError, AsyncFusexResult};
4use crate::fs_util::{*};
5use async_trait::async_trait;
6use tracing::{error, warn};
7use serde::{Deserialize, Serialize};
8use nix::sys::stat::SFlag;
9#[derive(Debug, Serialize, Deserialize, Eq, PartialEq)]
11pub struct DirEntry {
12 ino: INum,
14 name: String,
16 file_type: FileType,
18}
19
20#[derive(Debug, Serialize, Deserialize, Eq, PartialEq, Clone)]
24pub enum FileType {
25 Dir,
27 File,
29 Symlink,
31}
32
33impl TryFrom<SFlag> for FileType {
34 type Error = AsyncFusexError;
35
36 fn try_from(value: SFlag) -> Result<Self, Self::Error> {
48 match value {
49 SFlag::S_IFDIR => Ok(Self::Dir),
50 SFlag::S_IFREG => Ok(Self::File),
51 SFlag::S_IFLNK => Ok(Self::Symlink),
52 _ => {
53 error!("Try convert {:?} to FileType failed.", value);
54 Err(AsyncFusexError::ArgumentInvalid { context: vec![] })
55 }
56 }
57 }
58}
59
60impl From<FileType> for SFlag {
61 fn from(value: FileType) -> Self {
71 match value {
72 FileType::Dir => SFlag::S_IFDIR,
73 FileType::File => SFlag::S_IFREG,
74 FileType::Symlink => SFlag::S_IFLNK,
75 }
76 }
77}
78impl DirEntry {
79 #[must_use]
91 pub fn new(inum: INum, name: String, file_type: FileType) -> Self {
92 Self {
93 ino: inum,
94 name,
95 file_type,
96 }
97 }
98
99 #[must_use]
101 pub fn ino(&self) -> INum {
102 self.ino
103 }
104
105 #[must_use]
107 pub fn name(&self) -> &str {
108 &self.name
109 }
110
111 #[must_use]
113 pub fn file_type(&self) -> FileType {
114 self.file_type.clone()
115 }
116}
117
118#[async_trait]
120pub trait VirtualFs: Sync + Send {
121 async fn init(&self) -> AsyncFusexResult<()> {
123 Err(AsyncFusexError::Unimplemented {
124 context: vec!["init unimplemented".to_owned()],
125 })
126 }
127
128 async fn destroy(&self) -> AsyncFusexResult<()> {
130 Err(AsyncFusexError::Unimplemented {
131 context: vec!["destroy unimplemented".to_owned()],
132 })
133 }
134
135 async fn interrupt(&self, unique: u64) {
138 warn!(
139 "INTERRUPT received, request w/ unique={} interrupted",
140 unique
141 );
142 }
143
144 async fn lookup(
146 &self,
147 uid: u32,
148 gid: u32,
149 parent: INum,
150 name: &str,
151 ) -> AsyncFusexResult<(Duration, FileAttr, u64)>;
152
153 async fn forget(&self, ino: u64, nlookup: u64);
155
156 async fn getattr(&self, ino: u64) -> AsyncFusexResult<(Duration, FileAttr)>;
158
159 async fn setattr(
161 &self,
162 uid: u32,
163 gid: u32,
164 ino: u64,
165 param: SetAttrParam,
166 ) -> AsyncFusexResult<(Duration, FileAttr)>;
167
168 async fn readlink(&self, ino: u64) -> AsyncFusexResult<Vec<u8>>;
170
171 async fn mknod(&self, param: CreateParam) -> AsyncFusexResult<(Duration, FileAttr, u64)>;
173
174 async fn mkdir(&self, param: CreateParam) -> AsyncFusexResult<(Duration, FileAttr, u64)>;
176
177 async fn unlink(&self, uid: u32, gid: u32, parent: INum, name: &str) -> AsyncFusexResult<()>;
179
180 async fn rmdir(
182 &self,
183 uid: u32,
184 gid: u32,
185 parent: INum,
186 dir_name: &str,
187 ) -> AsyncFusexResult<Option<INum>>;
188
189 async fn symlink(
191 &self,
192 uid: u32,
193 gid: u32,
194 parent: INum,
195 name: &str,
196 target_path: &Path,
197 ) -> AsyncFusexResult<(Duration, FileAttr, u64)>;
198
199 async fn rename(&self, uid: u32, gid: u32, param: RenameParam) -> AsyncFusexResult<()>;
201
202 #[allow(unused_variables)]
204 async fn link(&self, newparent: u64, newname: &str) -> AsyncFusexResult<()> {
205 Err(AsyncFusexError::Unimplemented {
206 context: vec!["link unimplemented".to_owned()],
207 })
208 }
209
210 async fn open(&self, uid: u32, gid: u32, ino: u64, flags: u32) -> AsyncFusexResult<u64>;
212
213 async fn read(
215 &self,
216 ino: u64,
217 offset: u64,
218 size: u32,
219 buf: &mut Vec<u8>,
220 ) -> AsyncFusexResult<usize>;
221
222 async fn write(&self, ino: u64, offset: i64, data: &[u8], flags: u32) -> AsyncFusexResult<()>;
224
225 async fn flush(&self, ino: u64, lock_owner: u64) -> AsyncFusexResult<()>;
227
228 async fn release(
230 &self,
231 ino: u64,
232 flags: u32, lock_owner: u64,
234 flush: bool,
235 ) -> AsyncFusexResult<()>;
236
237 async fn fsync(&self, ino: u64, datasync: bool) -> AsyncFusexResult<()>;
239
240 async fn opendir(&self, uid: u32, gid: u32, ino: u64, flags: u32) -> AsyncFusexResult<u64>;
242
243 async fn readdir(
245 &self,
246 uid: u32,
247 gid: u32,
248 ino: u64,
249 fh: u64,
250 offset: i64,
251 ) -> AsyncFusexResult<Vec<DirEntry>>;
252
253 async fn releasedir(&self, ino: u64, fh: u64, flags: u32) -> AsyncFusexResult<()>;
255
256 async fn fsyncdir(&self, ino: u64, fh: u64, datasync: bool) -> AsyncFusexResult<()>;
258
259 async fn statfs(&self, uid: u32, gid: u32, ino: u64) -> AsyncFusexResult<StatFsParam>;
261
262 #[allow(unused_variables)]
264 async fn setxattr(
265 &self,
266 ino: u64,
267 name: &str,
268 value: &[u8],
269 flags: u32,
270 position: u32,
271 ) -> AsyncFusexResult<()> {
272 Err(AsyncFusexError::Unimplemented {
273 context: vec!["setxattr unimplemented".to_owned()],
274 })
275 }
276
277 #[allow(unused_variables)]
279 async fn getxattr(&self, ino: u64, name: &str, size: u32) -> AsyncFusexResult<()> {
280 Err(AsyncFusexError::Unimplemented {
281 context: vec!["getxattr unimplemented".to_owned()],
282 })
283 }
284
285 #[allow(unused_variables)]
287 async fn listxattr(&self, ino: u64, size: u32) -> AsyncFusexResult<()> {
288 Err(AsyncFusexError::Unimplemented {
289 context: vec!["listxattr unimplemented".to_owned()],
290 })
291 }
292
293 #[allow(unused_variables)]
295 async fn removexattr(&self, ino: u64, name: &str) -> AsyncFusexResult<()> {
296 Err(AsyncFusexError::Unimplemented {
297 context: vec!["removexattr unimplemented".to_owned()],
298 })
299 }
300
301 #[allow(unused_variables)]
308 async fn access(&self, uid: u32, gid: u32, ino: u64, mask: u32) -> AsyncFusexResult<()> {
309 Err(AsyncFusexError::Unimplemented {
310 context: vec!["access unimplemented".to_owned()],
311 })
312 }
313
314 #[allow(unused_variables)]
328 #[allow(clippy::too_many_arguments)]
329 async fn create(
330 &self,
331 uid: u32,
332 gid: u32,
333 ino: u64,
334 parent: u64,
335 name: &str,
336 mode: u32,
337 flags: u32,
338 ) -> AsyncFusexResult<()> {
339 Err(AsyncFusexError::Unimplemented {
340 context: vec!["create unimplemented".to_owned()],
341 })
342 }
343
344 #[allow(unused_variables)]
346 async fn getlk(
347 &self,
348 uid: u32,
349 gid: u32,
350 ino: u64,
351 lk_param: FileLockParam,
352 ) -> AsyncFusexResult<()> {
353 Err(AsyncFusexError::Unimplemented {
354 context: vec!["getlk unimplemented".to_owned()],
355 })
356 }
357
358 #[allow(unused_variables)]
369 async fn setlk(
370 &self,
371 uid: u32,
372 gid: u32,
373 ino: u64,
374 lk_param: FileLockParam,
375 sleep: bool,
376 ) -> AsyncFusexResult<()> {
377 Err(AsyncFusexError::Unimplemented {
378 context: vec!["setlk unimplemented".to_owned()],
379 })
380 }
381
382 #[allow(unused_variables)]
386 async fn bmap(
387 &self,
388 uid: u32,
389 gid: u32,
390 ino: u64,
391 blocksize: u32,
392 idx: u64,
393 ) -> AsyncFusexResult<()> {
394 Err(AsyncFusexError::Unimplemented {
395 context: vec!["bmap unimplemented".to_owned()],
396 })
397 }
398}