Skip to content

Commit e3c6331

Browse files
committed
fs: implement remove_dir_all
With this PR, the fs module is feature-complete and ready to be shipped.
1 parent c91e290 commit e3c6331

File tree

3 files changed

+43
-7
lines changed

3 files changed

+43
-7
lines changed

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

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,10 @@ pub fn test(sfs: ScopedProtocol<SimpleFileSystem>) -> Result<(), fs::Error> {
6060
assert_eq!(boxinfo.file_size(), data_to_write.len() as u64);
6161

6262
// test remove dir all
63-
// TODO
63+
fs.remove_dir_all(cstr16!("foo_dir\\1"))?;
64+
// file should not be available after remove all
65+
let err = fs.try_exists(cstr16!("foo_dir\\1"));
66+
assert!(err.is_err());
6467

6568
Ok(())
6669
}

uefi/src/fs/dir_entry_iter.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,9 @@ use alloc::boxed::Box;
66

77
/// Iterates over the entries of an UEFI directory. It returns boxed values of
88
/// type [`UefiFileInfo`].
9+
///
10+
/// Note that on UEFI/FAT-style file systems, the root dir usually doesn't
11+
/// return the entries `.` and `..`, whereas sub directories do.
912
#[derive(Debug)]
1013
pub struct UefiDirectoryIter(UefiDirectoryHandle);
1114

uefi/src/fs/file_system/fs.rs

Lines changed: 36 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ use core::fmt;
1111
use core::fmt::{Debug, Formatter};
1212
use core::ops::Deref;
1313
use log::debug;
14+
use uefi::CStr16;
15+
use uefi_macros::cstr16;
1416

1517
/// Return type for public [`FileSystem`] operations.
1618
pub type FileSystemResult<T> = Result<T, Error>;
@@ -156,6 +158,8 @@ impl<'a> FileSystem<'a> {
156158
pub fn remove_dir(&mut self, path: impl AsRef<Path>) -> FileSystemResult<()> {
157159
let path = path.as_ref();
158160

161+
// log::trace!("delete dir {}", path);
162+
159163
let file = self
160164
.open(path, UefiFileMode::ReadWrite, false)?
161165
.into_type()
@@ -181,16 +185,42 @@ impl<'a> FileSystem<'a> {
181185
}
182186
}
183187

184-
/*/// Removes a directory at this path, after removing all its contents. Use
188+
/// Removes a directory at this path, after removing all its contents. Use
185189
/// carefully!
186190
pub fn remove_dir_all(&mut self, path: impl AsRef<Path>) -> FileSystemResult<()> {
191+
const SKIP_DIRS: [&CStr16; 2] = [cstr16!("."), cstr16!("..")];
187192
let path = path.as_ref();
188-
}*/
193+
for file_info in self
194+
.read_dir(path)?
195+
.filter_map(|file_info_result| file_info_result.ok())
196+
{
197+
if SKIP_DIRS.contains(&file_info.file_name()) {
198+
continue;
199+
}
200+
201+
let mut abs_entry_path = PathBuf::new();
202+
abs_entry_path.push(path);
203+
abs_entry_path.push(file_info.file_name());
204+
if file_info.is_directory() {
205+
// delete all inner files
206+
// This recursion is fine as there are no links in UEFI/FAT file
207+
// systems. No cycles possible.
208+
self.remove_dir_all(&abs_entry_path)?;
209+
} else {
210+
self.remove_file(abs_entry_path)?;
211+
}
212+
}
213+
// Now that the dir is empty, we delete it as final step.
214+
self.remove_dir(path)?;
215+
Ok(())
216+
}
189217

190218
/// Removes a file from the filesystem.
191219
pub fn remove_file(&mut self, path: impl AsRef<Path>) -> FileSystemResult<()> {
192220
let path = path.as_ref();
193221

222+
// log::trace!("delete file {}", path);
223+
194224
let file = self
195225
.open(path, UefiFileMode::ReadWrite, false)?
196226
.into_type()
@@ -282,17 +312,17 @@ impl<'a> FileSystem<'a> {
282312
/// absolute path.
283313
///
284314
/// May create a file if [`UefiFileMode::CreateReadWrite`] is set. May
285-
/// create a directory if [`UefiFileMode::CreateReadWrite`] and `is_dir`
286-
/// is set.
315+
/// create a directory if [`UefiFileMode::CreateReadWrite`] and `create_dir`
316+
/// is set. The parameter `create_dir` is ignored otherwise.
287317
fn open(
288318
&mut self,
289319
path: &Path,
290320
mode: UefiFileMode,
291-
is_dir: bool,
321+
create_dir: bool,
292322
) -> FileSystemResult<UefiFileHandle> {
293323
validate_path(path)?;
294324

295-
let attr = if mode == UefiFileMode::CreateReadWrite && is_dir {
325+
let attr = if mode == UefiFileMode::CreateReadWrite && create_dir {
296326
UefiFileAttribute::DIRECTORY
297327
} else {
298328
UefiFileAttribute::empty()

0 commit comments

Comments
 (0)