1pub type FsResult<T> = Result<T, FsError>;
7
8#[derive(Debug, Clone, Copy, PartialEq, Eq, thiserror::Error)]
9pub enum FsError {
10 #[error("Buffer too small")]
11 BufferTooSmall,
12 #[error("End of file")]
13 EndOfFile,
14 #[error("Disk I/O error")]
15 DiskError,
16 #[error("Device not ready")]
17 DeviceNotReady,
18 #[error("Filesystem corrupted")]
19 Corrupted,
20 #[error("Invalid block type")]
21 InvalidBlockType,
22 #[error("Invalid magic number")]
23 InvalidMagic,
24 #[error("Unsupported version")]
25 UnsupportedVersion,
26 #[error("Invalid block address")]
27 InvalidBlockAddress,
28 #[error("Inode not found")]
29 InodeNotFound,
30 #[error("Not found")]
31 NotFound,
32 #[error("Not a directory")]
33 NotADirectory,
34 #[error("Is a directory")]
35 IsADirectory,
36 #[error("Invalid path")]
37 InvalidPath,
38 #[error("Path too long")]
39 PathTooLong,
40 #[error("Arithmetic overflow")]
41 ArithmeticOverflow,
42 #[error("Security violation")]
43 SecurityViolation,
44 #[error("Alignment error")]
45 AlignmentError,
46 #[error("Out of memory")]
47 OutOfMemory,
48 #[error("No space left")]
49 NoSpace,
50 #[error("Too many open files")]
51 TooManyOpenFiles,
52 #[error("Invalid UTF-8")]
53 InvalidUtf8,
54 #[error("Invalid UTF-16")]
55 InvalidUtf16,
56 #[error("String too long")]
57 StringTooLong,
58 #[error("Not implemented")]
59 NotImplemented,
60 #[error("Not supported")]
61 NotSupported,
62 #[error("Read-only filesystem")]
63 ReadOnly,
64 #[error("Already exists")]
65 AlreadyExists,
66 #[error("Directory not empty")]
67 NotEmpty,
68 #[error("Invalid argument")]
69 InvalidArgument,
70 #[error("Permission denied")]
71 PermissionDenied,
72 #[error("Cross-device link")]
73 CrossDeviceLink,
74 #[error("Too many symbolic links")]
75 TooManySymlinks,
76 #[error("File too large")]
77 FileTooLarge,
78 #[error("Unknown filesystem")]
79 UnknownFilesystem,
80}
81
82impl FsError {
83 pub const fn to_ntstatus(self) -> i32 {
85 match self {
86 FsError::BufferTooSmall => 0xC0000023_u32 as i32,
87 FsError::EndOfFile => 0xC0000011_u32 as i32,
88 FsError::DiskError => 0xC000016A_u32 as i32,
89 FsError::DeviceNotReady => 0xC00000A3_u32 as i32,
90 FsError::Corrupted => 0xC0000032_u32 as i32,
91 FsError::InvalidBlockType => 0xC0000032_u32 as i32,
92 FsError::InvalidMagic => 0xC000014F_u32 as i32,
93 FsError::UnsupportedVersion => 0xC000019C_u32 as i32,
94 FsError::InvalidBlockAddress => 0xC0000015_u32 as i32,
95 FsError::InodeNotFound => 0xC000000F_u32 as i32,
96 FsError::NotFound => 0xC0000034_u32 as i32,
97 FsError::NotADirectory => 0xC0000103_u32 as i32,
98 FsError::IsADirectory => 0xC00000BA_u32 as i32,
99 FsError::InvalidPath => 0xC0000033_u32 as i32,
100 FsError::PathTooLong => 0xC0000106_u32 as i32,
101 FsError::ArithmeticOverflow => 0xC0000095_u32 as i32,
102 FsError::SecurityViolation => 0xC0000005_u32 as i32,
103 FsError::AlignmentError => 0x80000002_u32 as i32,
104 FsError::OutOfMemory => 0xC000009A_u32 as i32,
105 FsError::NoSpace => 0xC000007F_u32 as i32,
106 FsError::TooManyOpenFiles => 0xC000011F_u32 as i32,
107 FsError::InvalidUtf8 => 0xC000000D_u32 as i32,
108 FsError::InvalidUtf16 => 0xC000000D_u32 as i32,
109 FsError::StringTooLong => 0x80000005_u32 as i32,
110 FsError::NotImplemented => 0xC0000002_u32 as i32,
111 FsError::NotSupported => 0xC00000BB_u32 as i32,
112 FsError::ReadOnly => 0xC00000A2_u32 as i32,
113 FsError::AlreadyExists => 0xC0000035_u32 as i32,
114 FsError::NotEmpty => 0xC0000101_u32 as i32,
115 FsError::InvalidArgument => 0xC000000D_u32 as i32,
116 FsError::PermissionDenied => 0xC0000022_u32 as i32,
117 FsError::CrossDeviceLink => 0xC00000D4_u32 as i32,
118 FsError::TooManySymlinks => 0xC0000280_u32 as i32,
119 FsError::FileTooLarge => 0xC0000904_u32 as i32,
120 FsError::UnknownFilesystem => 0xC000014F_u32 as i32,
121 }
122 }
123
124 pub const fn is_security_error(self) -> bool {
126 matches!(
127 self,
128 FsError::ArithmeticOverflow | FsError::SecurityViolation
129 )
130 }
131
132 pub const fn is_corruption_error(self) -> bool {
134 matches!(
135 self,
136 FsError::Corrupted
137 | FsError::InvalidMagic
138 | FsError::InvalidBlockAddress
139 | FsError::InvalidBlockType
140 )
141 }
142}
143
144#[cfg(feature = "syscall")]
145impl From<FsError> for strat9_syscall::error::Error {
146 fn from(e: FsError) -> Self {
148 use strat9_syscall::error::Error as SE;
149 match e {
150 FsError::BufferTooSmall => SE::InvalidArgument,
151 FsError::EndOfFile => SE::IoError,
152 FsError::DiskError => SE::IoError,
153 FsError::DeviceNotReady => SE::Again,
154 FsError::Corrupted | FsError::InvalidBlockType | FsError::InvalidMagic => SE::IoError,
155 FsError::UnsupportedVersion => SE::NotSupported,
156 FsError::InvalidBlockAddress => SE::InvalidArgument,
157 FsError::InodeNotFound | FsError::NotFound => SE::NotFound,
158 FsError::NotADirectory | FsError::IsADirectory => SE::InvalidArgument,
159 FsError::InvalidPath | FsError::PathTooLong => SE::InvalidArgument,
160 FsError::ArithmeticOverflow | FsError::SecurityViolation => SE::Fault,
161 FsError::AlignmentError => SE::Fault,
162 FsError::OutOfMemory => SE::OutOfMemory,
163 FsError::NoSpace => SE::NoSpace,
164 FsError::TooManyOpenFiles => SE::Again,
165 FsError::InvalidUtf8 | FsError::InvalidUtf16 | FsError::StringTooLong => {
166 SE::InvalidArgument
167 }
168 FsError::NotImplemented => SE::NotImplemented,
169 FsError::NotSupported | FsError::ReadOnly => SE::NotSupported,
170 FsError::AlreadyExists => SE::AlreadyExists,
171 FsError::NotEmpty => SE::InvalidArgument,
172 FsError::InvalidArgument => SE::InvalidArgument,
173 FsError::PermissionDenied => SE::PermissionDenied,
174 FsError::CrossDeviceLink => SE::NotSupported,
175 FsError::TooManySymlinks => SE::IoError,
176 FsError::FileTooLarge => SE::NoSpace,
177 FsError::UnknownFilesystem => SE::NotSupported,
178 }
179 }
180}