authfs: Reorganize modules & rename flags/classes/vars

This change adjusts the module/directory layout to make it easier to
reason.

 - File "transports" are now under file/. Common traits are defined in
   file.rs.

 - All fs-verity related modules are now under fsverity/. This includes
   VerifiedFileReader, which implements traits in the file module to
   provide transparent verification.

 - Rename structs for better consistency.  Drop "Chunked" for
   simplicity.

    ChunkedFileReader          ->  LocalFileReader
    RemoteChunkedFileReader    ->  RemoteFileReader
    FsverityChunkedFileReader  ->  VerifiedFileReader

 - Move and rename get_local_service from remote_file.rs to file.rs.

Also, rename command line flags and related class/field names in main.rs
so that later the name of new read-writable file can fit in more consistently.

New layours:
  src/
  |-- auth.rs
  |-- common.rs
  |-- crypto.hpp
  |-- crypto.rs
  |-- file.rs
  |-- file
  |   |-- local_file.rs
  |   `-- remote_file.rs
  |-- fsverity.rs
  |-- fsverity
  |   |-- builder.rs
  |   |-- common.rs
  |   |-- sys.rs
  |   |-- verifier.rs
  |   `-- editor.rs
  |-- fusefs.rs
  `-- main.rs

Bug: 171279640
Test: atest

Change-Id: Ib257a37df89c6b813f4d97978678db3483d28b57
diff --git a/authfs/src/file.rs b/authfs/src/file.rs
new file mode 100644
index 0000000..1d52631
--- /dev/null
+++ b/authfs/src/file.rs
@@ -0,0 +1,49 @@
+mod local_file;
+mod remote_file;
+
+pub use local_file::LocalFileReader;
+pub use remote_file::{RemoteFileReader, RemoteMerkleTreeReader};
+
+use std::io;
+
+use authfs_aidl_interface::aidl::com::android::virt::fs::IVirtFdService;
+use authfs_aidl_interface::binder::{get_interface, Strong};
+
+// TODO(victorhsieh): use remote binder.
+pub fn get_local_binder() -> Strong<dyn IVirtFdService::IVirtFdService> {
+    let service_name = "authfs_fd_server";
+    get_interface(&service_name).expect("Cannot reach authfs_fd_server binder service")
+}
+
+/// A trait for reading data by chunks. The data is assumed readonly and has fixed length. Chunks
+/// can be read by specifying the chunk index. Only the last chunk may have incomplete chunk size.
+pub trait ReadOnlyDataByChunk {
+    /// Read the `chunk_index`-th chunk to `buf`. Each slice/chunk has size `CHUNK_SIZE` except for
+    /// the last one, which can be an incomplete chunk. `buf` is currently required to be large
+    /// enough to hold a full chunk of data. Reading beyond the file size (including empty file)
+    /// will crash.
+    fn read_chunk(&self, chunk_index: u64, buf: &mut [u8]) -> io::Result<usize>;
+}
+
+/// A trait to write a buffer to the destination at a given offset. The implementation does not
+/// necessarily own or maintain the destination state.
+///
+/// NB: The trait is required in a member of `fusefs::AuthFs`, which is required to be Sync and
+/// immutable (this the member).
+pub trait RandomWrite {
+    /// Writes `buf` to the destination at `offset`. Returns the written size, which may not be the
+    /// full buffer.
+    fn write_at(&self, buf: &[u8], offset: u64) -> io::Result<usize>;
+
+    /// Writes the full `buf` to the destination at `offset`.
+    fn write_all_at(&self, buf: &[u8], offset: u64) -> io::Result<()> {
+        let mut input_offset = 0;
+        let mut output_offset = offset;
+        while input_offset < buf.len() {
+            let size = self.write_at(&buf[input_offset..], output_offset)?;
+            input_offset += size;
+            output_offset += size as u64;
+        }
+        Ok(())
+    }
+}
diff --git a/authfs/src/reader.rs b/authfs/src/file/local_file.rs
similarity index 64%
rename from authfs/src/reader.rs
rename to authfs/src/file/local_file.rs
index 0242afa..0692767 100644
--- a/authfs/src/reader.rs
+++ b/authfs/src/file/local_file.rs
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2020 The Android Open Source Project
+ * 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.
@@ -14,24 +14,13 @@
  * limitations under the License.
  */
 
-//! A module for reading data by chunks.
-
 use std::fs::File;
 use std::io::Result;
 use std::os::unix::fs::FileExt;
 
+use super::ReadOnlyDataByChunk;
 use crate::common::CHUNK_SIZE;
 
-/// A trait for reading data by chunks. The data is assumed readonly and has fixed length. Chunks
-/// can be read by specifying the chunk index. Only the last chunk may have incomplete chunk size.
-pub trait ReadOnlyDataByChunk {
-    /// Read the `chunk_index`-th chunk to `buf`. Each slice/chunk has size `CHUNK_SIZE` except for
-    /// the last one, which can be an incomplete chunk. `buf` is currently required to be large
-    /// enough to hold a full chunk of data. Reading beyond the file size (including empty file)
-    /// will crash.
-    fn read_chunk(&self, chunk_index: u64, buf: &mut [u8]) -> Result<usize>;
-}
-
 fn chunk_index_to_range(size: u64, chunk_index: u64) -> Result<(u64, u64)> {
     let start = chunk_index * CHUNK_SIZE;
     assert!(start < size);
@@ -40,16 +29,16 @@
 }
 
 /// A read-only file that can be read by chunks.
-pub struct ChunkedFileReader {
+pub struct LocalFileReader {
     file: File,
     size: u64,
 }
 
-impl ChunkedFileReader {
-    /// Creates a `ChunkedFileReader` to read from for the specified `path`.
-    pub fn new(file: File) -> Result<ChunkedFileReader> {
+impl LocalFileReader {
+    /// Creates a `LocalFileReader` to read from for the specified `path`.
+    pub fn new(file: File) -> Result<LocalFileReader> {
         let size = file.metadata()?.len();
-        Ok(ChunkedFileReader { file, size })
+        Ok(LocalFileReader { file, size })
     }
 
     pub fn len(&self) -> u64 {
@@ -57,7 +46,7 @@
     }
 }
 
-impl ReadOnlyDataByChunk for ChunkedFileReader {
+impl ReadOnlyDataByChunk for LocalFileReader {
     fn read_chunk(&self, chunk_index: u64, buf: &mut [u8]) -> Result<usize> {
         debug_assert!(buf.len() as u64 >= CHUNK_SIZE);
         let (start, end) = chunk_index_to_range(self.size, chunk_index)?;
@@ -73,7 +62,7 @@
 
     #[test]
     fn test_read_4k_file() -> Result<()> {
-        let file_reader = ChunkedFileReader::new(File::open("testdata/input.4k")?)?;
+        let file_reader = LocalFileReader::new(File::open("testdata/input.4k")?)?;
         let mut buf = [0u8; 4096];
         let size = file_reader.read_chunk(0, &mut buf)?;
         assert_eq!(size, buf.len());
@@ -82,7 +71,7 @@
 
     #[test]
     fn test_read_4k1_file() -> Result<()> {
-        let file_reader = ChunkedFileReader::new(File::open("testdata/input.4k1")?)?;
+        let file_reader = LocalFileReader::new(File::open("testdata/input.4k1")?)?;
         let mut buf = [0u8; 4096];
         let size = file_reader.read_chunk(0, &mut buf)?;
         assert_eq!(size, buf.len());
@@ -93,7 +82,7 @@
 
     #[test]
     fn test_read_4m_file() -> Result<()> {
-        let file_reader = ChunkedFileReader::new(File::open("testdata/input.4m")?)?;
+        let file_reader = LocalFileReader::new(File::open("testdata/input.4m")?)?;
         for index in 0..file_reader.len() / 4096 {
             let mut buf = [0u8; 4096];
             let size = file_reader.read_chunk(index, &mut buf)?;
@@ -105,7 +94,7 @@
     #[test]
     #[should_panic]
     fn test_read_beyond_file_size() {
-        let file_reader = ChunkedFileReader::new(File::open("testdata/input.4k").unwrap()).unwrap();
+        let file_reader = LocalFileReader::new(File::open("testdata/input.4k").unwrap()).unwrap();
         let mut buf = [0u8; 4096];
         let _ = file_reader.read_chunk(1u64, &mut buf); // should panic
     }
@@ -115,7 +104,7 @@
     fn test_read_empty_file() {
         let mut temp_file = temp_dir();
         temp_file.push("authfs_test_empty_file");
-        let file_reader = ChunkedFileReader::new(File::create(temp_file).unwrap()).unwrap();
+        let file_reader = LocalFileReader::new(File::create(temp_file).unwrap()).unwrap();
         let mut buf = [0u8; 4096];
         let _ = file_reader.read_chunk(0, &mut buf); // should panic
     }
diff --git a/authfs/src/remote_file.rs b/authfs/src/file/remote_file.rs
similarity index 82%
rename from authfs/src/remote_file.rs
rename to authfs/src/file/remote_file.rs
index ed7381c..b87891b 100644
--- a/authfs/src/remote_file.rs
+++ b/authfs/src/file/remote_file.rs
@@ -19,24 +19,14 @@
 use std::io::Write;
 use std::sync::{Arc, Mutex};
 
+use super::{RandomWrite, ReadOnlyDataByChunk};
 use crate::common::CHUNK_SIZE;
-use crate::reader::ReadOnlyDataByChunk;
-use crate::writer::RandomWrite;
 
 use authfs_aidl_interface::aidl::com::android::virt::fs::IVirtFdService;
 use authfs_aidl_interface::binder::Strong;
 
 type VirtFdService = Strong<dyn IVirtFdService::IVirtFdService>;
 
-pub mod server {
-    // TODO(victorhsieh): use remote binder.
-    pub fn get_local_service() -> super::VirtFdService {
-        let service_name = "authfs_fd_server";
-        authfs_aidl_interface::binder::get_interface(&service_name)
-            .expect("Cannot reach authfs_fd_server binder service")
-    }
-}
-
 fn remote_read_chunk(
     service: &Arc<Mutex<VirtFdService>>,
     remote_fd: i32,
@@ -54,38 +44,38 @@
     buf.write(&chunk)
 }
 
-pub struct RemoteChunkedFileReader {
+pub struct RemoteFileReader {
     // This needs to have Sync trait to be used in fuse::worker::start_message_loop.
     service: Arc<Mutex<VirtFdService>>,
     file_fd: i32,
 }
 
-impl RemoteChunkedFileReader {
+impl RemoteFileReader {
     pub fn new(service: Arc<Mutex<VirtFdService>>, file_fd: i32) -> Self {
-        RemoteChunkedFileReader { service, file_fd }
+        RemoteFileReader { service, file_fd }
     }
 }
 
-impl ReadOnlyDataByChunk for RemoteChunkedFileReader {
+impl ReadOnlyDataByChunk for RemoteFileReader {
     fn read_chunk(&self, chunk_index: u64, buf: &mut [u8]) -> io::Result<usize> {
         remote_read_chunk(&self.service, self.file_fd, chunk_index, buf)
     }
 }
 
-pub struct RemoteFsverityMerkleTreeReader {
+pub struct RemoteMerkleTreeReader {
     // This needs to be a Sync to be used in fuse::worker::start_message_loop.
     // TODO(victorhsieh): change to Strong<> once binder supports it.
     service: Arc<Mutex<VirtFdService>>,
     file_fd: i32,
 }
 
-impl RemoteFsverityMerkleTreeReader {
+impl RemoteMerkleTreeReader {
     pub fn new(service: Arc<Mutex<VirtFdService>>, file_fd: i32) -> Self {
-        RemoteFsverityMerkleTreeReader { service, file_fd }
+        RemoteMerkleTreeReader { service, file_fd }
     }
 }
 
-impl ReadOnlyDataByChunk for RemoteFsverityMerkleTreeReader {
+impl ReadOnlyDataByChunk for RemoteMerkleTreeReader {
     fn read_chunk(&self, chunk_index: u64, mut buf: &mut [u8]) -> io::Result<usize> {
         let offset = i64::try_from(chunk_index * CHUNK_SIZE)
             .map_err(|_| io::Error::from_raw_os_error(libc::EOVERFLOW))?;
diff --git a/authfs/src/fsverity.rs b/authfs/src/fsverity.rs
index 37d96c1..1515574 100644
--- a/authfs/src/fsverity.rs
+++ b/authfs/src/fsverity.rs
@@ -16,8 +16,9 @@
 
 mod builder;
 mod common;
+mod editor;
 mod sys;
 mod verifier;
 
-pub use self::builder::MerkleLeaves;
-pub use self::verifier::FsverityChunkedFileReader;
+pub use editor::VerifiedFileEditor;
+pub use verifier::VerifiedFileReader;
diff --git a/authfs/src/writer.rs b/authfs/src/fsverity/editor.rs
similarity index 90%
rename from authfs/src/writer.rs
rename to authfs/src/fsverity/editor.rs
index 6706a08..fc4e101 100644
--- a/authfs/src/writer.rs
+++ b/authfs/src/fsverity/editor.rs
@@ -55,10 +55,10 @@
 use std::io;
 use std::sync::{Arc, RwLock};
 
+use super::builder::MerkleLeaves;
 use crate::common::{ChunkedSizeIter, CHUNK_SIZE};
 use crate::crypto::{CryptoError, Sha256Hash, Sha256Hasher};
-use crate::fsverity::MerkleLeaves;
-use crate::reader::ReadOnlyDataByChunk;
+use crate::file::{RandomWrite, ReadOnlyDataByChunk};
 
 // Implement the conversion from `CryptoError` to `io::Error` just to avoid manual error type
 // mapping below.
@@ -68,26 +68,6 @@
     }
 }
 
-/// A trait to write a buffer to the destination at a given offset. The implementation does not
-/// necessarily own or maintain the destination state.
-pub trait RandomWrite {
-    /// Writes `buf` to the destination at `offset`. Returns the written size, which may not be the
-    /// full buffer.
-    fn write_at(&self, buf: &[u8], offset: u64) -> io::Result<usize>;
-
-    /// Writes the full `buf` to the destination at `offset`.
-    fn write_all_at(&self, buf: &[u8], offset: u64) -> io::Result<()> {
-        let mut input_offset = 0;
-        let mut output_offset = offset;
-        while input_offset < buf.len() {
-            let size = self.write_at(&buf[input_offset..], output_offset)?;
-            input_offset += size;
-            output_offset += size as u64;
-        }
-        Ok(())
-    }
-}
-
 /// VerifiedFileEditor provides an integrity layer to an underlying read-writable file, which may
 /// not be stored in a trusted environment. Only new, empty files are currently supported.
 pub struct VerifiedFileEditor<F: ReadOnlyDataByChunk + RandomWrite> {
@@ -247,18 +227,18 @@
     use std::cell::RefCell;
     use std::convert::TryInto;
 
-    struct InMemoryWriter {
+    struct InMemoryEditor {
         data: RefCell<Vec<u8>>,
         fail_read: bool,
     }
 
-    impl InMemoryWriter {
-        pub fn new() -> InMemoryWriter {
-            InMemoryWriter { data: RefCell::new(Vec::new()), fail_read: false }
+    impl InMemoryEditor {
+        pub fn new() -> InMemoryEditor {
+            InMemoryEditor { data: RefCell::new(Vec::new()), fail_read: false }
         }
     }
 
-    impl RandomWrite for InMemoryWriter {
+    impl RandomWrite for InMemoryEditor {
         fn write_at(&self, buf: &[u8], offset: u64) -> io::Result<usize> {
             let begin: usize =
                 offset.try_into().map_err(|e| io::Error::new(io::ErrorKind::Other, e))?;
@@ -271,7 +251,7 @@
         }
     }
 
-    impl ReadOnlyDataByChunk for InMemoryWriter {
+    impl ReadOnlyDataByChunk for InMemoryEditor {
         fn read_chunk(&self, chunk_index: u64, buf: &mut [u8]) -> io::Result<usize> {
             debug_assert!(buf.len() as u64 >= CHUNK_SIZE);
 
@@ -296,7 +276,7 @@
 
     #[test]
     fn test_writer() -> Result<()> {
-        let writer = InMemoryWriter::new();
+        let writer = InMemoryEditor::new();
         let buf = [1; 4096];
         assert_eq!(writer.data.borrow().len(), 0);
 
@@ -313,7 +293,7 @@
     #[test]
     fn test_verified_writer_no_write() -> Result<()> {
         // Verify fs-verity hash without any write.
-        let file = VerifiedFileEditor::new(InMemoryWriter::new());
+        let file = VerifiedFileEditor::new(InMemoryEditor::new());
         assert_eq!(
             file.calculate_fsverity_digest()?,
             to_u8_vec("3d248ca542a24fc62d1c43b916eae5016878e2533c88238480b26128a1f1af95")
@@ -325,7 +305,7 @@
     #[test]
     fn test_verified_writer_from_zero() -> Result<()> {
         // Verify a write of a full chunk.
-        let file = VerifiedFileEditor::new(InMemoryWriter::new());
+        let file = VerifiedFileEditor::new(InMemoryEditor::new());
         assert_eq!(file.write_at(&[1; 4096], 0)?, 4096);
         assert_eq!(
             file.calculate_fsverity_digest()?,
@@ -334,7 +314,7 @@
         );
 
         // Verify a write of across multiple chunks.
-        let file = VerifiedFileEditor::new(InMemoryWriter::new());
+        let file = VerifiedFileEditor::new(InMemoryEditor::new());
         assert_eq!(file.write_at(&[1; 4097], 0)?, 4097);
         assert_eq!(
             file.calculate_fsverity_digest()?,
@@ -343,7 +323,7 @@
         );
 
         // Verify another write of across multiple chunks.
-        let file = VerifiedFileEditor::new(InMemoryWriter::new());
+        let file = VerifiedFileEditor::new(InMemoryEditor::new());
         assert_eq!(file.write_at(&[1; 10000], 0)?, 10000);
         assert_eq!(
             file.calculate_fsverity_digest()?,
@@ -356,7 +336,7 @@
     #[test]
     fn test_verified_writer_unaligned() -> Result<()> {
         // Verify small, unaligned write beyond EOF.
-        let file = VerifiedFileEditor::new(InMemoryWriter::new());
+        let file = VerifiedFileEditor::new(InMemoryEditor::new());
         assert_eq!(file.write_at(&[1; 5], 3)?, 5);
         assert_eq!(
             file.calculate_fsverity_digest()?,
@@ -365,7 +345,7 @@
         );
 
         // Verify bigger, unaligned write beyond EOF.
-        let file = VerifiedFileEditor::new(InMemoryWriter::new());
+        let file = VerifiedFileEditor::new(InMemoryEditor::new());
         assert_eq!(file.write_at(&[1; 6000], 4000)?, 6000);
         assert_eq!(
             file.calculate_fsverity_digest()?,
@@ -378,7 +358,7 @@
     #[test]
     fn test_verified_writer_with_hole() -> Result<()> {
         // Verify an aligned write beyond EOF with holes.
-        let file = VerifiedFileEditor::new(InMemoryWriter::new());
+        let file = VerifiedFileEditor::new(InMemoryEditor::new());
         assert_eq!(file.write_at(&[1; 4096], 4096)?, 4096);
         assert_eq!(
             file.calculate_fsverity_digest()?,
@@ -387,7 +367,7 @@
         );
 
         // Verify an unaligned write beyond EOF with holes.
-        let file = VerifiedFileEditor::new(InMemoryWriter::new());
+        let file = VerifiedFileEditor::new(InMemoryEditor::new());
         assert_eq!(file.write_at(&[1; 5000], 6000)?, 5000);
         assert_eq!(
             file.calculate_fsverity_digest()?,
@@ -396,7 +376,7 @@
         );
 
         // Just another example with a small write.
-        let file = VerifiedFileEditor::new(InMemoryWriter::new());
+        let file = VerifiedFileEditor::new(InMemoryEditor::new());
         assert_eq!(file.write_at(&[1; 5], 16381)?, 5);
         assert_eq!(
             file.calculate_fsverity_digest()?,
@@ -408,7 +388,7 @@
 
     #[test]
     fn test_verified_writer_various_writes() -> Result<()> {
-        let file = VerifiedFileEditor::new(InMemoryWriter::new());
+        let file = VerifiedFileEditor::new(InMemoryEditor::new());
         assert_eq!(file.write_at(&[1; 2048], 0)?, 2048);
         assert_eq!(file.write_at(&[1; 2048], 4096 + 2048)?, 2048);
         assert_eq!(
@@ -448,7 +428,7 @@
 
     #[test]
     fn test_verified_writer_inconsistent_read() -> Result<()> {
-        let file = VerifiedFileEditor::new(InMemoryWriter::new());
+        let file = VerifiedFileEditor::new(InMemoryEditor::new());
         assert_eq!(file.write_at(&[1; 8192], 0)?, 8192);
 
         // Replace the expected hash of the first/0-th chunk. An incomplete write will fail when it
@@ -478,7 +458,7 @@
 
     #[test]
     fn test_verified_writer_failed_read_back() -> Result<()> {
-        let mut writer = InMemoryWriter::new();
+        let mut writer = InMemoryEditor::new();
         writer.fail_read = true;
         let file = VerifiedFileEditor::new(writer);
         assert_eq!(file.write_at(&[1; 8192], 0)?, 8192);
diff --git a/authfs/src/fsverity/verifier.rs b/authfs/src/fsverity/verifier.rs
index fd108f5..4021ce1 100644
--- a/authfs/src/fsverity/verifier.rs
+++ b/authfs/src/fsverity/verifier.rs
@@ -22,7 +22,7 @@
 use crate::auth::Authenticator;
 use crate::common::{divide_roundup, CHUNK_SIZE};
 use crate::crypto::{CryptoError, Sha256Hasher};
-use crate::reader::ReadOnlyDataByChunk;
+use crate::file::ReadOnlyDataByChunk;
 
 const ZEROS: [u8; CHUNK_SIZE as usize] = [0u8; CHUNK_SIZE as usize];
 
@@ -125,21 +125,21 @@
     Ok(formatted_digest)
 }
 
-pub struct FsverityChunkedFileReader<F: ReadOnlyDataByChunk, M: ReadOnlyDataByChunk> {
+pub struct VerifiedFileReader<F: ReadOnlyDataByChunk, M: ReadOnlyDataByChunk> {
     chunked_file: F,
     file_size: u64,
     merkle_tree: M,
     root_hash: HashBuffer,
 }
 
-impl<F: ReadOnlyDataByChunk, M: ReadOnlyDataByChunk> FsverityChunkedFileReader<F, M> {
+impl<F: ReadOnlyDataByChunk, M: ReadOnlyDataByChunk> VerifiedFileReader<F, M> {
     pub fn new<A: Authenticator>(
         authenticator: &A,
         chunked_file: F,
         file_size: u64,
         sig: Vec<u8>,
         merkle_tree: M,
-    ) -> Result<FsverityChunkedFileReader<F, M>, FsverityError> {
+    ) -> Result<VerifiedFileReader<F, M>, FsverityError> {
         let mut buf = [0u8; CHUNK_SIZE as usize];
         let size = merkle_tree.read_chunk(0, &mut buf)?;
         if buf.len() != size {
@@ -149,7 +149,7 @@
         let formatted_digest = build_fsverity_formatted_digest(&root_hash, file_size)?;
         let valid = authenticator.verify(&sig, &formatted_digest)?;
         if valid {
-            Ok(FsverityChunkedFileReader { chunked_file, file_size, merkle_tree, root_hash })
+            Ok(VerifiedFileReader { chunked_file, file_size, merkle_tree, root_hash })
         } else {
             Err(FsverityError::BadSignature)
         }
@@ -157,7 +157,7 @@
 }
 
 impl<F: ReadOnlyDataByChunk, M: ReadOnlyDataByChunk> ReadOnlyDataByChunk
-    for FsverityChunkedFileReader<F, M>
+    for VerifiedFileReader<F, M>
 {
     fn read_chunk(&self, chunk_index: u64, buf: &mut [u8]) -> io::Result<usize> {
         debug_assert!(buf.len() as u64 >= CHUNK_SIZE);
@@ -176,13 +176,12 @@
 mod tests {
     use super::*;
     use crate::auth::FakeAuthenticator;
-    use crate::reader::{ChunkedFileReader, ReadOnlyDataByChunk};
+    use crate::file::{LocalFileReader, ReadOnlyDataByChunk};
     use anyhow::Result;
     use std::fs::File;
     use std::io::Read;
 
-    type LocalFsverityChunkedFileReader =
-        FsverityChunkedFileReader<ChunkedFileReader, ChunkedFileReader>;
+    type LocalVerifiedFileReader = VerifiedFileReader<LocalFileReader, LocalFileReader>;
 
     fn total_chunk_number(file_size: u64) -> u64 {
         (file_size + 4095) / 4096
@@ -193,21 +192,15 @@
         content_path: &str,
         merkle_tree_path: &str,
         signature_path: &str,
-    ) -> Result<(LocalFsverityChunkedFileReader, u64)> {
-        let file_reader = ChunkedFileReader::new(File::open(content_path)?)?;
+    ) -> Result<(LocalVerifiedFileReader, u64)> {
+        let file_reader = LocalFileReader::new(File::open(content_path)?)?;
         let file_size = file_reader.len();
-        let merkle_tree = ChunkedFileReader::new(File::open(merkle_tree_path)?)?;
+        let merkle_tree = LocalFileReader::new(File::open(merkle_tree_path)?)?;
         let mut sig = Vec::new();
         let _ = File::open(signature_path)?.read_to_end(&mut sig)?;
         let authenticator = FakeAuthenticator::always_succeed();
         Ok((
-            FsverityChunkedFileReader::new(
-                &authenticator,
-                file_reader,
-                file_size,
-                sig,
-                merkle_tree,
-            )?,
+            VerifiedFileReader::new(&authenticator, file_reader, file_size, sig, merkle_tree)?,
             file_size,
         ))
     }
@@ -280,18 +273,12 @@
     #[test]
     fn invalid_signature() -> Result<()> {
         let authenticator = FakeAuthenticator::always_fail();
-        let file_reader = ChunkedFileReader::new(File::open("testdata/input.4m")?)?;
+        let file_reader = LocalFileReader::new(File::open("testdata/input.4m")?)?;
         let file_size = file_reader.len();
-        let merkle_tree = ChunkedFileReader::new(File::open("testdata/input.4m.merkle_dump")?)?;
+        let merkle_tree = LocalFileReader::new(File::open("testdata/input.4m.merkle_dump")?)?;
         let sig = include_bytes!("../../testdata/input.4m.fsv_sig").to_vec();
-        assert!(FsverityChunkedFileReader::new(
-            &authenticator,
-            file_reader,
-            file_size,
-            sig,
-            merkle_tree
-        )
-        .is_err());
+        assert!(VerifiedFileReader::new(&authenticator, file_reader, file_size, sig, merkle_tree)
+            .is_err());
         Ok(())
     }
 }
diff --git a/authfs/src/fusefs.rs b/authfs/src/fusefs.rs
index bbcb84f..bdf7cd8 100644
--- a/authfs/src/fusefs.rs
+++ b/authfs/src/fusefs.rs
@@ -30,27 +30,19 @@
 use fuse::mount::MountOption;
 
 use crate::common::{divide_roundup, ChunkedSizeIter, CHUNK_SIZE};
-use crate::fsverity::FsverityChunkedFileReader;
-use crate::reader::{ChunkedFileReader, ReadOnlyDataByChunk};
-use crate::remote_file::{RemoteChunkedFileReader, RemoteFsverityMerkleTreeReader};
+use crate::file::{LocalFileReader, ReadOnlyDataByChunk, RemoteFileReader, RemoteMerkleTreeReader};
+use crate::fsverity::VerifiedFileReader;
 
 const DEFAULT_METADATA_TIMEOUT: std::time::Duration = Duration::from_secs(5);
 
 pub type Inode = u64;
 type Handle = u64;
 
-type RemoteFsverityChunkedFileReader =
-    FsverityChunkedFileReader<RemoteChunkedFileReader, RemoteFsverityMerkleTreeReader>;
-
-// A debug only type where everything are stored as local files.
-type FileBackedFsverityChunkedFileReader =
-    FsverityChunkedFileReader<ChunkedFileReader, ChunkedFileReader>;
-
 pub enum FileConfig {
-    LocalVerifiedFile(FileBackedFsverityChunkedFileReader, u64),
-    LocalUnverifiedFile(ChunkedFileReader, u64),
-    RemoteVerifiedFile(RemoteFsverityChunkedFileReader, u64),
-    RemoteUnverifiedFile(RemoteChunkedFileReader, u64),
+    LocalVerifiedReadonlyFile(VerifiedFileReader<LocalFileReader, LocalFileReader>, u64),
+    LocalUnverifiedReadonlyFile(LocalFileReader, u64),
+    RemoteVerifiedReadonlyFile(VerifiedFileReader<RemoteFileReader, RemoteMerkleTreeReader>, u64),
+    RemoteUnverifiedReadonlyFile(RemoteFileReader, u64),
 }
 
 struct AuthFs {
@@ -177,10 +169,12 @@
         // be static.
         let inode = num.parse::<Inode>().map_err(|_| io::Error::from_raw_os_error(libc::ENOENT))?;
         let st = match self.get_file_config(&inode)? {
-            FileConfig::LocalVerifiedFile(_, file_size)
-            | FileConfig::LocalUnverifiedFile(_, file_size)
-            | FileConfig::RemoteUnverifiedFile(_, file_size)
-            | FileConfig::RemoteVerifiedFile(_, file_size) => create_stat(inode, *file_size)?,
+            FileConfig::LocalVerifiedReadonlyFile(_, file_size)
+            | FileConfig::LocalUnverifiedReadonlyFile(_, file_size)
+            | FileConfig::RemoteUnverifiedReadonlyFile(_, file_size)
+            | FileConfig::RemoteVerifiedReadonlyFile(_, file_size) => {
+                create_stat(inode, *file_size)?
+            }
         };
         Ok(Entry {
             inode,
@@ -199,10 +193,12 @@
     ) -> io::Result<(libc::stat64, Duration)> {
         Ok((
             match self.get_file_config(&inode)? {
-                FileConfig::LocalVerifiedFile(_, file_size)
-                | FileConfig::LocalUnverifiedFile(_, file_size)
-                | FileConfig::RemoteUnverifiedFile(_, file_size)
-                | FileConfig::RemoteVerifiedFile(_, file_size) => create_stat(inode, *file_size)?,
+                FileConfig::LocalVerifiedReadonlyFile(_, file_size)
+                | FileConfig::LocalUnverifiedReadonlyFile(_, file_size)
+                | FileConfig::RemoteUnverifiedReadonlyFile(_, file_size)
+                | FileConfig::RemoteVerifiedReadonlyFile(_, file_size) => {
+                    create_stat(inode, *file_size)?
+                }
             },
             DEFAULT_METADATA_TIMEOUT,
         ))
@@ -215,15 +211,18 @@
         flags: u32,
     ) -> io::Result<(Option<Self::Handle>, fuse::sys::OpenOptions)> {
         // Since file handle is not really used in later operations (which use Inode directly),
-        // return None as the handle..
+        // return None as the handle.
         match self.get_file_config(&inode)? {
-            FileConfig::LocalVerifiedFile(_, _) | FileConfig::RemoteVerifiedFile(_, _) => {
+            FileConfig::LocalVerifiedReadonlyFile(_, _)
+            | FileConfig::RemoteVerifiedReadonlyFile(_, _) => {
                 check_access_mode(flags, libc::O_RDONLY)?;
                 // Once verified, and only if verified, the file content can be cached. This is not
-                // really needed for a local file, but is the behavior of RemoteVerifiedFile later.
+                // really needed for a local file, but is the behavior of RemoteVerifiedReadonlyFile
+                // later.
                 Ok((None, fuse::sys::OpenOptions::KEEP_CACHE))
             }
-            FileConfig::LocalUnverifiedFile(_, _) | FileConfig::RemoteUnverifiedFile(_, _) => {
+            FileConfig::LocalUnverifiedReadonlyFile(_, _)
+            | FileConfig::RemoteUnverifiedReadonlyFile(_, _) => {
                 check_access_mode(flags, libc::O_RDONLY)?;
                 // Do not cache the content. This type of file is supposed to be verified using
                 // dm-verity. The filesystem mount over dm-verity already is already cached, so use
@@ -245,16 +244,16 @@
         _flags: u32,
     ) -> io::Result<usize> {
         match self.get_file_config(&inode)? {
-            FileConfig::LocalVerifiedFile(file, file_size) => {
+            FileConfig::LocalVerifiedReadonlyFile(file, file_size) => {
                 read_chunks(w, file, *file_size, offset, size)
             }
-            FileConfig::LocalUnverifiedFile(file, file_size) => {
+            FileConfig::LocalUnverifiedReadonlyFile(file, file_size) => {
                 read_chunks(w, file, *file_size, offset, size)
             }
-            FileConfig::RemoteVerifiedFile(file, file_size) => {
+            FileConfig::RemoteVerifiedReadonlyFile(file, file_size) => {
                 read_chunks(w, file, *file_size, offset, size)
             }
-            FileConfig::RemoteUnverifiedFile(file, file_size) => {
+            FileConfig::RemoteUnverifiedReadonlyFile(file, file_size) => {
                 read_chunks(w, file, *file_size, offset, size)
             }
         }
diff --git a/authfs/src/main.rs b/authfs/src/main.rs
index 05e4584..39482e3 100644
--- a/authfs/src/main.rs
+++ b/authfs/src/main.rs
@@ -38,17 +38,14 @@
 mod auth;
 mod common;
 mod crypto;
+mod file;
 mod fsverity;
 mod fusefs;
-mod reader;
-mod remote_file;
-mod writer;
 
 use auth::FakeAuthenticator;
-use fsverity::FsverityChunkedFileReader;
+use file::{LocalFileReader, RemoteFileReader, RemoteMerkleTreeReader};
+use fsverity::VerifiedFileReader;
 use fusefs::{FileConfig, Inode};
-use reader::ChunkedFileReader;
-use remote_file::{RemoteChunkedFileReader, RemoteFsverityMerkleTreeReader};
 
 #[derive(StructOpt)]
 struct Args {
@@ -56,31 +53,31 @@
     #[structopt(parse(from_os_str))]
     mount_point: PathBuf,
 
-    /// A verifiable read-only file. Can be multiple.
+    /// A read-only remote file with integrity check. Can be multiple.
     ///
     /// For example, `--remote-verified-file 5:10:1234:/path/to/cert` tells the filesystem to
     /// associate entry 5 with a remote file 10 of size 1234 bytes, and need to be verified against
     /// the /path/to/cert.
-    #[structopt(long, parse(try_from_str = parse_remote_verified_file_option))]
-    remote_verified_file: Vec<RemoteVerifiedFileConfig>,
+    #[structopt(long, parse(try_from_str = parse_remote_ro_file_option))]
+    remote_ro_file: Vec<OptionRemoteRoFile>,
 
-    /// An unverifiable read-only file. Can be multiple.
+    /// A read-only remote file without integrity check. Can be multiple.
     ///
     /// For example, `--remote-unverified-file 5:10:1234` tells the filesystem to associate entry 5
     /// with a remote file 10 of size 1234 bytes.
-    #[structopt(long, parse(try_from_str = parse_remote_unverified_file_option))]
-    remote_unverified_file: Vec<RemoteUnverifiedFileConfig>,
+    #[structopt(long, parse(try_from_str = parse_remote_ro_file_unverified_option))]
+    remote_ro_file_unverified: Vec<OptionRemoteRoFileUnverified>,
 
-    /// Debug only. A readonly file to be protected by fs-verity. Can be multiple.
-    #[structopt(long, parse(try_from_str = parse_local_verified_file_option))]
-    local_verified_file: Vec<LocalVerifiedFileConfig>,
+    /// Debug only. A read-only local file with integrity check. Can be multiple.
+    #[structopt(long, parse(try_from_str = parse_local_file_ro_option))]
+    local_ro_file: Vec<OptionLocalFileRo>,
 
-    /// Debug only. An unverified read-only file. Can be multiple.
-    #[structopt(long, parse(try_from_str = parse_local_unverified_file_option))]
-    local_unverified_file: Vec<LocalUnverifiedFileConfig>,
+    /// Debug only. A read-only local file without integrity check. Can be multiple.
+    #[structopt(long, parse(try_from_str = parse_local_ro_file_unverified_ro_option))]
+    local_ro_file_unverified: Vec<OptionLocalRoFileUnverified>,
 }
 
-struct RemoteVerifiedFileConfig {
+struct OptionRemoteRoFile {
     ino: Inode,
 
     /// ID to refer to the remote file.
@@ -95,7 +92,7 @@
     _certificate_path: PathBuf,
 }
 
-struct RemoteUnverifiedFileConfig {
+struct OptionRemoteRoFileUnverified {
     ino: Inode,
 
     /// ID to refer to the remote file.
@@ -105,7 +102,7 @@
     file_size: u64,
 }
 
-struct LocalVerifiedFileConfig {
+struct OptionLocalFileRo {
     ino: Inode,
 
     /// Local path of the backing file.
@@ -122,19 +119,19 @@
     _certificate_path: PathBuf,
 }
 
-struct LocalUnverifiedFileConfig {
+struct OptionLocalRoFileUnverified {
     ino: Inode,
 
     /// Local path of the backing file.
     file_path: PathBuf,
 }
 
-fn parse_remote_verified_file_option(option: &str) -> Result<RemoteVerifiedFileConfig> {
+fn parse_remote_ro_file_option(option: &str) -> Result<OptionRemoteRoFile> {
     let strs: Vec<&str> = option.split(':').collect();
     if strs.len() != 4 {
         bail!("Invalid option: {}", option);
     }
-    Ok(RemoteVerifiedFileConfig {
+    Ok(OptionRemoteRoFile {
         ino: strs[0].parse::<Inode>()?,
         remote_id: strs[1].parse::<i32>()?,
         file_size: strs[2].parse::<u64>()?,
@@ -142,24 +139,24 @@
     })
 }
 
-fn parse_remote_unverified_file_option(option: &str) -> Result<RemoteUnverifiedFileConfig> {
+fn parse_remote_ro_file_unverified_option(option: &str) -> Result<OptionRemoteRoFileUnverified> {
     let strs: Vec<&str> = option.split(':').collect();
     if strs.len() != 3 {
         bail!("Invalid option: {}", option);
     }
-    Ok(RemoteUnverifiedFileConfig {
+    Ok(OptionRemoteRoFileUnverified {
         ino: strs[0].parse::<Inode>()?,
         remote_id: strs[1].parse::<i32>()?,
         file_size: strs[2].parse::<u64>()?,
     })
 }
 
-fn parse_local_verified_file_option(option: &str) -> Result<LocalVerifiedFileConfig> {
+fn parse_local_file_ro_option(option: &str) -> Result<OptionLocalFileRo> {
     let strs: Vec<&str> = option.split(':').collect();
     if strs.len() != 5 {
         bail!("Invalid option: {}", option);
     }
-    Ok(LocalVerifiedFileConfig {
+    Ok(OptionLocalFileRo {
         ino: strs[0].parse::<Inode>()?,
         file_path: PathBuf::from(strs[1]),
         merkle_tree_dump_path: PathBuf::from(strs[2]),
@@ -168,92 +165,85 @@
     })
 }
 
-fn parse_local_unverified_file_option(option: &str) -> Result<LocalUnverifiedFileConfig> {
+fn parse_local_ro_file_unverified_ro_option(option: &str) -> Result<OptionLocalRoFileUnverified> {
     let strs: Vec<&str> = option.split(':').collect();
     if strs.len() != 2 {
         bail!("Invalid option: {}", option);
     }
-    Ok(LocalUnverifiedFileConfig {
+    Ok(OptionLocalRoFileUnverified {
         ino: strs[0].parse::<Inode>()?,
         file_path: PathBuf::from(strs[1]),
     })
 }
 
 fn new_config_remote_verified_file(remote_id: i32, file_size: u64) -> Result<FileConfig> {
-    let service = remote_file::server::get_local_service();
+    let service = file::get_local_binder();
     let signature = service.readFsveritySignature(remote_id).context("Failed to read signature")?;
 
     let service = Arc::new(Mutex::new(service));
     let authenticator = FakeAuthenticator::always_succeed();
-    Ok(FileConfig::RemoteVerifiedFile(
-        FsverityChunkedFileReader::new(
+    Ok(FileConfig::RemoteVerifiedReadonlyFile(
+        VerifiedFileReader::new(
             &authenticator,
-            RemoteChunkedFileReader::new(Arc::clone(&service), remote_id),
+            RemoteFileReader::new(Arc::clone(&service), remote_id),
             file_size,
             signature,
-            RemoteFsverityMerkleTreeReader::new(Arc::clone(&service), remote_id),
+            RemoteMerkleTreeReader::new(Arc::clone(&service), remote_id),
         )?,
         file_size,
     ))
 }
 
 fn new_config_remote_unverified_file(remote_id: i32, file_size: u64) -> Result<FileConfig> {
-    let file_reader = RemoteChunkedFileReader::new(
-        Arc::new(Mutex::new(remote_file::server::get_local_service())),
-        remote_id,
-    );
-    Ok(FileConfig::RemoteUnverifiedFile(file_reader, file_size))
+    let file_reader =
+        RemoteFileReader::new(Arc::new(Mutex::new(file::get_local_binder())), remote_id);
+    Ok(FileConfig::RemoteUnverifiedReadonlyFile(file_reader, file_size))
 }
 
-fn new_config_local_verified_file(
+fn new_config_local_ro_file(
     protected_file: &PathBuf,
     merkle_tree_dump: &PathBuf,
     signature: &PathBuf,
 ) -> Result<FileConfig> {
     let file = File::open(&protected_file)?;
     let file_size = file.metadata()?.len();
-    let file_reader = ChunkedFileReader::new(file)?;
-    let merkle_tree_reader = ChunkedFileReader::new(File::open(merkle_tree_dump)?)?;
+    let file_reader = LocalFileReader::new(file)?;
+    let merkle_tree_reader = LocalFileReader::new(File::open(merkle_tree_dump)?)?;
     let authenticator = FakeAuthenticator::always_succeed();
     let mut sig = Vec::new();
     let _ = File::open(signature)?.read_to_end(&mut sig)?;
-    let file_reader = FsverityChunkedFileReader::new(
-        &authenticator,
-        file_reader,
-        file_size,
-        sig,
-        merkle_tree_reader,
-    )?;
-    Ok(FileConfig::LocalVerifiedFile(file_reader, file_size))
+    let file_reader =
+        VerifiedFileReader::new(&authenticator, file_reader, file_size, sig, merkle_tree_reader)?;
+    Ok(FileConfig::LocalVerifiedReadonlyFile(file_reader, file_size))
 }
 
-fn new_config_local_unverified_file(file_path: &PathBuf) -> Result<FileConfig> {
-    let file_reader = ChunkedFileReader::new(File::open(file_path)?)?;
+fn new_config_local_ro_file_unverified(file_path: &PathBuf) -> Result<FileConfig> {
+    let file_reader = LocalFileReader::new(File::open(file_path)?)?;
     let file_size = file_reader.len();
-    Ok(FileConfig::LocalUnverifiedFile(file_reader, file_size))
+    Ok(FileConfig::LocalUnverifiedReadonlyFile(file_reader, file_size))
 }
 
 fn prepare_file_pool(args: &Args) -> Result<BTreeMap<Inode, FileConfig>> {
     let mut file_pool = BTreeMap::new();
 
-    for config in &args.remote_verified_file {
+    for config in &args.remote_ro_file {
         file_pool.insert(
             config.ino,
             new_config_remote_verified_file(config.remote_id, config.file_size)?,
         );
     }
 
-    for config in &args.remote_unverified_file {
+    for config in &args.remote_ro_file_unverified {
         file_pool.insert(
             config.ino,
             new_config_remote_unverified_file(config.remote_id, config.file_size)?,
         );
     }
 
-    for config in &args.local_verified_file {
+    for config in &args.local_ro_file {
         file_pool.insert(
             config.ino,
-            new_config_local_verified_file(
+            new_config_local_ro_file(
                 &config.file_path,
                 &config.merkle_tree_dump_path,
                 &config.signature_path,
@@ -261,8 +251,8 @@
         );
     }
 
-    for config in &args.local_unverified_file {
-        file_pool.insert(config.ino, new_config_local_unverified_file(&config.file_path)?);
+    for config in &args.local_ro_file_unverified {
+        file_pool.insert(config.ino, new_config_local_ro_file_unverified(&config.file_path)?);
     }
 
     Ok(file_pool)