1pub mod attrs;
2pub mod basic;
3pub mod error;
4mod runner;
5
6pub use crate::runner::Runner;
7
8use crate::attrs::*;
9use crate::error::{FSError, FSResult};
10
11use std::ffi::{OsStr, OsString};
12use std::io::BufRead;
13use std::time::Duration;
14
15use typed_builder::TypedBuilder;
16
17#[derive(Debug, Copy, Clone, Hash, Eq, PartialEq)]
18pub struct INode(u64);
19
20impl INode {
21 pub const fn to_u64(self) -> u64 {
22 self.0
23 }
24
25 const fn next_inode(self) -> INode {
26 INode(self.0 + 1)
27 }
28}
29
30impl From<u64> for INode {
31 fn from(i: u64) -> INode {
32 INode(i)
33 }
34}
35
36#[derive(Debug, TypedBuilder)]
37pub struct Lookup {
38 attributes: FileAttributes,
39 inode: INode,
40
41 #[builder(default = None)]
42 generation: Option<u64>,
43
44 #[builder(default = Some(Duration::from_secs(1)))]
45 attr_timeout: Option<Duration>,
46
47 #[builder(default = Some(Duration::from_secs(1)))]
48 entry_timeout: Option<Duration>,
49}
50
51#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
52pub struct Filehandle(u64);
53
54impl Filehandle {
55 pub const fn from_raw(old: u64) -> Self {
56 Self(old)
57 }
58
59 pub const fn to_raw(self) -> u64 {
60 self.0
61 }
62}
63
64#[derive(Debug, TypedBuilder)]
65pub struct OpenFile {
66 handle: Filehandle,
67
68 #[builder(default = true)]
69 direct_io: bool,
70
71 #[builder(default = false)]
72 keep_cache: bool,
73
74 #[builder(default = true)]
75 seekable: bool,
76}
77
78#[derive(Debug, TypedBuilder)]
79pub struct OpenDir {
80 handle: Filehandle,
81
82 #[builder(default = true)]
83 direct_io: bool,
84
85 #[builder(default = false)]
86 keep_cache: bool,
87
88 #[builder(default = true)]
89 seekable: bool,
90
91 #[builder(default = true)]
92 cache_dir: bool,
93}
94
95#[derive(Debug, Copy, Clone)]
96pub enum FileType {
97 FIFO,
98 Unknown,
99 Regular,
100 Directory,
101 Socket,
102 Char,
103 Block,
104 Link,
105}
106
107impl FileType {
108 pub const fn to_libc_type(self) -> u8 {
109 match self {
110 Self::FIFO => libc::DT_FIFO,
111 Self::Unknown => libc::DT_UNKNOWN,
112 Self::Regular => libc::DT_REG,
113 Self::Directory => libc::DT_DIR,
114 Self::Socket => libc::DT_SOCK,
115 Self::Char => libc::DT_CHR,
116 Self::Block => libc::DT_BLK,
117 Self::Link => libc::DT_LNK,
118 }
119 }
120}
121
122#[derive(Debug, TypedBuilder, Clone)]
123pub struct DirEntry {
124 name: OsString,
125 inode: INode,
126 typ: FileType,
127 offset: u64,
128}
129
130#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
131pub enum SetXAttrFlags {
132 Create,
133 Replace,
134}
135
136impl SetXAttrFlags {
137 pub const fn to_libc_type(self) -> i32 {
138 match self {
139 Self::Create => libc::XATTR_CREATE,
140 Self::Replace => libc::XATTR_REPLACE,
141 }
142 }
143
144 pub const fn from_libc_type(from: i32) -> Option<Self> {
145 let create = from & libc::XATTR_CREATE != 0;
146 let replace = from & libc::XATTR_REPLACE != 0;
147
148 if create && replace {
149 None
151 } else if create {
152 Some(Self::Create)
153 } else if replace {
154 Some(Self::Replace)
155 } else {
156 None
158 }
159 }
160}
161
162#[derive(Debug, Hash, PartialEq, Eq, PartialOrd, Ord)]
165pub struct XAttrRef<'a> {
166 full_len: usize,
169 data: &'a [u8],
170}
171
172impl<'a> XAttrRef<'a> {
173 pub fn new(data: &'a [u8], full_len: usize) -> XAttrRef<'a> {
174 XAttrRef { full_len, data }
175 }
176
177 pub fn full_len(&self) -> usize {
178 self.full_len
179 }
180
181 pub fn data(&self) -> &[u8] {
182 self.data
183 }
184}
185
186pub trait Filesystem {
187 fn open(&mut self, _ino: INode, _flags: u32) -> FSResult<OpenFile> {
188 Err(FSError::NotImplemented)
189 }
190
191 fn open_dir(&mut self, _ino: INode, _flags: u32) -> FSResult<OpenDir> {
192 Err(FSError::NotImplemented)
193 }
194
195 fn lookup(&mut self, _parent: INode, _name: &OsStr) -> FSResult<Lookup> {
196 Err(FSError::NotImplemented)
197 }
198
199 fn getattr(&mut self, _inode: INode) -> FSResult<FileAttributes> {
200 Err(FSError::NotImplemented)
201 }
202
203 fn setattr(&mut self, _inode: INode, _attr: SetFileAttributes) -> FSResult<FileAttributes> {
204 Err(FSError::NotImplemented)
205 }
206
207 fn setxattr(
208 &mut self,
209 _ino: INode,
210 _attr_name: &OsStr,
211 _attr_value: &[u8],
212 _flags: SetXAttrFlags,
213 ) -> FSResult<()> {
214 Err(FSError::NotImplemented)
215 }
216
217 fn getxattr(
220 &mut self,
221 _ino: INode,
222 _attr_name: &OsStr,
223 _max_len: u32,
224 ) -> FSResult<XAttrRef<'_>> {
225 Err(FSError::NotImplemented)
226 }
227
228 fn listxattrs(&mut self, _ino: INode, _max_len: u32) -> FSResult<(OsString, u32)> {
235 Err(FSError::NotImplemented)
236 }
237
238 fn readdir(&mut self, _dir: INode, _offset: u64) -> FSResult<Vec<DirEntry>> {
245 Err(FSError::NotImplemented)
246 }
247
248 fn read(&mut self, _ino: INode, _offset: u64, _size: u32) -> FSResult<&[u8]> {
249 Err(FSError::NotImplemented)
250 }
251
252 fn write<T: BufRead>(
254 &mut self,
255 _ino: INode,
256 _offset: u64,
257 _size: u32,
258 _buf: T,
259 ) -> FSResult<u32> {
260 Err(FSError::NotImplemented)
261 }
262}