From c031632fec1728083bf661b108af4056e1725ee8 Mon Sep 17 00:00:00 2001 From: "M.Amin Rayej" Date: Fri, 17 May 2024 01:06:24 +0330 Subject: [PATCH 01/27] make rename file test repeatable --- tests/wasi-fyi/fs_rename-file.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/wasi-fyi/fs_rename-file.rs b/tests/wasi-fyi/fs_rename-file.rs index e598ce2dbb3..4a304d30b70 100644 --- a/tests/wasi-fyi/fs_rename-file.rs +++ b/tests/wasi-fyi/fs_rename-file.rs @@ -11,4 +11,6 @@ fn main() { let metadata = fs::metadata(new_path).unwrap(); assert!(metadata.is_file()); + + assert!(fs::rename(new_path, old_path).is_ok()); } From 12461088aa570e310332fa81d6146b536ab6fb6e Mon Sep 17 00:00:00 2001 From: "M.Amin Rayej" Date: Fri, 17 May 2024 01:06:38 +0330 Subject: [PATCH 02/27] make rename dir test repeatable --- tests/wasi-fyi/fs_rename-directory.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/wasi-fyi/fs_rename-directory.rs b/tests/wasi-fyi/fs_rename-directory.rs index ed04b887c67..af4ca249799 100644 --- a/tests/wasi-fyi/fs_rename-directory.rs +++ b/tests/wasi-fyi/fs_rename-directory.rs @@ -5,4 +5,5 @@ fn main() { let new_path = "/fyi/fs_rename-directory.dir/new_directory"; assert!(fs::rename(old_path, new_path).is_ok()); + assert!(fs::rename(new_path, old_path).is_ok()); } From 1f44a86acd3a30c17b6fae4f5d7f2a1e9209434f Mon Sep 17 00:00:00 2001 From: "M.Amin Rayej" Date: Fri, 17 May 2024 01:07:10 +0330 Subject: [PATCH 03/27] make path_create_directory return error if no dir was created --- lib/wasix/src/syscalls/wasi/path_create_directory.rs | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/lib/wasix/src/syscalls/wasi/path_create_directory.rs b/lib/wasix/src/syscalls/wasi/path_create_directory.rs index b7263ff21c5..bf20379e261 100644 --- a/lib/wasix/src/syscalls/wasi/path_create_directory.rs +++ b/lib/wasix/src/syscalls/wasi/path_create_directory.rs @@ -84,6 +84,7 @@ pub(crate) fn path_create_directory_internal( return Err(Errno::Inval); } + let mut created_dir = false; let mut cur_dir_inode = working_dir.inode; for comp in &path_vec { let processing_cur_dir_inode = cur_dir_inode.clone(); @@ -125,6 +126,7 @@ pub(crate) fn path_create_directory_internal( return Err(Errno::Notdir); } } else { + created_dir = true; state.fs_create_dir(&adjusted_path)?; } let kind = Kind::Dir { @@ -160,5 +162,9 @@ pub(crate) fn path_create_directory_internal( } } - Ok(()) + if created_dir { + Ok(()) + } else { + Err(Errno::Exist) + } } From b1b885cd45c6aa0133115b9313934e9f1e46a7cc Mon Sep 17 00:00:00 2001 From: "M.Amin Rayej" Date: Fri, 17 May 2024 01:07:35 +0330 Subject: [PATCH 04/27] make create dir test repeatable --- tests/wasi-fyi/fs_create_dir-new-directory.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/wasi-fyi/fs_create_dir-new-directory.rs b/tests/wasi-fyi/fs_create_dir-new-directory.rs index e9f99d69ece..56b3db4dc7b 100644 --- a/tests/wasi-fyi/fs_create_dir-new-directory.rs +++ b/tests/wasi-fyi/fs_create_dir-new-directory.rs @@ -2,4 +2,5 @@ use std::fs; fn main() { assert!(fs::create_dir("/fyi/fs_create_dir-new-directory.dir/new_directory").is_ok()); + assert!(fs::remove_dir("/fyi/fs_create_dir-new-directory.dir/new_directory").is_ok()); } From 7db2a81e6ad07745d1c09147b9babb4d9e0c31d6 Mon Sep 17 00:00:00 2001 From: "M.Amin Rayej" Date: Fri, 17 May 2024 01:08:00 +0330 Subject: [PATCH 05/27] enable create dir test --- tests/wasi-fyi/test.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/wasi-fyi/test.sh b/tests/wasi-fyi/test.sh index 4085c2c024e..e4eaff7327d 100755 --- a/tests/wasi-fyi/test.sh +++ b/tests/wasi-fyi/test.sh @@ -6,7 +6,7 @@ bash build.sh status=0 # Define skip list as an array -SKIP_LIST=("ported_readlink.wasm" "fs_create_dir-existing-directory.wasm") +SKIP_LIST=("ported_readlink.wasm") # List and process .foo files for file in *.wasm; do From 2d03ecaa70dc6f0a931f3477a05346a8b964e014 Mon Sep 17 00:00:00 2001 From: "M.Amin Rayej" Date: Fri, 17 May 2024 01:12:20 +0330 Subject: [PATCH 06/27] add wasi-fyi test for create dir all for existing dirs --- tests/wasi-fyi/fs_create_dir_all-existing.rs | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 tests/wasi-fyi/fs_create_dir_all-existing.rs diff --git a/tests/wasi-fyi/fs_create_dir_all-existing.rs b/tests/wasi-fyi/fs_create_dir_all-existing.rs new file mode 100644 index 00000000000..cd2a087c2c6 --- /dev/null +++ b/tests/wasi-fyi/fs_create_dir_all-existing.rs @@ -0,0 +1,7 @@ +use std::fs; + +fn main() { + assert!( + fs::create_dir_all("/fyi/fs_create_dir-existing-directory.dir/existing_directory").is_ok() + ); +} From 2f2fe7eab0c83382d7392007bcaf83701cd80e3e Mon Sep 17 00:00:00 2001 From: "M.Amin Rayej" Date: Fri, 17 May 2024 01:12:33 +0330 Subject: [PATCH 07/27] add wasi-fyi test for create dir all for new dirs --- tests/wasi-fyi/fs_create_dir_all-new-directories.rs | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 tests/wasi-fyi/fs_create_dir_all-new-directories.rs diff --git a/tests/wasi-fyi/fs_create_dir_all-new-directories.rs b/tests/wasi-fyi/fs_create_dir_all-new-directories.rs new file mode 100644 index 00000000000..0c46e5b14fa --- /dev/null +++ b/tests/wasi-fyi/fs_create_dir_all-new-directories.rs @@ -0,0 +1,6 @@ +use std::fs; + +fn main() { + assert!(fs::create_dir_all("/fyi/fs_create_dir_all-new-directories.dir/new_directory").is_ok()); + assert!(fs::remove_dir_all("/fyi/fs_create_dir_all-new-directories.dir/new_directory").is_ok()); +} From 7798f932848ae4070f3d8c8db4395f7cb60ddb5b Mon Sep 17 00:00:00 2001 From: "M.Amin Rayej" Date: Fri, 17 May 2024 02:56:52 +0330 Subject: [PATCH 08/27] add basic support for symlinks to the API --- lib/virtual-fs/src/lib.rs | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/lib/virtual-fs/src/lib.rs b/lib/virtual-fs/src/lib.rs index f3a4f66d2a0..dd23826d89c 100644 --- a/lib/virtual-fs/src/lib.rs +++ b/lib/virtual-fs/src/lib.rs @@ -91,6 +91,7 @@ pub trait ClonableVirtualFile: VirtualFile + Clone {} pub use ops::{copy_reference, copy_reference_ext}; pub trait FileSystem: fmt::Debug + Send + Sync + 'static + Upcastable { + fn readlink(&self, path: &Path) -> Result; fn read_dir(&self, path: &Path) -> Result; fn create_dir(&self, path: &Path) -> Result<()>; fn remove_dir(&self, path: &Path) -> Result<()>; @@ -99,9 +100,7 @@ pub trait FileSystem: fmt::Debug + Send + Sync + 'static + Upcastable { /// This method gets metadata without following symlinks in the path. /// Currently identical to `metadata` because symlinks aren't implemented /// yet. - fn symlink_metadata(&self, path: &Path) -> Result { - self.metadata(path) - } + fn symlink_metadata(&self, path: &Path) -> Result; fn remove_file(&self, path: &Path) -> Result<()>; fn new_open_options(&self) -> OpenOptions; @@ -128,6 +127,10 @@ where (**self).read_dir(path) } + fn readlink(&self, path: &Path) -> Result { + (**self).readlink(path) + } + fn create_dir(&self, path: &Path) -> Result<()> { (**self).create_dir(path) } @@ -144,6 +147,10 @@ where (**self).metadata(path) } + fn symlink_metadata(&self, path: &Path) -> Result { + (**self).symlink_metadata(path) + } + fn remove_file(&self, path: &Path) -> Result<()> { (**self).remove_file(path) } From 28f64bd4717db2096cce313d07ea99dd4c1b4e75 Mon Sep 17 00:00:00 2001 From: "M.Amin Rayej" Date: Fri, 17 May 2024 02:57:07 +0330 Subject: [PATCH 09/27] arc_fs: add symlink support --- lib/virtual-fs/src/arc_fs.rs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/lib/virtual-fs/src/arc_fs.rs b/lib/virtual-fs/src/arc_fs.rs index 734774fc16c..605f814ddc8 100644 --- a/lib/virtual-fs/src/arc_fs.rs +++ b/lib/virtual-fs/src/arc_fs.rs @@ -18,6 +18,10 @@ impl ArcFileSystem { } impl FileSystem for ArcFileSystem { + fn readlink(&self, path: &Path) -> Result { + self.fs.readlink(path) + } + fn read_dir(&self, path: &Path) -> Result { self.fs.read_dir(path) } From 0097fcf83bf116a4c26428e2bbe613c59ca6074e Mon Sep 17 00:00:00 2001 From: "M.Amin Rayej" Date: Fri, 17 May 2024 02:57:16 +0330 Subject: [PATCH 10/27] empty_fs: add symlink support --- lib/virtual-fs/src/empty_fs.rs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/lib/virtual-fs/src/empty_fs.rs b/lib/virtual-fs/src/empty_fs.rs index ce5be69637c..6745c337453 100644 --- a/lib/virtual-fs/src/empty_fs.rs +++ b/lib/virtual-fs/src/empty_fs.rs @@ -12,6 +12,10 @@ pub struct EmptyFileSystem {} #[allow(unused_variables)] impl FileSystem for EmptyFileSystem { + fn readlink(&self, path: &Path) -> Result { + Err(FsError::EntryNotFound) + } + fn read_dir(&self, path: &Path) -> Result { // Special-case the root path by returning an empty iterator. // An empty file system should still be readable, just not contain From a6d383f3b655bf18fb5c07baf8322198c8580eb1 Mon Sep 17 00:00:00 2001 From: "M.Amin Rayej" Date: Fri, 17 May 2024 02:57:37 +0330 Subject: [PATCH 11/27] host_fs: add symlink support --- lib/virtual-fs/src/host_fs.rs | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/lib/virtual-fs/src/host_fs.rs b/lib/virtual-fs/src/host_fs.rs index 43048b2dc21..b39a0e791d8 100644 --- a/lib/virtual-fs/src/host_fs.rs +++ b/lib/virtual-fs/src/host_fs.rs @@ -52,6 +52,10 @@ impl FileSystem { } impl crate::FileSystem for FileSystem { + fn readlink(&self, path: &Path) -> Result { + fs::read_link(path).map_err(Into::into) + } + fn read_dir(&self, path: &Path) -> Result { let read_dir = fs::read_dir(path)?; let mut data = read_dir @@ -153,6 +157,12 @@ impl crate::FileSystem for FileSystem { .and_then(TryInto::try_into) .map_err(Into::into) } + + fn symlink_metadata(&self, path: &Path) -> Result { + fs::symlink_metadata(path) + .and_then(TryInto::try_into) + .map_err(Into::into) + } } impl TryInto for std::fs::Metadata { From 12a581859af436b1bece3143574dcaeb45d599ba Mon Sep 17 00:00:00 2001 From: "M.Amin Rayej" Date: Fri, 17 May 2024 02:57:51 +0330 Subject: [PATCH 12/27] overlayfs: add symlink support --- lib/virtual-fs/src/overlay_fs.rs | 58 ++++++++++++++++++++++++++++++++ 1 file changed, 58 insertions(+) diff --git a/lib/virtual-fs/src/overlay_fs.rs b/lib/virtual-fs/src/overlay_fs.rs index cdee8580e21..e243327f33d 100644 --- a/lib/virtual-fs/src/overlay_fs.rs +++ b/lib/virtual-fs/src/overlay_fs.rs @@ -113,6 +113,35 @@ where S: for<'a> FileSystems<'a> + Send + Sync + 'static, for<'a> <>::Iter as IntoIterator>::IntoIter: Send, { + fn readlink(&self, path: &Path) -> crate::Result { + // Whiteout files can not be read, they are just markers + if ops::is_white_out(path).is_some() { + return Err(FsError::EntryNotFound); + } + + // Check if the file is in the primary + match self.primary.readlink(path) { + Ok(meta) => return Ok(meta), + Err(e) if should_continue(e) => {} + Err(e) => return Err(e), + } + + // There might be a whiteout, search for this + if ops::has_white_out(&self.primary, path) { + return Err(FsError::EntryNotFound); + } + + // Otherwise scan the secondaries + for fs in self.secondaries.filesystems() { + match fs.readlink(path) { + Err(e) if should_continue(e) => continue, + other => return other, + } + } + + Err(FsError::EntryNotFound) + } + fn read_dir(&self, path: &Path) -> Result { let mut entries = Vec::new(); let mut had_at_least_one_success = false; @@ -328,6 +357,35 @@ where Err(FsError::EntryNotFound) } + fn symlink_metadata(&self, path: &Path) -> crate::Result { + // Whiteout files can not be read, they are just markers + if ops::is_white_out(path).is_some() { + return Err(FsError::EntryNotFound); + } + + // Check if the file is in the primary + match self.primary.symlink_metadata(path) { + Ok(meta) => return Ok(meta), + Err(e) if should_continue(e) => {} + Err(e) => return Err(e), + } + + // There might be a whiteout, search for this + if ops::has_white_out(&self.primary, path) { + return Err(FsError::EntryNotFound); + } + + // Otherwise scan the secondaries + for fs in self.secondaries.filesystems() { + match fs.symlink_metadata(path) { + Err(e) if should_continue(e) => continue, + other => return other, + } + } + + Err(FsError::EntryNotFound) + } + fn remove_file(&self, path: &Path) -> Result<(), FsError> { // It is not possible to delete whiteout files directly, instead // one must delete the original file From 3e3d30dec25b0e35e9250fab1ae76b419a18a0b9 Mon Sep 17 00:00:00 2001 From: "M.Amin Rayej" Date: Fri, 17 May 2024 02:58:06 +0330 Subject: [PATCH 13/27] passthru_fs: add symlink support --- lib/virtual-fs/src/passthru_fs.rs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/lib/virtual-fs/src/passthru_fs.rs b/lib/virtual-fs/src/passthru_fs.rs index 08a940ed0c5..0d138a90075 100644 --- a/lib/virtual-fs/src/passthru_fs.rs +++ b/lib/virtual-fs/src/passthru_fs.rs @@ -18,6 +18,10 @@ impl PassthruFileSystem { } impl FileSystem for PassthruFileSystem { + fn readlink(&self, path: &Path) -> Result { + self.fs.readlink(path) + } + fn read_dir(&self, path: &Path) -> Result { self.fs.read_dir(path) } From 224157cdf3a86432ef118f7e095a34f8235a2cbd Mon Sep 17 00:00:00 2001 From: "M.Amin Rayej" Date: Fri, 17 May 2024 02:58:22 +0330 Subject: [PATCH 14/27] scoped_directory: add symlink support --- lib/virtual-fs/src/scoped_directory_fs.rs | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/lib/virtual-fs/src/scoped_directory_fs.rs b/lib/virtual-fs/src/scoped_directory_fs.rs index 43b3b020093..ac292fef82a 100644 --- a/lib/virtual-fs/src/scoped_directory_fs.rs +++ b/lib/virtual-fs/src/scoped_directory_fs.rs @@ -51,6 +51,11 @@ impl ScopedDirectoryFileSystem { } impl FileSystem for ScopedDirectoryFileSystem { + fn readlink(&self, path: &Path) -> crate::Result { + let path = self.prepare_path(path); + self.inner.readlink(&path) + } + fn read_dir(&self, path: &Path) -> Result { let path = self.prepare_path(path); @@ -94,6 +99,11 @@ impl FileSystem for ScopedDirectoryFileSystem { self.inner.metadata(&path) } + fn symlink_metadata(&self, path: &Path) -> crate::Result { + let path = self.prepare_path(path); + self.inner.symlink_metadata(&path) + } + fn remove_file(&self, path: &Path) -> Result<(), FsError> { let path = self.prepare_path(path); self.inner.remove_file(&path) From c41589cb3d5fa1cce01a930dd7f4121a1b97cdf8 Mon Sep 17 00:00:00 2001 From: "M.Amin Rayej" Date: Fri, 17 May 2024 02:58:28 +0330 Subject: [PATCH 15/27] static_fs: add symlink support --- lib/virtual-fs/src/static_fs.rs | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/lib/virtual-fs/src/static_fs.rs b/lib/virtual-fs/src/static_fs.rs index 767741ec743..9a45702a4a6 100644 --- a/lib/virtual-fs/src/static_fs.rs +++ b/lib/virtual-fs/src/static_fs.rs @@ -238,6 +238,20 @@ fn transform_into_read_dir(path: &Path, fs_entries: &[FsEntry<'_>]) -> crate::Re } impl FileSystem for StaticFileSystem { + fn readlink(&self, path: &Path) -> crate::Result { + let path = normalizes_path(path); + if self + .volumes + .values() + .find_map(|v| v.get_file_entry(&path).ok()) + .is_some() + { + Err(FsError::InvalidInput) + } else { + self.memory.readlink(Path::new(&path)) + } + } + fn read_dir(&self, path: &Path) -> Result { let path = normalizes_path(path); for volume in self.volumes.values() { From 79f9181c5090536ddf6c0b2ea506c731dc53ea09 Mon Sep 17 00:00:00 2001 From: "M.Amin Rayej" Date: Fri, 17 May 2024 02:58:35 +0330 Subject: [PATCH 16/27] tmp_fs: add symlink support --- lib/virtual-fs/src/tmp_fs.rs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/lib/virtual-fs/src/tmp_fs.rs b/lib/virtual-fs/src/tmp_fs.rs index 46e47f0fe53..0f0667f402c 100644 --- a/lib/virtual-fs/src/tmp_fs.rs +++ b/lib/virtual-fs/src/tmp_fs.rs @@ -61,6 +61,10 @@ impl TmpFileSystem { } impl FileSystem for TmpFileSystem { + fn readlink(&self, path: &Path) -> Result { + self.fs.readlink(path) + } + fn read_dir(&self, path: &Path) -> Result { self.fs.read_dir(path) } From 5a341f89f29268b03ecda035189c159e373b68a4 Mon Sep 17 00:00:00 2001 From: "M.Amin Rayej" Date: Fri, 17 May 2024 02:58:40 +0330 Subject: [PATCH 17/27] trace_fs: add symlink support --- lib/virtual-fs/src/trace_fs.rs | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/lib/virtual-fs/src/trace_fs.rs b/lib/virtual-fs/src/trace_fs.rs index 86abc0687bd..44aa5bbbbc5 100644 --- a/lib/virtual-fs/src/trace_fs.rs +++ b/lib/virtual-fs/src/trace_fs.rs @@ -39,6 +39,11 @@ impl FileSystem for TraceFileSystem where F: FileSystem, { + #[tracing::instrument(level = "trace", skip(self), err)] + fn readlink(&self, path: &std::path::Path) -> crate::Result { + self.0.readlink(path) + } + #[tracing::instrument(level = "trace", skip(self), err)] fn read_dir(&self, path: &std::path::Path) -> crate::Result { self.0.read_dir(path) @@ -68,6 +73,11 @@ where self.0.metadata(path) } + #[tracing::instrument(level = "trace", skip(self), err)] + fn symlink_metadata(&self, path: &std::path::Path) -> crate::Result { + self.0.symlink_metadata(path) + } + #[tracing::instrument(level = "trace", skip(self), err)] fn remove_file(&self, path: &std::path::Path) -> crate::Result<()> { self.0.remove_file(path) From 2f1d4749932b098bcd694ded6e349902ccaa54ca Mon Sep 17 00:00:00 2001 From: "M.Amin Rayej" Date: Fri, 17 May 2024 02:58:46 +0330 Subject: [PATCH 18/27] union_fs: add symlink support --- lib/virtual-fs/src/union_fs.rs | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/lib/virtual-fs/src/union_fs.rs b/lib/virtual-fs/src/union_fs.rs index 635a92c62bc..f9b3b95ca00 100644 --- a/lib/virtual-fs/src/union_fs.rs +++ b/lib/virtual-fs/src/union_fs.rs @@ -206,6 +206,32 @@ impl UnionFileSystem { } impl FileSystem for UnionFileSystem { + fn readlink(&self, path: &Path) -> Result { + debug!("readlink: path={}", path.display()); + let mut ret_error = FsError::EntryNotFound; + let path = path.to_string_lossy(); + for (path_inner, mount) in filter_mounts(&self.mounts, path.as_ref()) { + match mount.fs.readlink(Path::new(path_inner.as_str())) { + Ok(ret) => { + return Ok(ret); + } + Err(err) => { + // This fixes a bug when attempting to create the directory /usr when it does not exist + // on the x86 version of memfs + // TODO: patch virtual-fs and remove + if let FsError::NotAFile = &err { + ret_error = FsError::EntryNotFound; + } else { + debug!("readlink failed: (path={}) - {}", path, err); + ret_error = err; + } + } + } + } + debug!("readlink: failed={}", ret_error); + Err(ret_error) + } + fn read_dir(&self, path: &Path) -> Result { debug!("read_dir: path={}", path.display()); self.read_dir_internal(path) From fa99b3d183cf3cf00c2d398180c2842f45603f8d Mon Sep 17 00:00:00 2001 From: "M.Amin Rayej" Date: Fri, 17 May 2024 02:58:55 +0330 Subject: [PATCH 19/27] webc_fs: add symlink support --- lib/virtual-fs/src/webc_fs.rs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/lib/virtual-fs/src/webc_fs.rs b/lib/virtual-fs/src/webc_fs.rs index ba521564fc5..eba2387b673 100644 --- a/lib/virtual-fs/src/webc_fs.rs +++ b/lib/virtual-fs/src/webc_fs.rs @@ -304,6 +304,10 @@ where T: std::fmt::Debug + Send + Sync + 'static, T: Deref>, { + fn readlink(&self, _path: &Path) -> crate::Result { + Err(FsError::InvalidInput) + } + fn read_dir(&self, path: &Path) -> Result { let path = normalizes_path(path); let read_dir_result = self From a1c999cb762b5882ba96a883596ee31edbdccaa0 Mon Sep 17 00:00:00 2001 From: "M.Amin Rayej" Date: Fri, 17 May 2024 02:59:01 +0330 Subject: [PATCH 20/27] webc_volume_fs: add symlink support --- lib/virtual-fs/src/webc_volume_fs.rs | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/lib/virtual-fs/src/webc_volume_fs.rs b/lib/virtual-fs/src/webc_volume_fs.rs index ce107cf65dd..f75dffff213 100644 --- a/lib/virtual-fs/src/webc_volume_fs.rs +++ b/lib/virtual-fs/src/webc_volume_fs.rs @@ -49,6 +49,10 @@ impl WebcVolumeFileSystem { } impl FileSystem for WebcVolumeFileSystem { + fn readlink(&self, _path: &Path) -> crate::Result { + Err(FsError::InvalidInput) + } + fn read_dir(&self, path: &Path) -> Result { let meta = self.metadata(path)?; @@ -134,6 +138,10 @@ impl FileSystem for WebcVolumeFileSystem { .ok_or(FsError::EntryNotFound) } + fn symlink_metadata(&self, path: &Path) -> crate::Result { + self.metadata(path) + } + fn remove_file(&self, path: &Path) -> Result<(), FsError> { let meta = self.metadata(path)?; From c42391801d1b456d41f9482a3e81e97ce8bff77c Mon Sep 17 00:00:00 2001 From: "M.Amin Rayej" Date: Fri, 17 May 2024 02:59:18 +0330 Subject: [PATCH 21/27] mem_fs: add symlink support --- lib/virtual-fs/src/mem_fs/filesystem.rs | 29 +++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/lib/virtual-fs/src/mem_fs/filesystem.rs b/lib/virtual-fs/src/mem_fs/filesystem.rs index 3c1258048c4..97d5c6679a0 100644 --- a/lib/virtual-fs/src/mem_fs/filesystem.rs +++ b/lib/virtual-fs/src/mem_fs/filesystem.rs @@ -257,6 +257,18 @@ impl FileSystem { } impl crate::FileSystem for FileSystem { + fn readlink(&self, path: &Path) -> Result { + // Read lock. + let guard = self.inner.read().map_err(|_| FsError::Lock)?; + + // Canonicalize the path. + let (_, inode_of_directory) = guard.canonicalize(path)?; + match inode_of_directory { + InodeResolution::Found(_) => Err(FsError::InvalidInput), + InodeResolution::Redirect(fs, path) => fs.readlink(path.as_path()), + } + } + fn read_dir(&self, path: &Path) -> Result { // Read lock. let guard = self.inner.read().map_err(|_| FsError::Lock)?; @@ -591,6 +603,23 @@ impl crate::FileSystem for FileSystem { } } + fn symlink_metadata(&self, path: &Path) -> Result { + // Read lock. + let guard = self.inner.read().map_err(|_| FsError::Lock)?; + match guard.inode_of(path)? { + InodeResolution::Found(inode) => Ok(guard + .storage + .get(inode) + .ok_or(FsError::UnknownError)? + .metadata() + .clone()), + InodeResolution::Redirect(fs, path) => { + drop(guard); + fs.symlink_metadata(path.as_path()) + } + } + } + fn remove_file(&self, path: &Path) -> Result<()> { let (inode_of_parent, position, inode_of_file) = { // Read lock. From 05adc186c7a9ae31c7cc7c6645f24f00d9d8df31 Mon Sep 17 00:00:00 2001 From: "M.Amin Rayej" Date: Fri, 17 May 2024 02:59:48 +0330 Subject: [PATCH 22/27] wasifs: add symlink support --- lib/wasix/src/fs/mod.rs | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/lib/wasix/src/fs/mod.rs b/lib/wasix/src/fs/mod.rs index 3e5efed659a..24751ceec1e 100644 --- a/lib/wasix/src/fs/mod.rs +++ b/lib/wasix/src/fs/mod.rs @@ -308,6 +308,13 @@ impl WasiFsRoot { } impl FileSystem for WasiFsRoot { + fn readlink(&self, path: &Path) -> virtual_fs::Result { + match self { + WasiFsRoot::Sandbox(fs) => fs.readlink(path), + WasiFsRoot::Backing(fs) => fs.readlink(path), + } + } + fn read_dir(&self, path: &Path) -> virtual_fs::Result { match self { WasiFsRoot::Sandbox(fs) => fs.read_dir(path), @@ -992,7 +999,8 @@ impl WasiFs { } } else if file_type.is_symlink() { should_insert = false; - let link_value = file.read_link().map_err(map_io_err)?; + let link_value = + self.root_fs.readlink(&file).ok().ok_or(Errno::Noent)?; debug!("attempting to decompose path {:?}", link_value); let (pre_open_dir_fd, relative_path) = if link_value.is_relative() { @@ -2026,6 +2034,9 @@ impl FallbackFileSystem { } impl FileSystem for FallbackFileSystem { + fn readlink(&self, _path: &Path) -> virtual_fs::Result { + Self::fail() + } fn read_dir(&self, _path: &Path) -> Result { Self::fail(); } From f76129415b23bb24586e27502eef44b107a8ee5a Mon Sep 17 00:00:00 2001 From: "M.Amin Rayej" Date: Fri, 17 May 2024 03:00:11 +0330 Subject: [PATCH 23/27] relative_or_common_fs: add symlink support --- lib/wasix/src/runners/wasi_common.rs | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/lib/wasix/src/runners/wasi_common.rs b/lib/wasix/src/runners/wasi_common.rs index f2b2bb9bf36..1a48482c1fc 100644 --- a/lib/wasix/src/runners/wasi_common.rs +++ b/lib/wasix/src/runners/wasi_common.rs @@ -302,6 +302,10 @@ impl RelativeOrAbsolutePathHack { } impl virtual_fs::FileSystem for RelativeOrAbsolutePathHack { + fn readlink(&self, path: &Path) -> virtual_fs::Result { + self.execute(path, |fs, p| fs.readlink(p)) + } + fn read_dir(&self, path: &Path) -> virtual_fs::Result { self.execute(path, |fs, p| fs.read_dir(p)) } @@ -324,6 +328,10 @@ impl virtual_fs::FileSystem for RelativeOrAbsolutePathHack { self.execute(path, |fs, p| fs.metadata(p)) } + fn symlink_metadata(&self, path: &Path) -> virtual_fs::Result { + self.execute(path, |fs, p| fs.symlink_metadata(p)) + } + fn remove_file(&self, path: &Path) -> virtual_fs::Result<()> { self.execute(path, |fs, p| fs.remove_file(p)) } From 003d3f22d44cc1d80ae938a2982c6cdc9bdc2108 Mon Sep 17 00:00:00 2001 From: "M.Amin Rayej" Date: Fri, 17 May 2024 03:00:29 +0330 Subject: [PATCH 24/27] mapped_path_fs: add symlink support --- .../src/runtime/package_loader/load_package_tree.rs | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/lib/wasix/src/runtime/package_loader/load_package_tree.rs b/lib/wasix/src/runtime/package_loader/load_package_tree.rs index a7c14e06b98..0b1f3a82e4e 100644 --- a/lib/wasix/src/runtime/package_loader/load_package_tree.rs +++ b/lib/wasix/src/runtime/package_loader/load_package_tree.rs @@ -528,6 +528,11 @@ where F: FileSystem, M: Fn(&Path) -> Result + Send + Sync + 'static, { + fn readlink(&self, path: &Path) -> virtual_fs::Result { + let path = self.path(path)?; + self.inner.readlink(&path) + } + fn read_dir(&self, path: &Path) -> virtual_fs::Result { let path = self.path(path)?; self.inner.read_dir(&path) @@ -558,6 +563,11 @@ where self.inner.metadata(&path) } + fn symlink_metadata(&self, path: &Path) -> virtual_fs::Result { + let path = self.path(path)?; + self.inner.symlink_metadata(&path) + } + fn remove_file(&self, path: &Path) -> virtual_fs::Result<()> { let path = self.path(path)?; self.inner.remove_file(&path) From c78eadfb5955125d25a7f9b98f7d098e66170f69 Mon Sep 17 00:00:00 2001 From: "M.Amin Rayej" Date: Fri, 17 May 2024 03:00:55 +0330 Subject: [PATCH 25/27] remove unncessary print from ported_readlink test --- tests/wasi-fyi/ported_readlink.rs | 3 --- 1 file changed, 3 deletions(-) diff --git a/tests/wasi-fyi/ported_readlink.rs b/tests/wasi-fyi/ported_readlink.rs index 7bc3d7b0fba..2ad013f3043 100644 --- a/tests/wasi-fyi/ported_readlink.rs +++ b/tests/wasi-fyi/ported_readlink.rs @@ -6,9 +6,6 @@ use std::io::Read; fn main() { let sym_link_path = "/hamlet/bookmarks/2019-07-16"; - let p = std::path::Path::new(sym_link_path); - dbg!(&p); - println!("{}", p.exists()); let link_path = std::fs::read_link(sym_link_path).expect("Could not read link"); println!("{}", link_path.to_string_lossy()); From bbc3f0faa23a9b823c5cc4ada9677acc8cfd9d8c Mon Sep 17 00:00:00 2001 From: "M.Amin Rayej" Date: Fri, 17 May 2024 03:01:06 +0330 Subject: [PATCH 26/27] add output of ported_readlink test --- tests/wasi-fyi/ported_readlink.stdout | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tests/wasi-fyi/ported_readlink.stdout b/tests/wasi-fyi/ported_readlink.stdout index e69de29bb2d..547b33b18d2 100644 --- a/tests/wasi-fyi/ported_readlink.stdout +++ b/tests/wasi-fyi/ported_readlink.stdout @@ -0,0 +1,4 @@ +../act1/scene2.txt +SCENE II. A room of state in the castle. + + Enter KING CLAUDIUS, QUEEN GERTRUDE, HAMLET, POLONIUS, LAERTES, VOLTIMAND, CORNELI From 307fe98f749722980eb015bf4cf9fdca06c478c7 Mon Sep 17 00:00:00 2001 From: "M.Amin Rayej" Date: Fri, 17 May 2024 03:01:23 +0330 Subject: [PATCH 27/27] enable ported_readlink test --- tests/wasi-fyi/test.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/wasi-fyi/test.sh b/tests/wasi-fyi/test.sh index e4eaff7327d..5d5214b7b24 100755 --- a/tests/wasi-fyi/test.sh +++ b/tests/wasi-fyi/test.sh @@ -6,7 +6,7 @@ bash build.sh status=0 # Define skip list as an array -SKIP_LIST=("ported_readlink.wasm") +SKIP_LIST=() # List and process .foo files for file in *.wasm; do