diff --git a/lib/vfs/src/host_fs.rs b/lib/vfs/src/host_fs.rs index 253f191b9e3..ef4f3fc4633 100644 --- a/lib/vfs/src/host_fs.rs +++ b/lib/vfs/src/host_fs.rs @@ -1365,7 +1365,5 @@ mod tests { .join("hello.txt")), "canonicalizing a crazily stupid path name", ); - - let _ = fs_extra::remove_items(&["./test_canonicalize"]); } } diff --git a/lib/vfs/src/overlay_fs.rs b/lib/vfs/src/overlay_fs.rs index 989d788896d..d27a99b4f95 100644 --- a/lib/vfs/src/overlay_fs.rs +++ b/lib/vfs/src/overlay_fs.rs @@ -43,11 +43,7 @@ use crate::{ /// /// A more complex example is #[derive(Clone, PartialEq, Eq)] -pub struct OverlayFileSystem
-where - P: FileSystem, - S: for<'a> FileSystems<'a>, -{ +pub struct OverlayFileSystem
{
primary: P,
secondaries: S,
}
@@ -136,10 +132,10 @@ where
}
if had_at_least_one_success {
- // Note: this sort is guaranteed to be stable, so it will prefer
- // filesystems "higher up" the chain.
+ // Note: this sort is guaranteed to be stable, so filesystems
+ // "higher up" the chain will be further towards the start.
entries.sort_by(|a, b| a.path.cmp(&b.path));
- // Make sure earlier entries shadow layer ones.
+ // Make sure later entries are removed in favour of earlier ones.
entries.dedup_by(|a, b| a.path == b.path);
Ok(ReadDir::new(entries))
@@ -149,15 +145,51 @@ where
}
fn create_dir(&self, path: &Path) -> Result<(), FsError> {
- self.for_each(|fs| fs.create_dir(path))
+ match self.primary.create_dir(path) {
+ Ok(()) => return Ok(()),
+ Err(e) if should_continue(e) => {}
+ Err(e) => return Err(e),
+ }
+
+ for fs in self.secondaries.iter_filesystems() {
+ if fs.is_dir(path) {
+ return Err(FsError::PermissionDenied);
+ }
+ }
+
+ Err(FsError::EntryNotFound)
}
fn remove_dir(&self, path: &Path) -> Result<(), FsError> {
- self.for_each(|fs| fs.remove_dir(path))
+ match self.primary.remove_dir(path) {
+ Ok(()) => return Ok(()),
+ Err(e) if should_continue(e) => {}
+ Err(e) => return Err(e),
+ }
+
+ for fs in self.secondaries.iter_filesystems() {
+ if fs.is_dir(path) {
+ return Err(FsError::PermissionDenied);
+ }
+ }
+
+ Err(FsError::EntryNotFound)
}
fn rename(&self, from: &Path, to: &Path) -> Result<(), FsError> {
- self.for_each(|fs| fs.rename(from, to))
+ match self.primary.rename(from, to) {
+ Ok(()) => return Ok(()),
+ Err(e) if should_continue(e) => {}
+ Err(e) => return Err(e),
+ }
+
+ for fs in self.secondaries.iter_filesystems() {
+ if fs.exists(from) {
+ return Err(FsError::PermissionDenied);
+ }
+ }
+
+ Err(FsError::EntryNotFound)
}
fn metadata(&self, path: &Path) -> Result