diff --git a/microdroid/Android.bp b/microdroid/Android.bp
index f2030d1..55075ca 100644
--- a/microdroid/Android.bp
+++ b/microdroid/Android.bp
@@ -59,6 +59,9 @@
         "libadbd_auth",
         "libadbd_fs",
 
+        // "com.android.art" requires
+        "heapprofd_client_api",
+
         "apexd",
         "debuggerd",
         "linker",
diff --git a/microdroid/README.md b/microdroid/README.md
index e1af9be..4edd65b 100644
--- a/microdroid/README.md
+++ b/microdroid/README.md
@@ -51,9 +51,9 @@
 ```
 
 Copy the artifacts to the temp directory, create the composite image using
-`mk_cdisk`, copy the VM config file, and run it via `vm`. For now, some other
-files have to be manually created. In the future, you won't need these, and this
-shall be done via [`virtmanager`](../virtmanager/).
+`mk_cdisk` and copy the VM config file. For now, some other files have to be
+manually created. In the future, you won't need these, and this shall be done
+via [`virtmanager`](../virtmanager/).
 
 ```sh
 $ adb root
@@ -71,6 +71,16 @@
 $ adb shell 'cd /data/local/tmp/microdroid; /apex/com.android.virt/bin/mk_payload /apex/com.android.virt/etc/microdroid_payload.json payload.img'
 $ adb shell 'chmod go+r /data/local/tmp/microdroid/*-header.img /data/local/tmp/microdroid/*-footer.img'
 $ adb push microdroid.json /data/local/tmp/microdroid/microdroid.json
+```
+
+Ensure SELinux is in permissive mode to allow virtmanager and crosvm to open
+files from `/data/local/tmp`. Opening files from this directory is
+neverallow-ed and file descriptors should be passed instead but, before that is
+supported, `adb shell setenforce 0` will put the device in permissive mode.
+
+Now, run the VM and look for `adbd` starting in the logs.
+
+```sh
 $ adb shell "start virtmanager"
 $ adb shell "RUST_BACKTRACE=1 RUST_LOG=trace /apex/com.android.virt/bin/vm run /data/local/tmp/microdroid/microdroid.json"
 ```
diff --git a/zipfuse/.cargo/config.toml b/zipfuse/.cargo/config.toml
new file mode 100644
index 0000000..b87b13a
--- /dev/null
+++ b/zipfuse/.cargo/config.toml
@@ -0,0 +1,4 @@
+# Mounting requires root privilege. The fuse library in crosvm doesn't support
+# fusermount yet.
+[target.x86_64-unknown-linux-gnu]
+runner = 'unshare -mUr'
diff --git a/zipfuse/Android.bp b/zipfuse/Android.bp
new file mode 100644
index 0000000..ec409f9
--- /dev/null
+++ b/zipfuse/Android.bp
@@ -0,0 +1,41 @@
+package {
+    default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
+rust_defaults {
+    name: "zipfuse.defaults",
+    crate_name: "zipfuse",
+    srcs: ["src/main.rs"],
+    edition: "2018",
+    prefer_rlib: true,
+    rustlibs: [
+        "libanyhow",
+        "libclap",
+        "libfuse_rust",
+        "liblibc",
+        "libzip",
+    ],
+    // libfuse_rust, etc don't support 32-bit targets
+    multilib: {
+        lib32: {
+            enabled: false,
+        },
+    },
+}
+
+rust_binary {
+    name: "zipfuse",
+    defaults: ["zipfuse.defaults"],
+}
+
+rust_test {
+    name: "ZipFuseTest",
+    stem: "zipfuse.test",
+    defaults: ["zipfuse.defaults"],
+    compile_multilib: "first",
+    rustlibs: [
+        "libnix",
+        "libtempfile",
+    ],
+    data: [":zipfuse"],
+}
diff --git a/zipfuse/AndroidTest.xml b/zipfuse/AndroidTest.xml
new file mode 100644
index 0000000..3eee236
--- /dev/null
+++ b/zipfuse/AndroidTest.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2021 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<configuration description="Config for zipfuse tests">
+    <!-- mounting a fuse filesystem requires root privilege -->
+    <target_preparer class="com.android.tradefed.targetprep.RootTargetPreparer"/>
+
+    <target_preparer class="com.android.tradefed.targetprep.PushFilePreparer">
+        <option name="cleanup" value="true" />
+        <option name="push-file" key="zipfuse.test" value="/data/local/tmp/zipfuse.test" />
+        <option name="push-file" key="zipfuse" value="/data/local/tmp/zipfuse" />
+    </target_preparer>
+
+    <test class="com.android.tradefed.testtype.rust.RustBinaryTest" >
+        <option name="test-device-path" value="/data/local/tmp" />
+        <option name="module-name" value="zipfuse.test" />
+    </test>
+</configuration>
diff --git a/zipfuse/Cargo.toml b/zipfuse/Cargo.toml
new file mode 100644
index 0000000..220d352
--- /dev/null
+++ b/zipfuse/Cargo.toml
@@ -0,0 +1,14 @@
+[package]
+name = "zipfuse"
+version = "0.1.0"
+authors = ["Jiyong Park <jiyong@google.com>"]
+edition = "2018"
+
+[dependencies]
+fuse = { path = "../../../../external/crosvm/fuse" }
+clap = "2.33"
+anyhow = "1.0"
+libc = "0.2"
+zip = "0.5"
+tempfile = "3.2"
+nix = "0.20"
diff --git a/zipfuse/src/inode.rs b/zipfuse/src/inode.rs
new file mode 100644
index 0000000..e6c0254
--- /dev/null
+++ b/zipfuse/src/inode.rs
@@ -0,0 +1,421 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+use anyhow::{anyhow, bail, Result};
+use std::collections::HashMap;
+use std::ffi::{CStr, CString};
+use std::io;
+use std::os::unix::ffi::OsStrExt;
+
+/// `InodeTable` is a table of `InodeData` indexed by `Inode`.
+#[derive(Debug)]
+pub struct InodeTable {
+    table: Vec<InodeData>,
+}
+
+/// `Inode` is the handle (or index in the table) to `InodeData` which represents an inode.
+pub type Inode = u64;
+
+const INVALID: Inode = 0;
+const ROOT: Inode = 1;
+
+/// `InodeData` represents an inode which has metadata about a file or a directory
+#[derive(Debug)]
+pub struct InodeData {
+    /// Size of the file that this inode represents. In case when the file is a directory, this
+    // is zero.
+    pub size: u64,
+    /// unix mode of this inode. It may not have `S_IFDIR` and `S_IFREG` in case the original zip
+    /// doesn't have the information in the external_attributes fields. To test if this inode
+    /// is for a regular file or a directory, use `is_dir`.
+    pub mode: u32,
+    data: InodeDataData,
+}
+
+type ZipIndex = usize;
+
+/// `InodeDataData` is the actual data (or a means to access the data) of the file or the directory
+/// that an inode is representing. In case of a directory, this data is the hash table of the
+/// directory entries. In case of a file, this data is the index of the file in `ZipArchive` which
+/// can be used to retrieve `ZipFile` that provides access to the content of the file.
+#[derive(Debug)]
+enum InodeDataData {
+    Directory(HashMap<CString, DirectoryEntry>),
+    File(ZipIndex),
+}
+
+#[derive(Debug, Clone)]
+pub struct DirectoryEntry {
+    pub inode: Inode,
+    pub kind: InodeKind,
+}
+
+#[derive(Debug, Clone, PartialEq, Copy)]
+pub enum InodeKind {
+    Directory,
+    File,
+}
+
+impl InodeData {
+    pub fn is_dir(&self) -> bool {
+        matches!(&self.data, InodeDataData::Directory(_))
+    }
+
+    pub fn get_directory(&self) -> Option<&HashMap<CString, DirectoryEntry>> {
+        match &self.data {
+            InodeDataData::Directory(hash) => Some(hash),
+            _ => None,
+        }
+    }
+
+    pub fn get_zip_index(&self) -> Option<ZipIndex> {
+        match &self.data {
+            InodeDataData::File(zip_index) => Some(*zip_index),
+            _ => None,
+        }
+    }
+
+    // Below methods are used to construct the inode table when initializing the filesystem. Once
+    // the initialization is done, these are not used because this is a read-only filesystem.
+
+    fn new_dir(mode: u32) -> InodeData {
+        InodeData { mode, size: 0, data: InodeDataData::Directory(HashMap::new()) }
+    }
+
+    fn new_file(zip_index: ZipIndex, zip_file: &zip::read::ZipFile) -> InodeData {
+        InodeData {
+            mode: zip_file.unix_mode().unwrap_or(0),
+            size: zip_file.size(),
+            data: InodeDataData::File(zip_index),
+        }
+    }
+
+    fn add_to_directory(&mut self, name: CString, entry: DirectoryEntry) {
+        match &mut self.data {
+            InodeDataData::Directory(hashtable) => {
+                let existing = hashtable.insert(name, entry);
+                assert!(existing.is_none());
+            }
+            _ => {
+                panic!("can't add a directory entry to a file inode");
+            }
+        }
+    }
+}
+
+impl InodeTable {
+    /// Gets `InodeData` at a specific index.
+    pub fn get(&self, inode: Inode) -> Option<&InodeData> {
+        match inode {
+            INVALID => None,
+            _ => self.table.get(inode as usize),
+        }
+    }
+
+    fn get_mut(&mut self, inode: Inode) -> Option<&mut InodeData> {
+        match inode {
+            INVALID => None,
+            _ => self.table.get_mut(inode as usize),
+        }
+    }
+
+    fn put(&mut self, data: InodeData) -> Inode {
+        let inode = self.table.len() as Inode;
+        self.table.push(data);
+        inode
+    }
+
+    /// Finds the inode number of a file named `name` in the `parent` inode. The `parent` inode
+    /// must exist and be a directory.
+    fn find(&self, parent: Inode, name: &CStr) -> Option<Inode> {
+        let data = self.get(parent).unwrap();
+        match data.get_directory().unwrap().get(name) {
+            Some(DirectoryEntry { inode, .. }) => Some(*inode),
+            _ => None,
+        }
+    }
+
+    // Adds the inode `data` to the inode table and also links it to the `parent` inode as a file
+    // named `name`. The `parent` inode must exist and be a directory.
+    fn add(&mut self, parent: Inode, name: CString, data: InodeData) -> Inode {
+        assert!(self.find(parent, &name).is_none());
+
+        let kind = if data.is_dir() { InodeKind::Directory } else { InodeKind::File };
+        // Add the inode to the table
+        let inode = self.put(data);
+
+        // ... and then register it to the directory of the parent inode
+        self.get_mut(parent).unwrap().add_to_directory(name, DirectoryEntry { inode, kind });
+        inode
+    }
+
+    /// Constructs `InodeTable` from a zip archive `archive`.
+    pub fn from_zip<R: io::Read + io::Seek>(
+        archive: &mut zip::ZipArchive<R>,
+    ) -> Result<InodeTable> {
+        let mut table = InodeTable { table: Vec::new() };
+
+        // Add the inodes for the invalid and the root directory
+        assert_eq!(INVALID, table.put(InodeData::new_dir(0)));
+        assert_eq!(ROOT, table.put(InodeData::new_dir(0)));
+
+        // For each zip file in the archive, create an inode and add it to the table. If the file's
+        // parent directories don't have corresponding inodes in the table, handle them too.
+        for i in 0..archive.len() {
+            let file = archive.by_index(i)?;
+            let path = file
+                .enclosed_name()
+                .ok_or_else(|| anyhow!("{} is an invalid name", file.name()))?;
+            // TODO(jiyong): normalize this (e.g. a/b/c/../d -> a/b/d). We can't use
+            // fs::canonicalize as this is a non-existing path yet.
+
+            let mut parent = ROOT;
+            let mut iter = path.iter().peekable();
+            while let Some(name) = iter.next() {
+                // TODO(jiyong): remove this check by canonicalizing `path`
+                if name == ".." {
+                    bail!(".. is not allowed");
+                }
+
+                let is_leaf = iter.peek().is_none();
+                let is_file = file.is_file() && is_leaf;
+
+                // The happy path; the inode for `name` is already in the `parent` inode. Move on
+                // to the next path element.
+                let name = CString::new(name.as_bytes()).unwrap();
+                if let Some(found) = table.find(parent, &name) {
+                    parent = found;
+                    // Update the mode if this is a directory leaf.
+                    if !is_file && is_leaf {
+                        let mut inode = table.get_mut(parent).unwrap();
+                        inode.mode = file.unix_mode().unwrap_or(0);
+                    }
+                    continue;
+                }
+
+                const DEFAULT_DIR_MODE: u32 = libc::S_IRUSR | libc::S_IXUSR;
+
+                // No inode found. Create a new inode and add it to the inode table.
+                let inode = if is_file {
+                    InodeData::new_file(i, &file)
+                } else if is_leaf {
+                    InodeData::new_dir(file.unix_mode().unwrap_or(DEFAULT_DIR_MODE))
+                } else {
+                    InodeData::new_dir(DEFAULT_DIR_MODE)
+                };
+                let new = table.add(parent, name, inode);
+                parent = new;
+            }
+        }
+        Ok(table)
+    }
+}
+
+#[cfg(test)]
+mod tests {
+    use crate::inode::*;
+    use std::io::{Cursor, Write};
+    use zip::write::FileOptions;
+
+    // Creates an in-memory zip buffer, adds some files to it, and converts it to InodeTable
+    fn setup(add: fn(&mut zip::ZipWriter<&mut std::io::Cursor<Vec<u8>>>)) -> InodeTable {
+        let mut buf: Cursor<Vec<u8>> = Cursor::new(Vec::new());
+        let mut writer = zip::ZipWriter::new(&mut buf);
+        add(&mut writer);
+        assert!(writer.finish().is_ok());
+        drop(writer);
+
+        let zip = zip::ZipArchive::new(buf);
+        assert!(zip.is_ok());
+        let it = InodeTable::from_zip(&mut zip.unwrap());
+        assert!(it.is_ok());
+        it.unwrap()
+    }
+
+    fn check_dir(it: &InodeTable, parent: Inode, name: &str) -> Inode {
+        let name = CString::new(name.as_bytes()).unwrap();
+        let inode = it.find(parent, &name);
+        assert!(inode.is_some());
+        let inode = inode.unwrap();
+        let inode_data = it.get(inode);
+        assert!(inode_data.is_some());
+        let inode_data = inode_data.unwrap();
+        assert_eq!(0, inode_data.size);
+        assert!(inode_data.is_dir());
+        inode
+    }
+
+    fn check_file<'a>(it: &'a InodeTable, parent: Inode, name: &str) -> &'a InodeData {
+        let name = CString::new(name.as_bytes()).unwrap();
+        let inode = it.find(parent, &name);
+        assert!(inode.is_some());
+        let inode = inode.unwrap();
+        let inode_data = it.get(inode);
+        assert!(inode_data.is_some());
+        let inode_data = inode_data.unwrap();
+        assert!(!inode_data.is_dir());
+        inode_data
+    }
+
+    #[test]
+    fn empty_zip_has_two_inodes() {
+        let it = setup(|_| {});
+        assert_eq!(2, it.table.len());
+        assert!(it.get(INVALID).is_none());
+        assert!(it.get(ROOT).is_some());
+    }
+
+    #[test]
+    fn one_file() {
+        let it = setup(|zip| {
+            zip.start_file("foo", FileOptions::default()).unwrap();
+            zip.write_all(b"0123456789").unwrap();
+        });
+        let inode_data = check_file(&it, ROOT, "foo");
+        assert_eq!(b"0123456789".len() as u64, inode_data.size);
+    }
+
+    #[test]
+    fn one_dir() {
+        let it = setup(|zip| {
+            zip.add_directory("foo", FileOptions::default()).unwrap();
+        });
+        let inode = check_dir(&it, ROOT, "foo");
+        // The directory doesn't have any entries
+        assert_eq!(0, it.get(inode).unwrap().get_directory().unwrap().len());
+    }
+
+    #[test]
+    fn one_file_in_subdirs() {
+        let it = setup(|zip| {
+            zip.start_file("a/b/c/d", FileOptions::default()).unwrap();
+            zip.write_all(b"0123456789").unwrap();
+        });
+
+        assert_eq!(6, it.table.len());
+        let a = check_dir(&it, ROOT, "a");
+        let b = check_dir(&it, a, "b");
+        let c = check_dir(&it, b, "c");
+        let d = check_file(&it, c, "d");
+        assert_eq!(10, d.size);
+    }
+
+    #[test]
+    fn complex_hierarchy() {
+        // root/
+        //   a/
+        //    b1/
+        //    b2/
+        //      c1 (file)
+        //      c2/
+        //          d1 (file)
+        //          d2 (file)
+        //          d3 (file)
+        //  x/
+        //    y1 (file)
+        //    y2 (file)
+        //    y3/
+        //
+        //  foo (file)
+        //  bar (file)
+        let it = setup(|zip| {
+            let opt = FileOptions::default();
+            zip.add_directory("a/b1", opt).unwrap();
+
+            zip.start_file("a/b2/c1", opt).unwrap();
+
+            zip.start_file("a/b2/c2/d1", opt).unwrap();
+            zip.start_file("a/b2/c2/d2", opt).unwrap();
+            zip.start_file("a/b2/c2/d3", opt).unwrap();
+
+            zip.start_file("x/y1", opt).unwrap();
+            zip.start_file("x/y2", opt).unwrap();
+            zip.add_directory("x/y3", opt).unwrap();
+
+            zip.start_file("foo", opt).unwrap();
+            zip.start_file("bar", opt).unwrap();
+        });
+
+        assert_eq!(16, it.table.len()); // 8 files, 6 dirs, and 2 (for root and the invalid inode)
+        let a = check_dir(&it, ROOT, "a");
+        let _b1 = check_dir(&it, a, "b1");
+        let b2 = check_dir(&it, a, "b2");
+        let _c1 = check_file(&it, b2, "c1");
+
+        let c2 = check_dir(&it, b2, "c2");
+        let _d1 = check_file(&it, c2, "d1");
+        let _d2 = check_file(&it, c2, "d3");
+        let _d3 = check_file(&it, c2, "d3");
+
+        let x = check_dir(&it, ROOT, "x");
+        let _y1 = check_file(&it, x, "y1");
+        let _y2 = check_file(&it, x, "y2");
+        let _y3 = check_dir(&it, x, "y3");
+
+        let _foo = check_file(&it, ROOT, "foo");
+        let _bar = check_file(&it, ROOT, "bar");
+    }
+
+    #[test]
+    fn file_size() {
+        let it = setup(|zip| {
+            let opt = FileOptions::default();
+            zip.start_file("empty", opt).unwrap();
+
+            zip.start_file("10bytes", opt).unwrap();
+            zip.write_all(&[0; 10]).unwrap();
+
+            zip.start_file("1234bytes", opt).unwrap();
+            zip.write_all(&[0; 1234]).unwrap();
+
+            zip.start_file("2^20bytes", opt).unwrap();
+            zip.write_all(&[0; 2 << 20]).unwrap();
+        });
+
+        let f = check_file(&it, ROOT, "empty");
+        assert_eq!(0, f.size);
+
+        let f = check_file(&it, ROOT, "10bytes");
+        assert_eq!(10, f.size);
+
+        let f = check_file(&it, ROOT, "1234bytes");
+        assert_eq!(1234, f.size);
+
+        let f = check_file(&it, ROOT, "2^20bytes");
+        assert_eq!(2 << 20, f.size);
+    }
+
+    #[test]
+    fn rejects_invalid_paths() {
+        let invalid_paths = [
+            "a/../../b",   // escapes the root
+            "a/..",        // escapes the root
+            "a/../../b/c", // escape the root
+            "a/b/../c",    // doesn't escape the root, but not normalized
+        ];
+        for path in invalid_paths.iter() {
+            let mut buf: Cursor<Vec<u8>> = Cursor::new(Vec::new());
+            let mut writer = zip::ZipWriter::new(&mut buf);
+            writer.start_file(*path, FileOptions::default()).unwrap();
+            assert!(writer.finish().is_ok());
+            drop(writer);
+
+            let zip = zip::ZipArchive::new(buf);
+            assert!(zip.is_ok());
+            let it = InodeTable::from_zip(&mut zip.unwrap());
+            assert!(it.is_err());
+        }
+    }
+}
diff --git a/zipfuse/src/main.rs b/zipfuse/src/main.rs
new file mode 100644
index 0000000..d0792d5
--- /dev/null
+++ b/zipfuse/src/main.rs
@@ -0,0 +1,597 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+//! `zipfuse` is a FUSE filesystem for zip archives. It provides transparent access to the files
+//! in a zip archive. This filesystem does not supporting writing files back to the zip archive.
+//! The filesystem has to be mounted read only.
+
+mod inode;
+
+use anyhow::Result;
+use clap::{App, Arg};
+use fuse::filesystem::*;
+use fuse::mount::*;
+use std::collections::HashMap;
+use std::convert::TryFrom;
+use std::ffi::{CStr, CString};
+use std::fs::{File, OpenOptions};
+use std::io;
+use std::io::Read;
+use std::os::unix::io::AsRawFd;
+use std::path::Path;
+use std::sync::Mutex;
+
+use crate::inode::{DirectoryEntry, Inode, InodeData, InodeKind, InodeTable};
+
+fn main() -> Result<()> {
+    let matches = App::new("zipfuse")
+        .arg(Arg::with_name("ZIPFILE").required(true))
+        .arg(Arg::with_name("MOUNTPOINT").required(true))
+        .get_matches();
+
+    let zip_file = matches.value_of("ZIPFILE").unwrap().as_ref();
+    let mount_point = matches.value_of("MOUNTPOINT").unwrap().as_ref();
+    run_fuse(zip_file, mount_point)?;
+    Ok(())
+}
+
+/// Runs a fuse filesystem by mounting `zip_file` on `mount_point`.
+pub fn run_fuse(zip_file: &Path, mount_point: &Path) -> Result<()> {
+    const MAX_READ: u32 = 1 << 20; // TODO(jiyong): tune this
+    const MAX_WRITE: u32 = 1 << 13; // This is a read-only filesystem
+
+    let dev_fuse = OpenOptions::new().read(true).write(true).open("/dev/fuse")?;
+
+    fuse::mount(
+        mount_point,
+        "zipfuse",
+        libc::MS_NOSUID | libc::MS_NODEV | libc::MS_RDONLY,
+        &[
+            MountOption::FD(dev_fuse.as_raw_fd()),
+            MountOption::RootMode(libc::S_IFDIR | libc::S_IXUSR | libc::S_IXGRP | libc::S_IXOTH),
+            MountOption::AllowOther,
+            MountOption::UserId(0),
+            MountOption::GroupId(0),
+            MountOption::MaxRead(MAX_READ),
+        ],
+    )?;
+    Ok(fuse::worker::start_message_loop(dev_fuse, MAX_READ, MAX_WRITE, ZipFuse::new(zip_file)?)?)
+}
+
+struct ZipFuse {
+    zip_archive: Mutex<zip::ZipArchive<File>>,
+    inode_table: InodeTable,
+    open_files: Mutex<HashMap<Handle, OpenFileBuf>>,
+    open_dirs: Mutex<HashMap<Handle, OpenDirBuf>>,
+}
+
+/// Holds the (decompressed) contents of a [`ZipFile`].
+///
+/// This buf is needed because `ZipFile` is in general not seekable due to the compression.
+///
+/// TODO(jiyong): do this only for compressed `ZipFile`s. Uncompressed (store) files don't need
+/// this; they can be directly read from `zip_archive`.
+struct OpenFileBuf {
+    open_count: u32, // multiple opens share the buf because this is a read-only filesystem
+    buf: Box<[u8]>,
+}
+
+/// Holds the directory entries in a directory opened by [`opendir`].
+struct OpenDirBuf {
+    open_count: u32,
+    buf: Box<[(CString, DirectoryEntry)]>,
+}
+
+type Handle = u64;
+
+fn ebadf() -> io::Error {
+    io::Error::from_raw_os_error(libc::EBADF)
+}
+
+fn timeout_max() -> std::time::Duration {
+    std::time::Duration::new(u64::MAX, 1_000_000_000 - 1)
+}
+
+impl ZipFuse {
+    fn new(zip_file: &Path) -> Result<ZipFuse> {
+        // TODO(jiyong): Use O_DIRECT to avoid double caching.
+        // `.custom_flags(nix::fcntl::OFlag::O_DIRECT.bits())` currently doesn't work.
+        let f = OpenOptions::new().read(true).open(zip_file)?;
+        let mut z = zip::ZipArchive::new(f)?;
+        let it = InodeTable::from_zip(&mut z)?;
+        Ok(ZipFuse {
+            zip_archive: Mutex::new(z),
+            inode_table: it,
+            open_files: Mutex::new(HashMap::new()),
+            open_dirs: Mutex::new(HashMap::new()),
+        })
+    }
+
+    fn find_inode(&self, inode: Inode) -> io::Result<&InodeData> {
+        self.inode_table.get(inode).ok_or_else(ebadf)
+    }
+
+    fn stat_from(&self, inode: Inode) -> io::Result<libc::stat64> {
+        let inode_data = self.find_inode(inode)?;
+        let mut st = unsafe { std::mem::MaybeUninit::<libc::stat64>::zeroed().assume_init() };
+        st.st_dev = 0;
+        st.st_nlink = if inode_data.is_dir() {
+            // 2 is for . and ..
+            // unwrap is safe because of the `is_dir` check.
+            2 + inode_data.get_directory().unwrap().len() as libc::nlink_t
+        } else {
+            1
+        };
+        st.st_ino = inode;
+        st.st_mode = if inode_data.is_dir() { libc::S_IFDIR } else { libc::S_IFREG };
+        st.st_mode |= inode_data.mode;
+        st.st_uid = 0;
+        st.st_gid = 0;
+        st.st_size = i64::try_from(inode_data.size).unwrap_or(i64::MAX);
+        Ok(st)
+    }
+}
+
+impl fuse::filesystem::FileSystem for ZipFuse {
+    type Inode = Inode;
+    type Handle = Handle;
+    type DirIter = DirIter;
+
+    fn init(&self, _capable: FsOptions) -> std::io::Result<FsOptions> {
+        // The default options added by the fuse crate are fine. We don't have additional options.
+        Ok(FsOptions::empty())
+    }
+
+    fn lookup(&self, _ctx: Context, parent: Self::Inode, name: &CStr) -> io::Result<Entry> {
+        let inode = self.find_inode(parent)?;
+        let directory = inode.get_directory().ok_or_else(ebadf)?;
+        let entry = directory.get(name);
+        match entry {
+            Some(e) => Ok(Entry {
+                inode: e.inode,
+                generation: 0,
+                attr: self.stat_from(e.inode)?,
+                attr_timeout: timeout_max(), // this is a read-only fs
+                entry_timeout: timeout_max(),
+            }),
+            _ => Err(io::Error::from_raw_os_error(libc::ENOENT)),
+        }
+    }
+
+    fn getattr(
+        &self,
+        _ctx: Context,
+        inode: Self::Inode,
+        _handle: Option<Self::Handle>,
+    ) -> io::Result<(libc::stat64, std::time::Duration)> {
+        let st = self.stat_from(inode)?;
+        Ok((st, timeout_max()))
+    }
+
+    fn open(
+        &self,
+        _ctx: Context,
+        inode: Self::Inode,
+        _flags: u32,
+    ) -> io::Result<(Option<Self::Handle>, fuse::filesystem::OpenOptions)> {
+        let mut open_files = self.open_files.lock().unwrap();
+        let handle = inode as Handle;
+
+        // If the file is already opened, just increase the reference counter. If not, read the
+        // entire file content to the buffer. When `read` is called, a portion of the buffer is
+        // copied to the kernel.
+        // TODO(jiyong): do this only for compressed zip files. Files that are not compressed
+        // (store) can be directly read from zip_archive. That will help reduce the memory usage.
+        if let Some(ofb) = open_files.get_mut(&handle) {
+            if ofb.open_count == 0 {
+                return Err(ebadf());
+            }
+            ofb.open_count += 1;
+        } else {
+            let inode_data = self.find_inode(inode)?;
+            let zip_index = inode_data.get_zip_index().ok_or_else(ebadf)?;
+            let mut zip_archive = self.zip_archive.lock().unwrap();
+            let mut zip_file = zip_archive.by_index(zip_index)?;
+            let mut buf = Vec::with_capacity(inode_data.size as usize);
+            zip_file.read_to_end(&mut buf)?;
+            open_files.insert(handle, OpenFileBuf { open_count: 1, buf: buf.into_boxed_slice() });
+        }
+        // Note: we don't return `DIRECT_IO` here, because then applications wouldn't be able to
+        // mmap the files.
+        Ok((Some(handle), fuse::filesystem::OpenOptions::empty()))
+    }
+
+    fn release(
+        &self,
+        _ctx: Context,
+        inode: Self::Inode,
+        _flags: u32,
+        _handle: Self::Handle,
+        _flush: bool,
+        _flock_release: bool,
+        _lock_owner: Option<u64>,
+    ) -> io::Result<()> {
+        // Releases the buffer for the `handle` when it is opened for nobody. While this is good
+        // for saving memory, this has a performance implication because we need to decompress
+        // again when the same file is opened in the future.
+        let mut open_files = self.open_files.lock().unwrap();
+        let handle = inode as Handle;
+        if let Some(ofb) = open_files.get_mut(&handle) {
+            if ofb.open_count.checked_sub(1).ok_or_else(ebadf)? == 0 {
+                open_files.remove(&handle);
+            }
+            Ok(())
+        } else {
+            Err(ebadf())
+        }
+    }
+
+    fn read<W: io::Write + ZeroCopyWriter>(
+        &self,
+        _ctx: Context,
+        _inode: Self::Inode,
+        handle: Self::Handle,
+        mut w: W,
+        size: u32,
+        offset: u64,
+        _lock_owner: Option<u64>,
+        _flags: u32,
+    ) -> io::Result<usize> {
+        let open_files = self.open_files.lock().unwrap();
+        let ofb = open_files.get(&handle).ok_or_else(ebadf)?;
+        if ofb.open_count == 0 {
+            return Err(ebadf());
+        }
+        let start = offset as usize;
+        let end = start + size as usize;
+        let end = std::cmp::min(end, ofb.buf.len());
+        let read_len = w.write(&ofb.buf[start..end])?;
+        Ok(read_len)
+    }
+
+    fn opendir(
+        &self,
+        _ctx: Context,
+        inode: Self::Inode,
+        _flags: u32,
+    ) -> io::Result<(Option<Self::Handle>, fuse::filesystem::OpenOptions)> {
+        let mut open_dirs = self.open_dirs.lock().unwrap();
+        let handle = inode as Handle;
+        if let Some(odb) = open_dirs.get_mut(&handle) {
+            if odb.open_count == 0 {
+                return Err(ebadf());
+            }
+            odb.open_count += 1;
+        } else {
+            let inode_data = self.find_inode(inode)?;
+            let directory = inode_data.get_directory().ok_or_else(ebadf)?;
+            let mut buf: Vec<(CString, DirectoryEntry)> = Vec::with_capacity(directory.len());
+            for (name, dir_entry) in directory.iter() {
+                let name = CString::new(name.as_bytes()).unwrap();
+                buf.push((name, dir_entry.clone()));
+            }
+            open_dirs.insert(handle, OpenDirBuf { open_count: 1, buf: buf.into_boxed_slice() });
+        }
+        Ok((Some(handle), fuse::filesystem::OpenOptions::empty()))
+    }
+
+    fn releasedir(
+        &self,
+        _ctx: Context,
+        inode: Self::Inode,
+        _flags: u32,
+        _handle: Self::Handle,
+    ) -> io::Result<()> {
+        let mut open_dirs = self.open_dirs.lock().unwrap();
+        let handle = inode as Handle;
+        if let Some(odb) = open_dirs.get_mut(&handle) {
+            if odb.open_count.checked_sub(1).ok_or_else(ebadf)? == 0 {
+                open_dirs.remove(&handle);
+            }
+            Ok(())
+        } else {
+            Err(ebadf())
+        }
+    }
+
+    fn readdir(
+        &self,
+        _ctx: Context,
+        inode: Self::Inode,
+        _handle: Self::Handle,
+        size: u32,
+        offset: u64,
+    ) -> io::Result<Self::DirIter> {
+        let open_dirs = self.open_dirs.lock().unwrap();
+        let handle = inode as Handle;
+        let odb = open_dirs.get(&handle).ok_or_else(ebadf)?;
+        if odb.open_count == 0 {
+            return Err(ebadf());
+        }
+        let buf = &odb.buf;
+        let start = offset as usize;
+        let end = start + size as usize;
+        let end = std::cmp::min(end, buf.len());
+        let mut new_buf = Vec::with_capacity(end - start);
+        // The portion of `buf` is *copied* to the iterator. This is not ideal, but inevitable
+        // because the `name` field in `fuse::filesystem::DirEntry` is `&CStr` not `CString`.
+        new_buf.extend_from_slice(&buf[start..end]);
+        Ok(DirIter { inner: new_buf, offset, cur: 0 })
+    }
+}
+
+struct DirIter {
+    inner: Vec<(CString, DirectoryEntry)>,
+    offset: u64, // the offset where this iterator begins. `next` doesn't change this.
+    cur: usize,  // the current index in `inner`. `next` advances this.
+}
+
+impl fuse::filesystem::DirectoryIterator for DirIter {
+    fn next(&mut self) -> Option<fuse::filesystem::DirEntry> {
+        if self.cur >= self.inner.len() {
+            return None;
+        }
+
+        let (name, entry) = &self.inner[self.cur];
+        self.cur += 1;
+        Some(fuse::filesystem::DirEntry {
+            ino: entry.inode as libc::ino64_t,
+            offset: self.offset + self.cur as u64,
+            type_: match entry.kind {
+                InodeKind::Directory => libc::DT_DIR.into(),
+                InodeKind::File => libc::DT_REG.into(),
+            },
+            name,
+        })
+    }
+}
+
+#[cfg(test)]
+mod tests {
+    use anyhow::{bail, Result};
+    use nix::sys::statfs::{statfs, FsType};
+    use std::collections::HashSet;
+    use std::fs;
+    use std::fs::File;
+    use std::io::Write;
+    use std::path::{Path, PathBuf};
+    use std::time::{Duration, Instant};
+    use zip::write::FileOptions;
+
+    #[cfg(not(target_os = "android"))]
+    fn start_fuse(zip_path: &Path, mnt_path: &Path) {
+        let zip_path = PathBuf::from(zip_path);
+        let mnt_path = PathBuf::from(mnt_path);
+        std::thread::spawn(move || {
+            crate::run_fuse(&zip_path, &mnt_path).unwrap();
+        });
+    }
+
+    #[cfg(target_os = "android")]
+    fn start_fuse(zip_path: &Path, mnt_path: &Path) {
+        // Note: for some unknown reason, running a thread to serve fuse doesn't work on Android.
+        // Explicitly spawn a zipfuse process instead.
+        // TODO(jiyong): fix this
+        assert!(std::process::Command::new("sh")
+            .arg("-c")
+            .arg(format!("/data/local/tmp/zipfuse {} {}", zip_path.display(), mnt_path.display()))
+            .spawn()
+            .is_ok());
+    }
+
+    fn wait_for_mount(mount_path: &Path) -> Result<()> {
+        let start_time = Instant::now();
+        const POLL_INTERVAL: Duration = Duration::from_millis(50);
+        const TIMEOUT: Duration = Duration::from_secs(10);
+        const FUSE_SUPER_MAGIC: FsType = FsType(0x65735546);
+        loop {
+            if statfs(mount_path)?.filesystem_type() == FUSE_SUPER_MAGIC {
+                break;
+            }
+
+            if start_time.elapsed() > TIMEOUT {
+                bail!("Time out mounting zipfuse");
+            }
+            std::thread::sleep(POLL_INTERVAL);
+        }
+        Ok(())
+    }
+
+    // Creates a zip file, adds some files to the zip file, mounts it using zipfuse, runs the check
+    // routine, and finally unmounts.
+    fn run_test(add: fn(&mut zip::ZipWriter<File>), check: fn(&std::path::Path)) {
+        // Create an empty zip file
+        let test_dir = tempfile::TempDir::new().unwrap();
+        let zip_path = test_dir.path().join("test.zip");
+        let zip = File::create(&zip_path);
+        assert!(zip.is_ok());
+        let mut zip = zip::ZipWriter::new(zip.unwrap());
+
+        // Let test users add files/dirs to the zip file
+        add(&mut zip);
+        assert!(zip.finish().is_ok());
+        drop(zip);
+
+        // Mount the zip file on the "mnt" dir using zipfuse.
+        let mnt_path = test_dir.path().join("mnt");
+        assert!(fs::create_dir(&mnt_path).is_ok());
+
+        start_fuse(&zip_path, &mnt_path);
+
+        let mnt_path = test_dir.path().join("mnt");
+        // Give some time for the fuse to boot up
+        assert!(wait_for_mount(&mnt_path).is_ok());
+        // Run the check routine, and do the clean up.
+        check(&mnt_path);
+        assert!(nix::mount::umount2(&mnt_path, nix::mount::MntFlags::empty()).is_ok());
+    }
+
+    fn check_file(root: &Path, file: &str, content: &[u8]) {
+        let path = root.join(file);
+        assert!(path.exists());
+
+        let metadata = fs::metadata(&path);
+        assert!(metadata.is_ok());
+
+        let metadata = metadata.unwrap();
+        assert!(metadata.is_file());
+        assert_eq!(content.len(), metadata.len() as usize);
+
+        let read_data = fs::read(&path);
+        assert!(read_data.is_ok());
+        assert_eq!(content, read_data.unwrap().as_slice());
+    }
+
+    fn check_dir(root: &Path, dir: &str, files: &[&str], dirs: &[&str]) {
+        let dir_path = root.join(dir);
+        assert!(dir_path.exists());
+
+        let metadata = fs::metadata(&dir_path);
+        assert!(metadata.is_ok());
+
+        let metadata = metadata.unwrap();
+        assert!(metadata.is_dir());
+
+        let iter = fs::read_dir(&dir_path);
+        assert!(iter.is_ok());
+
+        let iter = iter.unwrap();
+        let mut actual_files = HashSet::new();
+        let mut actual_dirs = HashSet::new();
+        for de in iter {
+            let entry = de.unwrap();
+            let path = entry.path();
+            if path.is_dir() {
+                actual_dirs.insert(path.strip_prefix(&dir_path).unwrap().to_path_buf());
+            } else {
+                actual_files.insert(path.strip_prefix(&dir_path).unwrap().to_path_buf());
+            }
+        }
+        let expected_files: HashSet<PathBuf> = files.iter().map(|&s| PathBuf::from(s)).collect();
+        let expected_dirs: HashSet<PathBuf> = dirs.iter().map(|&s| PathBuf::from(s)).collect();
+
+        assert_eq!(expected_files, actual_files);
+        assert_eq!(expected_dirs, actual_dirs);
+    }
+
+    #[test]
+    fn empty() {
+        run_test(
+            |_| {},
+            |root| {
+                check_dir(root, "", &[], &[]);
+            },
+        );
+    }
+
+    #[test]
+    fn single_file() {
+        run_test(
+            |zip| {
+                zip.start_file("foo", FileOptions::default()).unwrap();
+                zip.write_all(b"0123456789").unwrap();
+            },
+            |root| {
+                check_dir(root, "", &["foo"], &[]);
+                check_file(root, "foo", b"0123456789");
+            },
+        );
+    }
+
+    #[test]
+    fn single_dir() {
+        run_test(
+            |zip| {
+                zip.add_directory("dir", FileOptions::default()).unwrap();
+            },
+            |root| {
+                check_dir(root, "", &[], &["dir"]);
+                check_dir(root, "dir", &[], &[]);
+            },
+        );
+    }
+
+    #[test]
+    fn complex_hierarchy() {
+        // root/
+        //   a/
+        //    b1/
+        //    b2/
+        //      c1 (file)
+        //      c2/
+        //          d1 (file)
+        //          d2 (file)
+        //          d3 (file)
+        //  x/
+        //    y1 (file)
+        //    y2 (file)
+        //    y3/
+        //
+        //  foo (file)
+        //  bar (file)
+        run_test(
+            |zip| {
+                let opt = FileOptions::default();
+                zip.add_directory("a/b1", opt).unwrap();
+
+                zip.start_file("a/b2/c1", opt).unwrap();
+
+                zip.start_file("a/b2/c2/d1", opt).unwrap();
+                zip.start_file("a/b2/c2/d2", opt).unwrap();
+                zip.start_file("a/b2/c2/d3", opt).unwrap();
+
+                zip.start_file("x/y1", opt).unwrap();
+                zip.start_file("x/y2", opt).unwrap();
+                zip.add_directory("x/y3", opt).unwrap();
+
+                zip.start_file("foo", opt).unwrap();
+                zip.start_file("bar", opt).unwrap();
+            },
+            |root| {
+                check_dir(root, "", &["foo", "bar"], &["a", "x"]);
+                check_dir(root, "a", &[], &["b1", "b2"]);
+                check_dir(root, "a/b1", &[], &[]);
+                check_dir(root, "a/b2", &["c1"], &["c2"]);
+                check_dir(root, "a/b2/c2", &["d1", "d2", "d3"], &[]);
+                check_dir(root, "x", &["y1", "y2"], &["y3"]);
+                check_dir(root, "x/y3", &[], &[]);
+                check_file(root, "a/b2/c1", &[]);
+                check_file(root, "a/b2/c2/d1", &[]);
+                check_file(root, "a/b2/c2/d2", &[]);
+                check_file(root, "a/b2/c2/d3", &[]);
+                check_file(root, "x/y1", &[]);
+                check_file(root, "x/y2", &[]);
+                check_file(root, "foo", &[]);
+                check_file(root, "bar", &[]);
+            },
+        );
+    }
+
+    #[test]
+    fn large_file() {
+        run_test(
+            |zip| {
+                let data = vec![10; 2 << 20];
+                zip.start_file("foo", FileOptions::default()).unwrap();
+                zip.write_all(&data).unwrap();
+            },
+            |root| {
+                let data = vec![10; 2 << 20];
+                check_file(root, "foo", &data);
+            },
+        );
+    }
+}
