Skip to content

Commit e5203be

Browse files
committed
fs: use new FileSystemError type
1 parent 24ef18c commit e5203be

File tree

3 files changed

+87
-113
lines changed

3 files changed

+87
-113
lines changed

uefi-test-runner/src/fs/mod.rs

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,10 @@
22
33
use alloc::string::{String, ToString};
44
use alloc::vec::Vec;
5-
use uefi::cstr16;
6-
use uefi::fs::{FileSystem, FileSystemError, PathBuf};
5+
use uefi::fs::{FileSystem, FileSystemError, FileSystemIOError, FileSystemIOErrorContext, PathBuf};
76
use uefi::proto::media::fs::SimpleFileSystem;
87
use uefi::table::boot::ScopedProtocol;
8+
use uefi::{cstr16, Error, Status};
99

1010
/// Tests functionality from the `uefi::fs` module. This test relies on a
1111
/// working File System Protocol, which is tested at a dedicated place.
@@ -24,9 +24,14 @@ pub fn test(sfs: ScopedProtocol<SimpleFileSystem>) -> Result<(), FileSystemError
2424
let read = String::from_utf8(read).expect("Should be valid utf8");
2525
assert_eq!(read.as_str(), data_to_write);
2626

27-
// test copy from non-existent file
27+
// test copy from non-existent file: does the error type work as expected?
2828
let err = fs.copy(cstr16!("not_found"), cstr16!("abc"));
29-
assert!(matches!(err, Err(FileSystemError::OpenError { .. })));
29+
let expected_err = FileSystemError::IO(FileSystemIOError {
30+
path: PathBuf::from(cstr16!("not_found")),
31+
context: FileSystemIOErrorContext::OpenError,
32+
uefi_error: Error::new(Status::NOT_FOUND, ()),
33+
});
34+
assert_eq!(err, Err(expected_err));
3035

3136
// test rename file + path buf replaces / with \
3237
fs.rename(
@@ -35,7 +40,7 @@ pub fn test(sfs: ScopedProtocol<SimpleFileSystem>) -> Result<(), FileSystemError
3540
)?;
3641
// file should not be available after rename
3742
let err = fs.read(cstr16!("foo_dir\\foo_cpy"));
38-
assert!(matches!(err, Err(FileSystemError::OpenError { .. })));
43+
assert!(err.is_err());
3944

4045
// test read dir on a sub dir
4146
let entries = fs

uefi/src/fs/file_system/fs.rs

Lines changed: 76 additions & 107 deletions
Original file line numberDiff line numberDiff line change
@@ -1,77 +1,17 @@
11
//! Module for [`FileSystem`].
22
3-
use super::super::*;
4-
use crate::fs::path::{validate_path, PathError};
5-
use crate::proto::media::file::{FileAttribute, FileInfo, FileType};
3+
use crate::fs::*;
4+
use crate::fs::{Path, PathBuf, UefiDirectoryIter, SEPARATOR_STR};
65
use crate::table::boot::ScopedProtocol;
76
use alloc::boxed::Box;
8-
use alloc::string::{FromUtf8Error, String, ToString};
7+
use alloc::string::String;
98
use alloc::vec;
109
use alloc::vec::Vec;
1110
use core::fmt;
1211
use core::fmt::{Debug, Formatter};
1312
use core::ops::Deref;
14-
use derive_more::Display;
1513
use log::debug;
1614

17-
/// All errors that can happen when working with the [`FileSystem`].
18-
#[derive(Debug, Clone, Display, PartialEq, Eq)]
19-
pub enum FileSystemError {
20-
/// Can't open the root directory of the underlying volume.
21-
CantOpenVolume,
22-
/// The path is invalid because of the underlying [`PathError`].
23-
///
24-
/// [`PathError`]: path::PathError
25-
IllegalPath(PathError),
26-
/// The file or directory was not found in the underlying volume.
27-
FileNotFound(String),
28-
/// The path is existent but does not correspond to a directory when a
29-
/// directory was expected.
30-
NotADirectory(String),
31-
/// The path is existent but does not correspond to a file when a file was
32-
/// expected.
33-
NotAFile(String),
34-
/// Can't delete the file.
35-
CantDeleteFile(String),
36-
/// Can't delete the directory.
37-
CantDeleteDirectory(String),
38-
/// Error writing bytes.
39-
WriteFailure,
40-
/// Error flushing file.
41-
FlushFailure,
42-
/// Error reading file.
43-
ReadFailure,
44-
/// Can't parse file content as UTF-8.
45-
Utf8Error(FromUtf8Error),
46-
/// Could not open the given path. Carries the path that could not be opened
47-
/// and the underlying UEFI error.
48-
#[display(fmt = "{path:?}")]
49-
OpenError {
50-
/// Path that caused the failure.
51-
path: String,
52-
/// More detailed failure description.
53-
error: crate::Error,
54-
},
55-
}
56-
57-
#[cfg(feature = "unstable")]
58-
impl core::error::Error for FileSystemError {
59-
fn source(&self) -> Option<&(dyn core::error::Error + 'static)> {
60-
match self {
61-
FileSystemError::IllegalPath(e) => Some(e),
62-
FileSystemError::Utf8Error(e) => Some(e),
63-
FileSystemError::OpenError { path: _path, error } => Some(error),
64-
_ => None,
65-
}
66-
}
67-
}
68-
69-
impl From<PathError> for FileSystemError {
70-
fn from(err: PathError) -> Self {
71-
Self::IllegalPath(err)
72-
}
73-
}
74-
7515
/// Return type for public [`FileSystem`] operations.
7616
pub type FileSystemResult<T> = Result<T, FileSystemError>;
7717

@@ -143,11 +83,11 @@ impl<'a> FileSystem<'a> {
14383
let path = path.as_ref();
14484
let mut file = self.open(path, UefiFileMode::Read, false)?;
14585
file.get_boxed_info().map_err(|err| {
146-
log::trace!("failed to fetch file info: {err:#?}");
147-
FileSystemError::OpenError {
148-
path: path.to_cstr16().to_string(),
149-
error: err,
150-
}
86+
FileSystemError::IO(FileSystemIOError {
87+
path: path.to_path_buf(),
88+
context: FileSystemIOErrorContext::Metadata,
89+
uefi_error: err,
90+
})
15191
})
15292
}
15393

@@ -158,18 +98,24 @@ impl<'a> FileSystem<'a> {
15898
let mut file = self
15999
.open(path, UefiFileMode::Read, false)?
160100
.into_regular_file()
161-
.ok_or(FileSystemError::NotAFile(path.to_cstr16().to_string()))?;
162-
let info = file
163-
.get_boxed_info::<FileInfo>()
164-
.map_err(|err| FileSystemError::OpenError {
165-
path: path.to_cstr16().to_string(),
166-
error: err,
167-
})?;
101+
.ok_or(FileSystemError::Logic(LogicError::NotAFile(
102+
path.to_path_buf(),
103+
)))?;
104+
let info = file.get_boxed_info::<UefiFileInfo>().map_err(|err| {
105+
FileSystemError::IO(FileSystemIOError {
106+
path: path.to_path_buf(),
107+
context: FileSystemIOErrorContext::Metadata,
108+
uefi_error: err,
109+
})
110+
})?;
168111

169112
let mut vec = vec![0; info.file_size() as usize];
170-
let read_bytes = file.read(vec.as_mut_slice()).map_err(|e| {
171-
log::error!("reading failed: {e:?}");
172-
FileSystemError::ReadFailure
113+
let read_bytes = file.read(vec.as_mut_slice()).map_err(|err| {
114+
FileSystemError::IO(FileSystemIOError {
115+
path: path.to_path_buf(),
116+
context: FileSystemIOErrorContext::ReadFailure,
117+
uefi_error: err.to_err_without_payload(),
118+
})
173119
})?;
174120

175121
// we read the whole file at once!
@@ -186,13 +132,15 @@ impl<'a> FileSystem<'a> {
186132
let dir = self
187133
.open(path, UefiFileMode::Read, false)?
188134
.into_directory()
189-
.ok_or(FileSystemError::NotADirectory(path.to_cstr16().to_string()))?;
135+
.ok_or(FileSystemError::Logic(LogicError::NotADirectory(
136+
path.to_path_buf(),
137+
)))?;
190138
Ok(UefiDirectoryIter::new(dir))
191139
}
192140

193-
/// Read the entire contents of a file into a string.
141+
/// Read the entire contents of a file into a Rust string.
194142
pub fn read_to_string(&mut self, path: impl AsRef<Path>) -> FileSystemResult<String> {
195-
String::from_utf8(self.read(path)?).map_err(FileSystemError::Utf8Error)
143+
String::from_utf8(self.read(path)?).map_err(FileSystemError::Utf8Encoding)
196144
}
197145

198146
/// Removes an empty directory.
@@ -205,13 +153,16 @@ impl<'a> FileSystem<'a> {
205153
.unwrap();
206154

207155
match file {
208-
FileType::Dir(dir) => dir.delete().map_err(|e| {
209-
log::error!("error removing dir: {e:?}");
210-
FileSystemError::CantDeleteDirectory(path.to_cstr16().to_string())
156+
UefiFileType::Dir(dir) => dir.delete().map_err(|err| {
157+
FileSystemError::IO(FileSystemIOError {
158+
path: path.to_path_buf(),
159+
context: FileSystemIOErrorContext::CantDeleteDirectory,
160+
uefi_error: err,
161+
})
211162
}),
212-
FileType::Regular(_) => {
213-
Err(FileSystemError::NotADirectory(path.to_cstr16().to_string()))
214-
}
163+
UefiFileType::Regular(_) => Err(FileSystemError::Logic(LogicError::NotADirectory(
164+
path.to_path_buf(),
165+
))),
215166
}
216167
}
217168

@@ -231,11 +182,16 @@ impl<'a> FileSystem<'a> {
231182
.unwrap();
232183

233184
match file {
234-
FileType::Regular(file) => file.delete().map_err(|e| {
235-
log::error!("error removing file: {e:?}");
236-
FileSystemError::CantDeleteFile(path.to_cstr16().to_string())
185+
UefiFileType::Regular(file) => file.delete().map_err(|err| {
186+
FileSystemError::IO(FileSystemIOError {
187+
path: path.to_path_buf(),
188+
context: FileSystemIOErrorContext::CantDeleteFile,
189+
uefi_error: err,
190+
})
237191
}),
238-
FileType::Dir(_) => Err(FileSystemError::NotAFile(path.to_cstr16().to_string())),
192+
UefiFileType::Dir(_) => Err(FileSystemError::Logic(LogicError::NotAFile(
193+
path.to_path_buf(),
194+
))),
239195
}
240196
}
241197

@@ -271,22 +227,35 @@ impl<'a> FileSystem<'a> {
271227
.into_regular_file()
272228
.unwrap();
273229

274-
handle.write(content.as_ref()).map_err(|e| {
275-
log::error!("only wrote {e:?} bytes");
276-
FileSystemError::WriteFailure
230+
handle.write(content.as_ref()).map_err(|err| {
231+
FileSystemError::IO(FileSystemIOError {
232+
path: path.to_path_buf(),
233+
context: FileSystemIOErrorContext::WriteFailure,
234+
uefi_error: err.to_err_without_payload(),
235+
})
277236
})?;
278-
handle.flush().map_err(|e| {
279-
log::error!("flush failure: {e:?}");
280-
FileSystemError::FlushFailure
237+
handle.flush().map_err(|err| {
238+
FileSystemError::IO(FileSystemIOError {
239+
path: path.to_path_buf(),
240+
context: FileSystemIOErrorContext::FlushFailure,
241+
uefi_error: err,
242+
})
281243
})?;
282244
Ok(())
283245
}
284246

285247
/// Opens a fresh handle to the root directory of the volume.
286248
fn open_root(&mut self) -> FileSystemResult<UefiDirectoryHandle> {
287-
self.0.open_volume().map_err(|e| {
288-
log::error!("Can't open root volume: {e:?}");
289-
FileSystemError::CantOpenVolume
249+
self.0.open_volume().map_err(|err| {
250+
FileSystemError::IO(FileSystemIOError {
251+
path: {
252+
let mut path = PathBuf::new();
253+
path.push(SEPARATOR_STR);
254+
path
255+
},
256+
context: FileSystemIOErrorContext::CantOpenVolume,
257+
uefi_error: err,
258+
})
290259
})
291260
}
292261

@@ -303,22 +272,22 @@ impl<'a> FileSystem<'a> {
303272
is_dir: bool,
304273
) -> FileSystemResult<UefiFileHandle> {
305274
validate_path(path)?;
306-
log::trace!("open validated path: {path}");
307275

308276
let attr = if mode == UefiFileMode::CreateReadWrite && is_dir {
309-
FileAttribute::DIRECTORY
277+
UefiFileAttribute::DIRECTORY
310278
} else {
311-
FileAttribute::empty()
279+
UefiFileAttribute::empty()
312280
};
313281

314282
self.open_root()?
315283
.open(path.to_cstr16(), mode, attr)
316284
.map_err(|err| {
317285
log::trace!("Can't open file {path}: {err:?}");
318-
FileSystemError::OpenError {
319-
path: path.to_cstr16().to_string(),
320-
error: err,
321-
}
286+
FileSystemError::IO(FileSystemIOError {
287+
path: path.to_path_buf(),
288+
context: FileSystemIOErrorContext::OpenError,
289+
uefi_error: err,
290+
})
322291
})
323292
}
324293
}

uefi/src/fs/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ mod file_system;
3535
mod path;
3636
mod uefi_types;
3737

38-
pub use file_system::{FileSystem, FileSystemError, FileSystemResult};
38+
pub use file_system::*;
3939
pub use path::*;
4040

4141
use dir_entry_iter::*;

0 commit comments

Comments
 (0)