Skip to content

Commit

Permalink
[Fix] fix WasiVirtualSys
Browse files Browse the repository at this point in the history
Signed-off-by: csh <[email protected]>
  • Loading branch information
L-jasmine committed Dec 14, 2023
1 parent 971cb10 commit 9b20217
Show file tree
Hide file tree
Showing 4 changed files with 207 additions and 63 deletions.
28 changes: 13 additions & 15 deletions crates/async-wasi/src/snapshots/common/vfs/impls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,19 +25,17 @@ pub struct MemoryDir {
is_open: usize,
}

// impl Drop for MemoryDir {
// fn drop(&mut self) {
// println!("{self:#?}")
// }
// }

// impl Drop for MemoryFile {
// fn drop(&mut self) {
// let c = self.context.get_ref().clone();
// println!("{self:#?}");
// println!("{:#?}", String::from_utf8(c));
// }
// }
impl Drop for MemoryDir {
fn drop(&mut self) {
log::trace!("\r\n{self:#?}")
}
}

impl Drop for MemoryFile {
fn drop(&mut self) {
log::trace!("\r\n{self:#?} \r\n {:#?}", self.context.get_ref());
}
}

impl WasiNode for MemoryDir {
fn fd_fdstat_get(&self) -> Result<super::FdStat, Errno> {
Expand Down Expand Up @@ -189,7 +187,7 @@ impl WasiVirtualDir for MemoryDir {
}

fn close(&mut self) -> usize {
if self.is_open > 1 {
if self.is_open > 0 {
self.is_open -= 1;
}
self.nlink
Expand Down Expand Up @@ -335,7 +333,7 @@ impl WasiVirtualFile for MemoryFile {
}

fn dec_link(&mut self) -> Result<usize, Errno> {
if self.nlink > 1 {
if self.nlink > 0 {
self.nlink -= 1;
}
Ok(self.nlink)
Expand Down
16 changes: 14 additions & 2 deletions crates/async-wasi/src/snapshots/common/vfs/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -427,11 +427,23 @@ pub trait WasiFileSys {
fs_rights_inheriting: WASIRights,
fdflags: FdFlags,
) -> Result<Self::Index, Errno>;
fn path_rename(&mut self, old_path: &str, new_path: &str) -> Result<(), Errno>;
fn path_rename(
&mut self,
old_dir: Self::Index,
old_path: &str,
new_dir: Self::Index,
new_path: &str,
) -> Result<(), Errno>;
fn path_create_directory(&mut self, dir_ino: Self::Index, path: &str) -> Result<(), Errno>;
fn path_remove_directory(&mut self, dir_ino: Self::Index, path: &str) -> Result<(), Errno>;
fn path_unlink_file(&mut self, dir_ino: Self::Index, path: &str) -> Result<(), Errno>;
fn path_link_file(&mut self, src_path: &str, dst_path: &str) -> Result<(), Errno>;
fn path_link_file(
&mut self,
old_dir: Self::Index,
old_path: &str,
new_dir: Self::Index,
new_path: &str,
) -> Result<(), Errno>;
fn path_filestat_get(
&self,
dir_ino: Self::Index,
Expand Down
159 changes: 136 additions & 23 deletions crates/async-wasi/src/snapshots/common/vfs/virtual_sys.rs
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,8 @@ impl<D: WasiVirtualDir, F: WasiVirtualFile> WasiVirtualSys<D, F> {
mut new_file: F,
) -> Result<usize, Errno> {
new_file.inc_link();
let new_ino = self.inodes.vacant_key();
new_file.set_ino(new_ino);
let new_ino = self.inodes.insert(Inode::File(new_file));

if let Some(Inode::Dir(dir)) = self.inodes.get_mut(dir_ino) {
Expand Down Expand Up @@ -290,8 +292,16 @@ impl<D: WasiVirtualDir, F: WasiVirtualFile> WasiFileSys for WasiVirtualSys<D, F>
}
}

fn path_rename(&mut self, old_path: &str, new_path: &str) -> Result<(), Errno> {
todo!()
fn path_rename(
&mut self,
old_dir: usize,
old_path: &str,
new_dir: usize,
new_path: &str,
) -> Result<(), Errno> {
self.path_link_file(old_dir, old_path, new_dir, new_path)?;
self.path_unlink_file(old_dir, old_path)?;
Ok(())
}

fn path_create_directory(&mut self, dir_ino: Self::Index, path: &str) -> Result<(), Errno> {
Expand Down Expand Up @@ -327,6 +337,7 @@ impl<D: WasiVirtualDir, F: WasiVirtualFile> WasiFileSys for WasiVirtualSys<D, F>
Inode::Dir(dir) => dir.close(),
Inode::File(file) => file.close(),
};
log::trace!("WasiVirtualSys path_open {ino} close_r={i}");
if i == 0 {
self.inodes.remove(ino);
}
Expand Down Expand Up @@ -364,28 +375,95 @@ impl<D: WasiVirtualDir, F: WasiVirtualFile> WasiFileSys for WasiVirtualSys<D, F>
self.dir_rights.can(WASIRights::PATH_UNLINK_FILE)?;

let path: &Path = path.as_ref();
let file_ino = self.find_inode_index(dir_ino, &path)?;
let parent_dir_ino = if let Some(parent) = path.parent() {
self.find_inode_index(dir_ino, &parent)?
} else {
dir_ino
};

let file_name = path
.file_name()
.ok_or(Errno::__WASI_ERRNO_INVAL)?
.to_str()
.ok_or(Errno::__WASI_ERRNO_ILSEQ)?;

match self
let file_ino = if let Inode::Dir(dir) = self
.inodes
.get2_mut(dir_ino, file_ino)
.ok_or(Errno::__WASI_ERRNO_NOENT)?
.get_mut(parent_dir_ino)
.ok_or(Errno::__WASI_ERRNO_BADF)?
{
(Inode::Dir(dir), Inode::File(file)) => {
dir.unlink_inode(&path)?;
let link = file.dec_link()?;
if link == 0 && !file.is_open() {
self.inodes.try_remove(file_ino);
}
Ok(())
let file_ino = dir
.find_inode(&file_name)
.ok_or(Errno::__WASI_ERRNO_NOENT)?;
dir.unlink_inode(&file_name)?;
file_ino
} else {
return Err(Errno::__WASI_ERRNO_NOTDIR);
};

if let Inode::File(file) = self
.inodes
.get_mut(file_ino)
.ok_or(Errno::__WASI_ERRNO_BADF)?
{
let link = file.dec_link()?;
log::trace!("WasiVirtualSys path_unlink_file {file_ino} nlink = {link}");

if link == 0 && !file.is_open() {
self.inodes.try_remove(file_ino);
}
(Inode::File(dir), _) => Err(Errno::__WASI_ERRNO_NOTDIR),
(Inode::Dir(_), Inode::Dir(_)) => Err(Errno::__WASI_ERRNO_ISDIR),
Ok(())
} else {
return Err(Errno::__WASI_ERRNO_ISDIR);
}
}

fn path_link_file(&mut self, _src_path: &str, _dst_path: &str) -> Result<(), Errno> {
Err(Errno::__WASI_ERRNO_NOSYS)
fn path_link_file(
&mut self,
old_dir: usize,
old_path: &str,
new_dir: usize,
new_path: &str,
) -> Result<(), Errno> {
log::trace!("WasiVirtualSys path_link_file ({old_dir} {old_path}) ({new_dir} {new_path})");

let old_inode = self.find_inode_index(old_dir, &old_path)?;

let new_path: &Path = new_path.as_ref();
let parent_dir_ino = if let Some(parent) = new_path.parent() {
self.find_inode_index(new_dir, &parent)?
} else {
new_dir
};

let file_name = new_path
.file_name()
.ok_or(Errno::__WASI_ERRNO_INVAL)?
.to_str()
.ok_or(Errno::__WASI_ERRNO_ILSEQ)?;

if let Inode::Dir(dir) = self
.inodes
.get_mut(parent_dir_ino)
.ok_or(Errno::__WASI_ERRNO_BADF)?
{
dir.link_inode(&file_name, old_inode)?;
} else {
return Err(Errno::__WASI_ERRNO_NOTDIR);
};

if let Inode::File(file) = self
.inodes
.get_mut(old_inode)
.ok_or(Errno::__WASI_ERRNO_BADF)?
{
let nlink = file.inc_link()?;
log::trace!("WasiVirtualSys path_link_file {old_inode} nlink = {nlink}");
} else {
return Err(Errno::__WASI_ERRNO_ISDIR);
};

Ok(())
}

fn path_filestat_get(
Expand Down Expand Up @@ -1076,9 +1154,26 @@ impl WasiFileSys for DiskFileSys {
Ok(ino)
}

fn path_rename(&mut self, old_path: &str, new_path: &str) -> Result<(), Errno> {
let old_path = self.get_absolutize_path(&old_path)?;
let new_path = self.get_absolutize_path(&new_path)?;
fn path_rename(
&mut self,
old_dir: usize,
old_path: &str,
new_dir: usize,
new_path: &str,
) -> Result<(), Errno> {
let old_parent_dir = match self.inodes.get(old_dir).ok_or(Errno::__WASI_ERRNO_BADF)? {
DiskInode::Dir(dir) => dir,
_ => return Err(Errno::__WASI_ERRNO_NOTDIR),
};

let old_path = old_parent_dir.get_absolutize_path(&old_path)?;

let new_parent_dir = match self.inodes.get(new_dir).ok_or(Errno::__WASI_ERRNO_BADF)? {
DiskInode::Dir(dir) => dir,
_ => return Err(Errno::__WASI_ERRNO_NOTDIR),
};
let new_path = new_parent_dir.get_absolutize_path(&new_path)?;

Ok(std::fs::rename(old_path, new_path)?)
}

Expand Down Expand Up @@ -1118,7 +1213,13 @@ impl WasiFileSys for DiskFileSys {
Ok(())
}

fn path_link_file(&mut self, _src_path: &str, _dst_path: &str) -> Result<(), Errno> {
fn path_link_file(
&mut self,
old_dir: Self::Index,
old_path: &str,
new_dir: Self::Index,
new_path: &str,
) -> Result<(), Errno> {
Err(Errno::__WASI_ERRNO_NOSYS)
}

Expand Down Expand Up @@ -1487,7 +1588,13 @@ where
Err(Errno::__WASI_ERRNO_BADF)
}

fn path_rename(&mut self, old_path: &str, new_path: &str) -> Result<(), Errno> {
fn path_rename(
&mut self,
old_dir: usize,
old_path: &str,
new_dir: usize,
new_path: &str,
) -> Result<(), Errno> {
Err(Errno::__WASI_ERRNO_BADF)
}

Expand All @@ -1503,7 +1610,13 @@ where
Err(Errno::__WASI_ERRNO_BADF)
}

fn path_link_file(&mut self, src_path: &str, dst_path: &str) -> Result<(), Errno> {
fn path_link_file(
&mut self,
old_dir: Self::Index,
old_path: &str,
new_dir: Self::Index,
new_path: &str,
) -> Result<(), Errno> {
Err(Errno::__WASI_ERRNO_BADF)
}

Expand Down
67 changes: 44 additions & 23 deletions crates/async-wasi/src/snapshots/env.rs
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,8 @@ impl VFS {
fs_rights_inheriting,
fdflags,
)?;
log::trace!("path_open {dirfd} {path} fd=({dev},{ino})");

if ino != 0 {
Ok(self.fds.insert(VFD::Inode { dev, ino }))
} else {
Expand All @@ -137,33 +139,51 @@ impl VFS {
new_dir_fd: usize,
new_path: &str,
) -> Result<(), Errno> {
if let (
VFD::Inode {
dev: dev0,
ino: ino0,
},
VFD::Inode {
dev: dev1,
ino: ino1,
},
) = self
.fds
.get2_mut(old_dir_fd, new_dir_fd)
.ok_or(Errno::__WASI_ERRNO_BADF)?
{
if *dev0 != *dev1 {
return Err(Errno::__WASI_ERRNO_XDEV);
log::trace!(
"path_rename {:?} {:?}",
(old_dir_fd, old_path),
(new_dir_fd, new_path)
);

let (dev0, ino0, dev1, ino1) = if old_dir_fd == new_dir_fd {
if let VFD::Inode { dev, ino } =
self.fds.get(old_dir_fd).ok_or(Errno::__WASI_ERRNO_BADF)?
{
(*dev, *ino, *dev, *ino)
} else {
return Err(Errno::__WASI_ERRNO_BADF);
}

if *ino0 != 0 || *ino1 != 0 {
return Err(Errno::__WASI_ERRNO_ACCES);
} else {
if let (
VFD::Inode {
dev: dev0,
ino: ino0,
},
VFD::Inode {
dev: dev1,
ino: ino1,
},
) = self
.fds
.get2_mut(old_dir_fd, new_dir_fd)
.ok_or(Errno::__WASI_ERRNO_BADF)?
{
(*dev0, *ino0, *dev1, *ino1)
} else {
return Err(Errno::__WASI_ERRNO_BADF);
}
};

let vfs = self.vfs.get_mut(*dev0).ok_or(Errno::__WASI_ERRNO_BADF)?;
vfs.path_rename(old_path, new_path)
} else {
Err(Errno::__WASI_ERRNO_BADF)
if dev0 != dev1 {
return Err(Errno::__WASI_ERRNO_XDEV);
}

if ino0 != 0 || ino1 != 0 {
return Err(Errno::__WASI_ERRNO_ACCES);
}

let vfs = self.vfs.get_mut(dev0).ok_or(Errno::__WASI_ERRNO_BADF)?;
vfs.path_rename(ino0, old_path, ino1, new_path)
}

pub fn fd_preopen_get(&mut self, fd: usize) -> Result<String, Errno> {
Expand Down Expand Up @@ -201,6 +221,7 @@ impl VFS {
return Err(Errno::__WASI_ERRNO_NOTSUP);
}
if let Some(vfs) = self.vfs.get_mut(*dev) {
log::trace!("fclose fd=({},{})", *dev, *ino);
vfs.fclose(*ino)?;
}
self.fds.remove(fd);
Expand Down

0 comments on commit 9b20217

Please sign in to comment.