authfs: instantiate read-only files lazily

The earlier implementation instantiates all remote files (defined in the
build manifest) at start. The instantiation includes 1) asking fd_server
to create the actual FDs, and 2) fetch the file's Merkle tree. The
instantiation of all files happens during AuthFS start, even if many
files aren't/won't be used.

This change makes the instnaitation lazy, i.e. 1) and 2) will only
happen when the file is first used.

Bug: 205883847
Test: atest AuthFsHostTest ComposHostTestCases
Change-Id: I2e4ee48b5442b56937e212505526b2f26eaadd91
diff --git a/authfs/src/fusefs.rs b/authfs/src/fusefs.rs
index 84129b6..9b866f5 100644
--- a/authfs/src/fusefs.rs
+++ b/authfs/src/fusefs.rs
@@ -14,6 +14,7 @@
  * limitations under the License.
  */
 
+mod file;
 mod mount;
 
 use anyhow::{anyhow, bail, Result};
@@ -37,12 +38,13 @@
 
 use crate::common::{divide_roundup, ChunkedSizeIter, CHUNK_SIZE};
 use crate::file::{
-    validate_basename, Attr, EagerChunkReader, InMemoryDir, RandomWrite, ReadByChunk,
-    RemoteDirEditor, RemoteFileEditor, RemoteFileReader,
+    validate_basename, Attr, InMemoryDir, RandomWrite, ReadByChunk, RemoteDirEditor,
+    RemoteFileEditor, RemoteFileReader,
 };
 use crate::fsstat::RemoteFsStatsReader;
-use crate::fsverity::{VerifiedFileEditor, VerifiedFileReader};
+use crate::fsverity::VerifiedFileEditor;
 
+pub use self::file::LazyVerifiedReadonlyFile;
 pub use self::mount::mount_and_enter_message_loop;
 use self::mount::MAX_WRITE_BYTES;
 
@@ -61,10 +63,7 @@
     ReadonlyDirectory { dir: InMemoryDir },
     /// A file type that is verified against fs-verity signature (thus read-only). The file is
     /// served from a remote server.
-    VerifiedReadonly {
-        reader: VerifiedFileReader<RemoteFileReader, EagerChunkReader>,
-        file_size: u64,
-    },
+    VerifiedReadonly { reader: LazyVerifiedReadonlyFile },
     /// A file type that is a read-only passthrough from a file on a remote server.
     UnverifiedReadonly { reader: RemoteFileReader, file_size: u64 },
     /// A file type that is initially empty, and the content is stored on a remote server. File
@@ -537,10 +536,12 @@
                     AuthFsEntry::ReadonlyDirectory { dir } => {
                         create_dir_stat(inode, dir.number_of_entries(), AccessMode::ReadOnly)
                     }
-                    AuthFsEntry::UnverifiedReadonly { file_size, .. }
-                    | AuthFsEntry::VerifiedReadonly { file_size, .. } => {
+                    AuthFsEntry::UnverifiedReadonly { file_size, .. } => {
                         create_stat(inode, *file_size, AccessMode::ReadOnly)
                     }
+                    AuthFsEntry::VerifiedReadonly { reader } => {
+                        create_stat(inode, reader.file_size()?, AccessMode::ReadOnly)
+                    }
                     AuthFsEntry::VerifiedNew { editor, attr, .. } => {
                         create_stat(inode, editor.size(), AccessMode::Variable(attr.mode()))
                     }
@@ -608,10 +609,12 @@
                     AuthFsEntry::ReadonlyDirectory { dir } => {
                         create_dir_stat(inode, dir.number_of_entries(), AccessMode::ReadOnly)
                     }
-                    AuthFsEntry::UnverifiedReadonly { file_size, .. }
-                    | AuthFsEntry::VerifiedReadonly { file_size, .. } => {
+                    AuthFsEntry::UnverifiedReadonly { file_size, .. } => {
                         create_stat(inode, *file_size, AccessMode::ReadOnly)
                     }
+                    AuthFsEntry::VerifiedReadonly { reader } => {
+                        create_stat(inode, reader.file_size()?, AccessMode::ReadOnly)
+                    }
                     AuthFsEntry::VerifiedNew { editor, attr, .. } => {
                         create_stat(inode, editor.size(), AccessMode::Variable(attr.mode()))
                     }
@@ -708,8 +711,8 @@
     ) -> io::Result<usize> {
         self.handle_inode(&inode, |config| {
             match config {
-                AuthFsEntry::VerifiedReadonly { reader, file_size } => {
-                    read_chunks(w, reader, *file_size, offset, size)
+                AuthFsEntry::VerifiedReadonly { reader } => {
+                    read_chunks(w, reader, reader.file_size()?, offset, size)
                 }
                 AuthFsEntry::UnverifiedReadonly { reader, file_size } => {
                     read_chunks(w, reader, *file_size, offset, size)