diff --git a/src/fs/mem.rs b/src/fs/mem.rs index ec50894851..61002da066 100644 --- a/src/fs/mem.rs +++ b/src/fs/mem.rs @@ -279,16 +279,16 @@ impl VfsNode for RomFile { block_on(async { Ok(*self.data.attr.read().await) }, None) } - fn traverse_lstat(&self, components: &mut Vec<&str>) -> io::Result { - if !components.is_empty() { + fn traverse_lstat(&self, path: &str) -> io::Result { + if !path.is_empty() { return Err(Errno::Badf); } self.get_file_attributes() } - fn traverse_stat(&self, components: &mut Vec<&str>) -> io::Result { - if !components.is_empty() { + fn traverse_stat(&self, path: &str) -> io::Result { + if !path.is_empty() { return Err(Errno::Badf); } @@ -335,16 +335,16 @@ impl VfsNode for RamFile { block_on(async { Ok(self.data.read().await.attr) }, None) } - fn traverse_lstat(&self, components: &mut Vec<&str>) -> io::Result { - if !components.is_empty() { + fn traverse_lstat(&self, path: &str) -> io::Result { + if !path.is_empty() { return Err(Errno::Badf); } self.get_file_attributes() } - fn traverse_stat(&self, components: &mut Vec<&str>) -> io::Result { - if !components.is_empty() { + fn traverse_stat(&self, path: &str) -> io::Result { + if !path.is_empty() { return Err(Errno::Badf); } @@ -466,16 +466,16 @@ impl MemDirectory { async fn async_traverse_open( &self, - components: &mut Vec<&str>, + path: &str, opt: OpenOption, mode: AccessPermission, ) -> io::Result>> { - let component = components.pop().ok_or(Errno::Noent)?; + let (component, rest) = path.split_once("/").unwrap_or((path, "")); - if !components.is_empty() { + if !rest.is_empty() { let inner = self.inner.read().await; let directory = inner.get(component).ok_or(Errno::Noent)?; - return directory.traverse_open(components, opt, mode); + return directory.traverse_open(rest, opt, mode); } let mut inner = self.inner.write().await; @@ -517,16 +517,16 @@ impl VfsNode for MemDirectory { Ok(self.attr) } - fn traverse_mkdir(&self, components: &mut Vec<&str>, mode: AccessPermission) -> io::Result<()> { + fn traverse_mkdir(&self, path: &str, mode: AccessPermission) -> io::Result<()> { block_on( async { - let component = components.pop().ok_or(Errno::Badf)?; + let (component, rest) = path.split_once("/").unwrap_or((path, "")); if let Some(directory) = self.inner.read().await.get(component) { - return directory.traverse_mkdir(components, mode); + return directory.traverse_mkdir(rest, mode); } - if !components.is_empty() { + if !rest.is_empty() { return Err(Errno::Badf); } @@ -540,15 +540,15 @@ impl VfsNode for MemDirectory { ) } - fn traverse_rmdir(&self, components: &mut Vec<&str>) -> io::Result<()> { + fn traverse_rmdir(&self, path: &str) -> io::Result<()> { block_on( async { - let component = components.pop().ok_or(Errno::Badf)?; + let (component, rest) = path.split_once("/").unwrap_or((path, "")); - if !components.is_empty() { + if !rest.is_empty() { let inner = &*self.inner.read().await; let directory = inner.get(component).ok_or(Errno::Badf)?; - return directory.traverse_rmdir(components); + return directory.traverse_rmdir(rest); } let mut guard = self.inner.write().await; @@ -565,15 +565,15 @@ impl VfsNode for MemDirectory { ) } - fn traverse_unlink(&self, components: &mut Vec<&str>) -> io::Result<()> { + fn traverse_unlink(&self, path: &str) -> io::Result<()> { block_on( async { - let component = components.pop().ok_or(Errno::Badf)?; + let (component, rest) = path.split_once("/").unwrap_or((path, "")); - if !components.is_empty() { + if !rest.is_empty() { let inner = self.inner.read().await; let directory = inner.get(component).ok_or(Errno::Badf)?; - return directory.traverse_unlink(components); + return directory.traverse_unlink(rest); } let mut guard = self.inner.write().await; @@ -590,13 +590,13 @@ impl VfsNode for MemDirectory { ) } - fn traverse_readdir(&self, components: &mut Vec<&str>) -> io::Result> { + fn traverse_readdir(&self, path: &str) -> io::Result> { block_on( async { - if let Some(component) = components.pop() { + if let Some((component, rest)) = path.split_once("/") { let inner = self.inner.read().await; let directory = inner.get(component).ok_or(Errno::Badf)?; - return directory.traverse_readdir(components); + return directory.traverse_readdir(rest); }; let mut entries = Vec::new(); @@ -610,15 +610,15 @@ impl VfsNode for MemDirectory { ) } - fn traverse_lstat(&self, components: &mut Vec<&str>) -> io::Result { + fn traverse_lstat(&self, path: &str) -> io::Result { block_on( async { - let component = components.pop().ok_or(Errno::Nosys)?; + let (component, rest) = path.split_once("/").unwrap_or((path, "")); - if !components.is_empty() { + if !rest.is_empty() { let inner = self.inner.read().await; let directory = inner.get(component).ok_or(Errno::Badf)?; - return directory.traverse_lstat(components); + return directory.traverse_lstat(rest); } let inner = self.inner.read().await; @@ -629,15 +629,15 @@ impl VfsNode for MemDirectory { ) } - fn traverse_stat(&self, components: &mut Vec<&str>) -> io::Result { + fn traverse_stat(&self, path: &str) -> io::Result { block_on( async { - let component = components.pop().ok_or(Errno::Nosys)?; + let (component, rest) = path.split_once("/").unwrap_or((path, "")); - if !components.is_empty() { + if !rest.is_empty() { let inner = self.inner.read().await; let directory = inner.get(component).ok_or(Errno::Badf)?; - return directory.traverse_stat(components); + return directory.traverse_stat(rest); } let inner = self.inner.read().await; @@ -648,16 +648,16 @@ impl VfsNode for MemDirectory { ) } - fn traverse_mount(&self, components: &mut Vec<&str>, obj: Box) -> io::Result<()> { + fn traverse_mount(&self, path: &str, obj: Box) -> io::Result<()> { block_on( async { - let component = components.pop().ok_or(Errno::Badf)?; + let (component, rest) = path.split_once("/").unwrap_or((path, "")); if let Some(directory) = self.inner.read().await.get(component) { - return directory.traverse_mount(components, obj); + return directory.traverse_mount(rest, obj); } - if !components.is_empty() { + if !rest.is_empty() { return Err(Errno::Badf); } @@ -670,27 +670,27 @@ impl VfsNode for MemDirectory { fn traverse_open( &self, - components: &mut Vec<&str>, + path: &str, opt: OpenOption, mode: AccessPermission, ) -> io::Result>> { - block_on(self.async_traverse_open(components, opt, mode), None) + block_on(self.async_traverse_open(path, opt, mode), None) } fn traverse_create_file( &self, - components: &mut Vec<&str>, + path: &str, data: &'static [u8], mode: AccessPermission, ) -> io::Result<()> { block_on( async { - let component = components.pop().ok_or(Errno::Noent)?; + let (component, rest) = path.split_once("/").unwrap_or((path, "")); - if !components.is_empty() { + if !rest.is_empty() { let inner = self.inner.read().await; let directory = inner.get(component).ok_or(Errno::Noent)?; - return directory.traverse_create_file(components, data, mode); + return directory.traverse_create_file(rest, data, mode); } let file = RomFile::new(data, mode); diff --git a/src/fs/mod.rs b/src/fs/mod.rs index b2a9294d92..eb65cd1e98 100644 --- a/src/fs/mod.rs +++ b/src/fs/mod.rs @@ -66,52 +66,44 @@ pub(crate) trait VfsNode: Send + Sync + fmt::Debug { } /// Creates a new directory node - fn traverse_mkdir( - &self, - _components: &mut Vec<&str>, - _mode: AccessPermission, - ) -> io::Result<()> { + fn traverse_mkdir(&self, _path: &str, _mode: AccessPermission) -> io::Result<()> { Err(Errno::Nosys) } /// Deletes a directory node - fn traverse_rmdir(&self, _components: &mut Vec<&str>) -> io::Result<()> { + fn traverse_rmdir(&self, _path: &str) -> io::Result<()> { Err(Errno::Nosys) } /// Removes the specified file - fn traverse_unlink(&self, _components: &mut Vec<&str>) -> io::Result<()> { + fn traverse_unlink(&self, _path: &str) -> io::Result<()> { Err(Errno::Nosys) } /// Opens a directory - fn traverse_readdir(&self, _components: &mut Vec<&str>) -> io::Result> { + fn traverse_readdir(&self, _path: &str) -> io::Result> { Err(Errno::Nosys) } /// Gets file status - fn traverse_lstat(&self, _components: &mut Vec<&str>) -> io::Result { + fn traverse_lstat(&self, _path: &str) -> io::Result { Err(Errno::Nosys) } /// Gets file status - fn traverse_stat(&self, _components: &mut Vec<&str>) -> io::Result { + fn traverse_stat(&self, _path: &str) -> io::Result { Err(Errno::Nosys) } /// Mounts a file system - fn traverse_mount( - &self, - _components: &mut Vec<&str>, - _obj: Box, - ) -> io::Result<()> { + fn traverse_mount(&self, _path: &str, _obj: Box) -> io::Result<()> { Err(Errno::Nosys) } /// Opens a file fn traverse_open( &self, - _components: &mut Vec<&str>, + _path: &str, _option: OpenOption, _mode: AccessPermission, ) -> io::Result>> { @@ -121,7 +113,7 @@ pub(crate) trait VfsNode: Send + Sync + fmt::Debug { /// Creates a read-only file fn traverse_create_file( &self, - _components: &mut Vec<&str>, + _path: &str, _data: &'static [u8], _mode: AccessPermission, ) -> io::Result<()> { @@ -165,45 +157,37 @@ impl Filesystem { mode: AccessPermission, ) -> io::Result>> { debug!("Open file {path} with {opt:?}"); - let mut components: Vec<&str> = path.split('/').collect(); - components.reverse(); - components.pop(); + let path = path.strip_prefix('/').unwrap_or(path); - self.root.traverse_open(&mut components, opt, mode) + self.root.traverse_open(path, opt, mode) } /// Unlinks a file given by path pub fn unlink(&self, path: &str) -> io::Result<()> { debug!("Unlinking file {path}"); - let mut components: Vec<&str> = path.split('/').collect(); - components.reverse(); - components.pop(); + let path = path.strip_prefix('/').unwrap_or(path); - self.root.traverse_unlink(&mut components) + self.root.traverse_unlink(path) } /// Remove directory given by path pub fn rmdir(&self, path: &str) -> io::Result<()> { debug!("Removing directory {path}"); - let mut components: Vec<&str> = path.split('/').collect(); - components.reverse(); - components.pop(); + let path = path.strip_prefix('/').unwrap_or(path); - self.root.traverse_rmdir(&mut components) + self.root.traverse_rmdir(path) } /// Create directory given by path pub fn mkdir(&self, path: &str, mode: AccessPermission) -> io::Result<()> { debug!("Create directory {path}"); - let mut components: Vec<&str> = path.split('/').collect(); - components.reverse(); - components.pop(); + let path = path.strip_prefix('/').unwrap_or(path); - self.root.traverse_mkdir(&mut components, mode) + self.root.traverse_mkdir(path, mode) } pub fn opendir(&self, path: &str) -> io::Result>> { @@ -215,51 +199,38 @@ impl Filesystem { /// List given directory pub fn readdir(&self, path: &str) -> io::Result> { - if path.trim() == "/" { - let mut components: Vec<&str> = Vec::new(); - self.root.traverse_readdir(&mut components) - } else { - let mut components: Vec<&str> = path.split('/').collect(); + debug!("Readdir {path}"); - components.reverse(); - components.pop(); + let path = path.strip_prefix('/').unwrap_or(path); - self.root.traverse_readdir(&mut components) - } + self.root.traverse_readdir(path) } /// stat pub fn stat(&self, path: &str) -> io::Result { debug!("Getting stats {path}"); - let mut components: Vec<&str> = path.split('/').collect(); - components.reverse(); - components.pop(); + let path = path.strip_prefix('/').unwrap_or(path); - self.root.traverse_stat(&mut components) + self.root.traverse_stat(path) } /// lstat pub fn lstat(&self, path: &str) -> io::Result { debug!("Getting lstats {path}"); - let mut components: Vec<&str> = path.split('/').collect(); - components.reverse(); - components.pop(); + let path = path.strip_prefix('/').unwrap_or(path); - self.root.traverse_lstat(&mut components) + self.root.traverse_lstat(path) } /// Create new backing-fs at mountpoint mntpath pub fn mount(&self, path: &str, obj: Box) -> io::Result<()> { debug!("Mounting {path}"); - let mut components: Vec<&str> = path.split('/').collect(); + let path = path.strip_prefix('/').unwrap_or(path); - components.reverse(); - components.pop(); - - self.root.traverse_mount(&mut components, obj) + self.root.traverse_mount(path, obj) } /// Create read-only file @@ -271,12 +242,9 @@ impl Filesystem { ) -> io::Result<()> { debug!("Create read-only file {path}"); - let mut components: Vec<&str> = path.split('/').collect(); - - components.reverse(); - components.pop(); + let path = path.strip_prefix('/').unwrap_or(path); - self.root.traverse_create_file(&mut components, data, mode) + self.root.traverse_create_file(path, data, mode) } } diff --git a/src/fs/uhyve.rs b/src/fs/uhyve.rs index 1bd47c4ce0..682a5aee62 100644 --- a/src/fs/uhyve.rs +++ b/src/fs/uhyve.rs @@ -3,7 +3,6 @@ use alloc::boxed::Box; use alloc::ffi::CString; use alloc::string::String; use alloc::sync::Arc; -use alloc::vec::Vec; use async_lock::Mutex; use embedded_io::{ErrorType, Read, Write}; @@ -128,27 +127,23 @@ impl Clone for UhyveFileHandle { #[derive(Debug)] pub(crate) struct UhyveDirectory { - prefix: Option, + /// The external path of this directory. + /// + /// Before talking to virtio-fs, the relative path inside this directory is + /// adjoined with this prefix. + prefix: String, } impl UhyveDirectory { - pub const fn new(prefix: Option) -> Self { + pub const fn new(prefix: String) -> Self { UhyveDirectory { prefix } } - fn traversal_path(&self, components: &[&str]) -> CString { - let prefix_deref = self.prefix.as_deref(); - let components_with_prefix = prefix_deref.iter().chain(components.iter().rev()); - // Unlike src/fs/virtio_fs.rs, we skip the first element here so as to not prepend / before /root - let path: String = components_with_prefix - .flat_map(|component| ["/", component]) - .skip(1) - .collect(); - if path.is_empty() { - CString::new("/").unwrap() - } else { - CString::new(path).unwrap() - } + fn traversal_path(&self, path: &str) -> CString { + let prefix = self.prefix.as_str(); + let prefix = prefix.strip_suffix("/").unwrap_or(prefix); + let path = [prefix, path].join("/"); + CString::new(path).unwrap() } } @@ -158,21 +153,21 @@ impl VfsNode for UhyveDirectory { NodeKind::Directory } - fn traverse_stat(&self, _components: &mut Vec<&str>) -> io::Result { + fn traverse_stat(&self, _path: &str) -> io::Result { Err(Errno::Nosys) } - fn traverse_lstat(&self, _components: &mut Vec<&str>) -> io::Result { + fn traverse_lstat(&self, _path: &str) -> io::Result { Err(Errno::Nosys) } fn traverse_open( &self, - components: &mut Vec<&str>, + path: &str, opt: OpenOption, mode: AccessPermission, ) -> io::Result>> { - let path = self.traversal_path(components); + let path = self.traversal_path(path); let mut open_params = OpenParams { name: GuestPhysAddr::new( @@ -195,8 +190,8 @@ impl VfsNode for UhyveDirectory { ))) } - fn traverse_unlink(&self, components: &mut Vec<&str>) -> io::Result<()> { - let path = self.traversal_path(components); + fn traverse_unlink(&self, path: &str) -> io::Result<()> { + let path = self.traversal_path(path); let mut unlink_params = UnlinkParams { name: GuestPhysAddr::new( @@ -215,15 +210,11 @@ impl VfsNode for UhyveDirectory { Ok(()) } - fn traverse_rmdir(&self, _components: &mut Vec<&str>) -> io::Result<()> { + fn traverse_rmdir(&self, _path: &str) -> io::Result<()> { Err(Errno::Nosys) } - fn traverse_mkdir( - &self, - _components: &mut Vec<&str>, - _mode: AccessPermission, - ) -> io::Result<()> { + fn traverse_mkdir(&self, _path: &str, _mode: AccessPermission) -> io::Result<()> { Err(Errno::Nosys) } } @@ -246,7 +237,7 @@ pub(crate) fn init() { .unwrap() .mount( &mount_point, - Box::new(UhyveDirectory::new(Some(mount_point.clone()))), + Box::new(UhyveDirectory::new(mount_point.clone())), ) .expect("Mount failed. Duplicate mount_point?"); return; @@ -256,7 +247,7 @@ pub(crate) fn init() { for mount_point in mount_str.split('\0') { info!("Mounting uhyve filesystem at {mount_point}"); - let obj = Box::new(UhyveDirectory::new(Some(mount_point.to_owned()))); + let obj = Box::new(UhyveDirectory::new(mount_point.to_owned())); let Err(errno) = fs::FILESYSTEM.get().unwrap().mount(mount_point, obj) else { return; }; @@ -266,7 +257,7 @@ pub(crate) fn init() { let (parent_path, _file_name) = mount_point.rsplit_once('/').unwrap(); create_dir_recursive(parent_path, AccessPermission::S_IRWXU).unwrap(); - let obj = Box::new(UhyveDirectory::new(Some(mount_point.to_owned()))); + let obj = Box::new(UhyveDirectory::new(mount_point.to_owned())); fs::FILESYSTEM .get() .unwrap() diff --git a/src/fs/virtio_fs.rs b/src/fs/virtio_fs.rs index d57860d6b5..202955008f 100644 --- a/src/fs/virtio_fs.rs +++ b/src/fs/virtio_fs.rs @@ -964,12 +964,12 @@ impl Clone for VirtioFsFileHandle { } pub struct VirtioFsDirectoryHandle { - name: Option, + name: String, read_position: Mutex, } impl VirtioFsDirectoryHandle { - pub fn new(name: Option) -> Self { + pub fn new(name: String) -> Self { Self { name, read_position: Mutex::new(0), @@ -979,10 +979,11 @@ impl VirtioFsDirectoryHandle { impl ObjectInterface for VirtioFsDirectoryHandle { async fn getdents(&self, buf: &mut [MaybeUninit]) -> io::Result { - let path: CString = if let Some(name) = &self.name { - CString::new("/".to_owned() + name).unwrap() - } else { + let path = if self.name.is_empty() { CString::new("/").unwrap() + } else { + let path = ["/", &self.name].join(""); + CString::new(path).unwrap() }; debug!("virtio-fs opendir: {path:#?}"); @@ -1097,12 +1098,16 @@ impl ObjectInterface for VirtioFsDirectoryHandle { #[derive(Debug)] pub(crate) struct VirtioFsDirectory { - prefix: Option, + /// The external path of this directory. + /// + /// Before talking to virtio-fs, the relative path inside this directory is + /// adjoined with this prefix. + prefix: String, attr: FileAttr, } impl VirtioFsDirectory { - pub fn new(prefix: Option) -> Self { + pub fn new(prefix: String) -> Self { let microseconds = arch::kernel::systemtime::now_micros(); let t = timespec::from_usec(microseconds as i64); @@ -1118,17 +1123,11 @@ impl VirtioFsDirectory { } } - fn traversal_path(&self, components: &[&str]) -> CString { - let prefix_deref = self.prefix.as_deref(); - let components_with_prefix = prefix_deref.iter().chain(components.iter().rev()); - let path: String = components_with_prefix - .flat_map(|component| ["/", component]) - .collect(); - if path.is_empty() { - CString::new("/").unwrap() - } else { - CString::new(path).unwrap() - } + fn traversal_path(&self, path: &str) -> CString { + let prefix = self.prefix.as_str(); + let prefix = prefix.strip_suffix("/").unwrap_or(prefix); + let path = [prefix, path].join("/"); + CString::new(path).unwrap() } } @@ -1148,8 +1147,8 @@ impl VfsNode for VirtioFsDirectory { ))) } - fn traverse_readdir(&self, components: &mut Vec<&str>) -> io::Result> { - let path = self.traversal_path(components); + fn traverse_readdir(&self, path: &str) -> io::Result> { + let path = self.traversal_path(path); debug!("virtio-fs opendir: {path:#?}"); @@ -1228,8 +1227,8 @@ impl VfsNode for VirtioFsDirectory { Ok(entries) } - fn traverse_stat(&self, components: &mut Vec<&str>) -> io::Result { - let path = self.traversal_path(components); + fn traverse_stat(&self, path: &str) -> io::Result { + let path = self.traversal_path(path); debug!("virtio-fs stat: {path:#?}"); @@ -1252,12 +1251,11 @@ impl VfsNode for VirtioFsDirectory { } let path = readlink(entry_out.nodeid)?; - let mut components: Vec<&str> = path.split('/').collect(); - self.traverse_stat(&mut components) + self.traverse_stat(&path) } - fn traverse_lstat(&self, components: &mut Vec<&str>) -> io::Result { - let path = self.traversal_path(components); + fn traverse_lstat(&self, path: &str) -> io::Result { + let path = self.traversal_path(path); debug!("virtio-fs lstat: {path:#?}"); @@ -1271,11 +1269,11 @@ impl VfsNode for VirtioFsDirectory { fn traverse_open( &self, - components: &mut Vec<&str>, + path: &str, opt: OpenOption, mode: AccessPermission, ) -> io::Result>> { - let path = self.traversal_path(components); + let path = self.traversal_path(path); debug!("virtio-fs open: {path:#?}, {opt:?} {mode:?}"); @@ -1300,7 +1298,7 @@ impl VfsNode for VirtioFsDirectory { let mut path = path.into_string().unwrap(); path.remove(0); return Ok(Arc::new(async_lock::RwLock::new( - VirtioFsDirectoryHandle::new(Some(path)).into(), + VirtioFsDirectoryHandle::new(path).into(), ))); } @@ -1347,8 +1345,8 @@ impl VfsNode for VirtioFsDirectory { Ok(Arc::new(async_lock::RwLock::new(file.into()))) } - fn traverse_unlink(&self, components: &mut Vec<&str>) -> io::Result<()> { - let path = self.traversal_path(components); + fn traverse_unlink(&self, path: &str) -> io::Result<()> { + let path = self.traversal_path(path); let (cmd, rsp_payload_len) = ops::Unlink::create(path); let rsp = get_filesystem_driver() @@ -1360,8 +1358,8 @@ impl VfsNode for VirtioFsDirectory { Ok(()) } - fn traverse_rmdir(&self, components: &mut Vec<&str>) -> io::Result<()> { - let path = self.traversal_path(components); + fn traverse_rmdir(&self, path: &str) -> io::Result<()> { + let path = self.traversal_path(path); let (cmd, rsp_payload_len) = ops::Rmdir::create(path); let rsp = get_filesystem_driver() @@ -1373,8 +1371,8 @@ impl VfsNode for VirtioFsDirectory { Ok(()) } - fn traverse_mkdir(&self, components: &mut Vec<&str>, mode: AccessPermission) -> io::Result<()> { - let path = self.traversal_path(components); + fn traverse_mkdir(&self, path: &str, mode: AccessPermission) -> io::Result<()> { + let path = self.traversal_path(path); let (cmd, rsp_payload_len) = ops::Mkdir::create(path, mode.bits()); let rsp = get_filesystem_driver() @@ -1405,14 +1403,17 @@ pub(crate) fn init() { let mount_point = if mount_point.starts_with('/') { mount_point } else { - "/".to_owned() + &mount_point + ["/", &mount_point].join("") }; info!("Mounting virtio-fs at {mount_point}"); fs::FILESYSTEM .get() .unwrap() - .mount(mount_point.as_str(), Box::new(VirtioFsDirectory::new(None))) + .mount( + mount_point.as_str(), + Box::new(VirtioFsDirectory::new("/".to_owned())), + ) .expect("Mount failed. Invalid mount_point?"); return; } @@ -1504,14 +1505,12 @@ pub(crate) fn init() { let attr = FileAttr::from(rsp.headers.op_header.attr); if attr.st_mode.contains(AccessPermission::S_IFDIR) { - info!("virtio-fs mount {entry} to /{entry}"); + let path = ["/", &entry].join(""); + info!("virtio-fs mount {entry} to {path}"); fs::FILESYSTEM .get() .unwrap() - .mount( - &("/".to_owned() + entry.as_str()), - Box::new(VirtioFsDirectory::new(Some(entry))), - ) + .mount(&path, Box::new(VirtioFsDirectory::new(path.clone()))) .expect("Mount failed. Invalid mount_point?"); } else { warn!("virtio-fs don't mount {entry}. It isn't a directory!");