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)