From 220eaf5d2dd79f0271bcf16e8a4c5e8b31bc9af1 Mon Sep 17 00:00:00 2001 From: Chirantan Ekbote Date: Fri, 10 Apr 2020 16:43:36 +0900 Subject: devices: fs: Report "." and ".." entries BUG=b:153677176 TEST=vm.Virtiofs and manually check that the "." and ".." entries appear in a VM when you run `ls -al` Change-Id: I75045fd5bced67ff13045088e6f198fa61cb2d4b Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/crosvm/+/2142847 Auto-Submit: Chirantan Ekbote Reviewed-by: Daniel Verkamp Reviewed-by: Zach Reizner Tested-by: kokoro Commit-Queue: Chirantan Ekbote --- devices/src/virtio/fs/passthrough.rs | 42 ++++++++++++++++++++++-------------- 1 file changed, 26 insertions(+), 16 deletions(-) (limited to 'devices') diff --git a/devices/src/virtio/fs/passthrough.rs b/devices/src/virtio/fs/passthrough.rs index d2034ba..344ddc7 100644 --- a/devices/src/virtio/fs/passthrough.rs +++ b/devices/src/virtio/fs/passthrough.rs @@ -26,8 +26,6 @@ use crate::virtio::fs::filesystem::{ use crate::virtio::fs::fuse; use crate::virtio::fs::multikey::MultikeyBTreeMap; -const CURRENT_DIR_CSTR: &[u8] = b".\0"; -const PARENT_DIR_CSTR: &[u8] = b"..\0"; const EMPTY_CSTR: &[u8] = b"\0"; const ROOT_CSTR: &[u8] = b"/\0"; const PROC_CSTR: &[u8] = b"/proc\0"; @@ -577,18 +575,12 @@ impl PassthroughFs { debug_assert!(namelen <= back.len(), "back is smaller than `namelen`"); let name = &back[..namelen]; - let res = if name.starts_with(CURRENT_DIR_CSTR) || name.starts_with(PARENT_DIR_CSTR) { - // We don't want to report the "." and ".." entries. However, returning `Ok(0)` will - // break the loop so return `Ok` with a non-zero value instead. - Ok(1) - } else { - add_entry(DirEntry { - ino: dirent64.d_ino, - offset: dirent64.d_off as u64, - type_: dirent64.d_ty as u32, - name, - }) - }; + let res = add_entry(DirEntry { + ino: dirent64.d_ino, + offset: dirent64.d_off as u64, + type_: dirent64.d_ty as u32, + name, + }); debug_assert!( rem.len() >= dirent64.d_reclen as usize, @@ -806,7 +798,8 @@ impl FileSystem for PassthroughFs { }), ); - let mut opts = FsOptions::DO_READDIRPLUS | FsOptions::READDIRPLUS_AUTO; + let mut opts = + FsOptions::DO_READDIRPLUS | FsOptions::READDIRPLUS_AUTO | FsOptions::EXPORT_SUPPORT; if self.cfg.writeback && capable.contains(FsOptions::WRITEBACK_CACHE) { opts |= FsOptions::WRITEBACK_CACHE; self.writeback.store(true, Ordering::Relaxed); @@ -940,7 +933,24 @@ impl FileSystem for PassthroughFs { // interior '\0' bytes. We trust the kernel to provide us with properly formatted data // so we'll just skip the checks here. let name = unsafe { CStr::from_bytes_with_nul_unchecked(dir_entry.name) }; - let entry = self.do_lookup(inode, name)?; + let entry = if name.to_bytes() == b"." || name.to_bytes() == b".." { + // Don't do lookups on the current directory or the parent directory. Safe because + // this only contains integer fields and any value is valid. + let mut attr = unsafe { MaybeUninit::::zeroed().assume_init() }; + attr.st_ino = dir_entry.ino; + attr.st_mode = dir_entry.type_; + + // We use 0 for the inode value to indicate a negative entry. + Entry { + inode: 0, + generation: 0, + attr, + attr_timeout: Duration::from_secs(0), + entry_timeout: Duration::from_secs(0), + } + } else { + self.do_lookup(inode, name)? + }; add_entry(dir_entry, entry) }) -- cgit 1.4.1