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..ec00565
--- /dev/null
+++ b/zipfuse/src/inode.rs
@@ -0,0 +1,419 @@
+/*
+ * 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::{OsStr, OsString};
+use std::io;
+
+/// `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<OsString, 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<OsString, 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: OsString, 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: &OsStr) -> 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: &OsStr, 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(OsString::from(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.
+                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 inode = it.find(parent, &OsString::from(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 inode = it.find(parent, &OsString::from(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..d6710d6
--- /dev/null
+++ b/zipfuse/src/main.rs
@@ -0,0 +1,599 @@
+/*
+ * 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, OsStr};
+use std::fs::{File, OpenOptions};
+use std::io;
+use std::io::Read;
+use std::os::unix::ffi::OsStrExt;
+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 name = OsStr::from_bytes(name.to_bytes());
+        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);
+            },
+        );
+    }
+}
