fuchsia_storage_benchmarks/filesystems/
blobfs.rs
1use crate::filesystems::{BlobFilesystem, DeliveryBlob, FsManagementFilesystemInstance};
6use async_trait::async_trait;
7use delivery_blob::delivery_blob_path;
8use fidl_fuchsia_io as fio;
9use std::path::Path;
10use storage_benchmarks::{
11 BlockDeviceConfig, BlockDeviceFactory, CacheClearableFilesystem, Filesystem, FilesystemConfig,
12};
13
14#[derive(Clone)]
16pub struct Blobfs;
17
18#[async_trait]
19impl FilesystemConfig for Blobfs {
20 type Filesystem = BlobfsInstance;
21
22 async fn start_filesystem(
23 &self,
24 block_device_factory: &dyn BlockDeviceFactory,
25 ) -> BlobfsInstance {
26 let block_device = block_device_factory
27 .create_block_device(&BlockDeviceConfig {
28 requires_fvm: true,
29 use_zxcrypt: false,
30 volume_size: None,
31 })
32 .await;
33 let blobfs = FsManagementFilesystemInstance::new(
34 fs_management::Blobfs { ..Default::default() },
35 block_device,
36 None,
37 false,
38 )
39 .await;
40 let root = fuchsia_fs::directory::open_in_namespace(
41 blobfs.benchmark_dir().to_str().unwrap(),
42 fuchsia_fs::PERM_WRITABLE | fuchsia_fs::PERM_READABLE,
43 )
44 .unwrap();
45 BlobfsInstance { root, blobfs }
46 }
47
48 fn name(&self) -> String {
49 "blobfs".to_owned()
50 }
51}
52
53pub struct BlobfsInstance {
54 root: fio::DirectoryProxy,
55 blobfs: FsManagementFilesystemInstance,
56}
57
58#[async_trait]
59impl Filesystem for BlobfsInstance {
60 async fn shutdown(self) {
61 self.blobfs.shutdown().await
62 }
63
64 fn benchmark_dir(&self) -> &Path {
65 self.blobfs.benchmark_dir()
66 }
67}
68
69#[async_trait]
70impl CacheClearableFilesystem for BlobfsInstance {
71 async fn clear_cache(&mut self) {
72 let () = self.blobfs.clear_cache().await;
73 self.root = fuchsia_fs::directory::open_in_namespace(
74 self.blobfs.benchmark_dir().to_str().unwrap(),
75 fuchsia_fs::PERM_WRITABLE | fuchsia_fs::PERM_READABLE,
76 )
77 .unwrap();
78 }
79}
80
81#[async_trait]
82impl BlobFilesystem for BlobfsInstance {
83 async fn get_vmo(&self, blob: &DeliveryBlob) -> zx::Vmo {
84 let blob = fuchsia_fs::directory::open_file(
85 &self.root,
86 &delivery_blob_path(blob.name),
87 fuchsia_fs::PERM_READABLE,
88 )
89 .await
90 .unwrap();
91 blob.get_backing_memory(fio::VmoFlags::READ).await.unwrap().unwrap()
92 }
93
94 async fn write_blob(&self, blob: &DeliveryBlob) {
95 let blob_proxy = fuchsia_fs::directory::open_file(
96 &self.root,
97 &delivery_blob_path(blob.name),
98 fio::Flags::FLAG_MAYBE_CREATE | fio::PERM_WRITABLE,
99 )
100 .await
101 .unwrap();
102 let blob_size = blob.data.len();
103 blob_proxy.resize(blob_size as u64).await.unwrap().unwrap();
104 let mut written = 0;
105 while written != blob_size {
106 let bytes_to_write =
108 std::cmp::min(fio::MAX_TRANSFER_SIZE, (blob_size - written) as u64);
109 let bytes_written: u64 = blob_proxy
110 .write(&blob.data[written..written + bytes_to_write as usize])
111 .await
112 .unwrap()
113 .unwrap();
114 assert_eq!(bytes_written, bytes_to_write);
115 written += bytes_written as usize;
116 }
117 }
118
119 fn exposed_dir(&self) -> &fio::DirectoryProxy {
120 self.blobfs.exposed_dir()
121 }
122}
123
124#[cfg(test)]
125mod tests {
126 use super::Blobfs;
127 use crate::filesystems::testing::check_blob_filesystem;
128
129 #[fuchsia::test]
130 async fn start_blobfs() {
131 check_blob_filesystem(Blobfs).await;
132 }
133}