summary refs log tree commit diff
path: root/devices
diff options
context:
space:
mode:
authorChirantan Ekbote <chirantan@chromium.org>2020-04-10 16:43:36 +0900
committerCommit Bot <commit-bot@chromium.org>2020-04-14 14:12:50 +0000
commit220eaf5d2dd79f0271bcf16e8a4c5e8b31bc9af1 (patch)
tree9ef6edf6b1b1dd35feea6a2fc80fca457d373412 /devices
parented22f6b611e2623f5836ccf1288adf6b46146088 (diff)
downloadcrosvm-220eaf5d2dd79f0271bcf16e8a4c5e8b31bc9af1.tar
crosvm-220eaf5d2dd79f0271bcf16e8a4c5e8b31bc9af1.tar.gz
crosvm-220eaf5d2dd79f0271bcf16e8a4c5e8b31bc9af1.tar.bz2
crosvm-220eaf5d2dd79f0271bcf16e8a4c5e8b31bc9af1.tar.lz
crosvm-220eaf5d2dd79f0271bcf16e8a4c5e8b31bc9af1.tar.xz
crosvm-220eaf5d2dd79f0271bcf16e8a4c5e8b31bc9af1.tar.zst
crosvm-220eaf5d2dd79f0271bcf16e8a4c5e8b31bc9af1.zip
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 <chirantan@chromium.org>
Reviewed-by: Daniel Verkamp <dverkamp@chromium.org>
Reviewed-by: Zach Reizner <zachr@chromium.org>
Tested-by: kokoro <noreply+kokoro@google.com>
Commit-Queue: Chirantan Ekbote <chirantan@chromium.org>
Diffstat (limited to 'devices')
-rw-r--r--devices/src/virtio/fs/passthrough.rs42
1 files changed, 26 insertions, 16 deletions
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::<libc::stat64>::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)
         })