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);
+            },
+        );
+    }
+}
