1mod error;
13pub mod filesystem;
14pub mod format;
15pub mod partition;
16
17use crate::filesystem::BlockConnector;
18use fidl_fuchsia_fs_startup::{FormatOptions, StartOptions};
19use std::sync::Arc;
20
21pub use error::{QueryError, ShutdownError};
23
24pub const BLOBFS_TYPE_GUID: [u8; 16] = [
25 0x0e, 0x38, 0x67, 0x29, 0x4c, 0x13, 0xbb, 0x4c, 0xb6, 0xda, 0x17, 0xe7, 0xce, 0x1c, 0xa4, 0x5d,
26];
27pub const DATA_TYPE_GUID: [u8; 16] = [
28 0x0c, 0x5f, 0x18, 0x08, 0x2d, 0x89, 0x8a, 0x42, 0xa7, 0x89, 0xdb, 0xee, 0xc8, 0xf5, 0x5e, 0x6a,
29];
30pub const FVM_TYPE_GUID: [u8; 16] = [
31 0xb8, 0x7c, 0xfd, 0x49, 0x15, 0xdf, 0x73, 0x4e, 0xb9, 0xd9, 0x99, 0x20, 0x70, 0x12, 0x7f, 0x0f,
32];
33
34pub const FVM_TYPE_GUID_STR: &str = "49fd7cb8-df15-4e73-b9d9-992070127f0f";
35
36pub const FS_COLLECTION_NAME: &'static str = "fs-collection";
37
38#[derive(Clone)]
39pub enum ComponentType {
40 StaticChild,
43
44 DynamicChild { collection_name: String },
47}
48
49impl Default for ComponentType {
50 fn default() -> Self {
51 ComponentType::DynamicChild { collection_name: "fs-collection".to_string() }
52 }
53}
54
55pub struct Options<'a> {
56 pub component_name: &'a str,
62
63 pub reuse_component_after_serving: bool,
66
67 pub format_options: FormatOptions,
69
70 pub start_options: StartOptions,
72
73 pub component_type: ComponentType,
75}
76
77pub trait FSConfig: Send + Sync + 'static {
79 fn options(&self) -> Options<'_>;
81
82 fn is_multi_volume(&self) -> bool {
84 false
85 }
86
87 fn disk_format(&self) -> format::DiskFormat {
88 format::DiskFormat::Unknown
89 }
90}
91
92#[derive(Clone)]
98pub enum BlobLayout {
99 DeprecatedPadded,
102
103 Compact,
105}
106
107#[derive(Clone, Default)]
110pub struct Blobfs {
111 pub verbose: bool,
113 pub deprecated_padded_blobfs_format: bool,
114 pub num_inodes: u64,
115 pub readonly: bool,
117 pub component_type: ComponentType,
118}
119
120impl Blobfs {
121 pub fn new<B: BlockConnector + 'static>(block_connector: B) -> filesystem::Filesystem {
123 filesystem::Filesystem::new(block_connector, Self::default())
124 }
125
126 pub fn dynamic_child() -> Self {
128 Self {
129 component_type: ComponentType::DynamicChild {
130 collection_name: FS_COLLECTION_NAME.to_string(),
131 },
132 ..Default::default()
133 }
134 }
135}
136
137impl FSConfig for Blobfs {
138 fn options(&self) -> Options<'_> {
139 Options {
140 component_name: "blobfs",
141 reuse_component_after_serving: false,
142 format_options: FormatOptions {
143 verbose: Some(self.verbose),
144 deprecated_padded_blobfs_format: Some(self.deprecated_padded_blobfs_format),
145 num_inodes: if self.num_inodes > 0 { Some(self.num_inodes) } else { None },
146 ..Default::default()
147 },
148 start_options: {
149 StartOptions {
150 read_only: Some(self.readonly),
151 verbose: Some(self.verbose),
152 ..Default::default()
153 }
154 },
155 component_type: self.component_type.clone(),
156 }
157 }
158
159 fn disk_format(&self) -> format::DiskFormat {
160 format::DiskFormat::Blobfs
161 }
162}
163
164#[derive(Clone, Default)]
167pub struct Minfs {
168 pub verbose: bool,
171 pub fvm_data_slices: u32,
172 pub readonly: bool,
174 pub fsck_after_every_transaction: bool,
175 pub component_type: ComponentType,
176}
177
178impl Minfs {
179 pub fn new<B: BlockConnector + 'static>(block_connector: B) -> filesystem::Filesystem {
181 filesystem::Filesystem::new(block_connector, Self::default())
182 }
183
184 pub fn dynamic_child() -> Self {
186 Self {
187 component_type: ComponentType::DynamicChild {
188 collection_name: FS_COLLECTION_NAME.to_string(),
189 },
190 ..Default::default()
191 }
192 }
193}
194
195impl FSConfig for Minfs {
196 fn options(&self) -> Options<'_> {
197 Options {
198 component_name: "minfs",
199 reuse_component_after_serving: false,
200 format_options: FormatOptions {
201 verbose: Some(self.verbose),
202 fvm_data_slices: Some(self.fvm_data_slices),
203 ..Default::default()
204 },
205 start_options: StartOptions {
206 read_only: Some(self.readonly),
207 verbose: Some(self.verbose),
208 fsck_after_every_transaction: Some(self.fsck_after_every_transaction),
209 ..Default::default()
210 },
211 component_type: self.component_type.clone(),
212 }
213 }
214
215 fn disk_format(&self) -> format::DiskFormat {
216 format::DiskFormat::Minfs
217 }
218}
219
220pub type CryptClientFn = Arc<dyn Fn() -> zx::Channel + Send + Sync>;
221
222#[derive(Clone)]
224pub struct Fxfs {
225 pub readonly: bool,
227 pub fsck_after_every_transaction: bool,
228 pub component_type: ComponentType,
229 pub startup_profiling_seconds: Option<u32>,
230 pub inline_crypto_enabled: bool,
231 pub barriers_enabled: bool,
232 pub allow_type3_blobs: bool,
233}
234
235impl Default for Fxfs {
236 fn default() -> Self {
237 Self {
238 readonly: false,
239 fsck_after_every_transaction: false,
240 component_type: Default::default(),
241 startup_profiling_seconds: None,
242 inline_crypto_enabled: false,
243 barriers_enabled: false,
244 allow_type3_blobs: false,
245 }
246 }
247}
248
249impl Fxfs {
250 pub fn new<B: BlockConnector + 'static>(block_connector: B) -> filesystem::Filesystem {
252 filesystem::Filesystem::new(block_connector, Self::default())
253 }
254
255 pub fn dynamic_child() -> Self {
257 Self {
258 component_type: ComponentType::DynamicChild {
259 collection_name: FS_COLLECTION_NAME.to_string(),
260 },
261 ..Default::default()
262 }
263 }
264}
265
266impl FSConfig for Fxfs {
267 fn options(&self) -> Options<'_> {
268 Options {
269 component_name: "fxfs",
270 reuse_component_after_serving: true,
271 format_options: FormatOptions { verbose: Some(false), ..Default::default() },
272 start_options: StartOptions {
273 read_only: Some(self.readonly),
274 fsck_after_every_transaction: Some(self.fsck_after_every_transaction),
275 startup_profiling_seconds: Some(self.startup_profiling_seconds.unwrap_or(0)),
276 inline_crypto_enabled: Some(self.inline_crypto_enabled),
277 barriers_enabled: Some(self.barriers_enabled),
278 allow_type3_blobs: Some(self.allow_type3_blobs),
279 ..Default::default()
280 },
281 component_type: self.component_type.clone(),
282 }
283 }
284
285 fn is_multi_volume(&self) -> bool {
286 true
287 }
288
289 fn disk_format(&self) -> format::DiskFormat {
290 format::DiskFormat::Fxfs
291 }
292}
293
294#[derive(Clone, Default)]
297pub struct F2fs {
298 pub component_type: ComponentType,
299}
300
301impl F2fs {
302 pub fn new<B: BlockConnector + 'static>(block_connector: B) -> filesystem::Filesystem {
304 filesystem::Filesystem::new(block_connector, Self::default())
305 }
306
307 pub fn dynamic_child() -> Self {
309 Self {
310 component_type: ComponentType::DynamicChild {
311 collection_name: FS_COLLECTION_NAME.to_string(),
312 },
313 ..Default::default()
314 }
315 }
316}
317
318impl FSConfig for F2fs {
319 fn options(&self) -> Options<'_> {
320 Options {
321 component_name: "f2fs",
322 reuse_component_after_serving: false,
323 format_options: FormatOptions::default(),
324 start_options: StartOptions {
325 read_only: Some(false),
326 verbose: Some(false),
327 fsck_after_every_transaction: Some(false),
328 ..Default::default()
329 },
330 component_type: self.component_type.clone(),
331 }
332 }
333 fn is_multi_volume(&self) -> bool {
334 false
335 }
336
337 fn disk_format(&self) -> format::DiskFormat {
338 format::DiskFormat::F2fs
339 }
340}
341
342#[derive(Clone, Default)]
344pub struct Fvm {
345 pub component_type: ComponentType,
346 pub slice_size: u64,
347}
348
349impl Fvm {
350 pub fn new<B: BlockConnector + 'static>(block_connector: B) -> filesystem::Filesystem {
352 filesystem::Filesystem::new(block_connector, Self::default())
353 }
354
355 pub fn dynamic_child() -> Self {
357 Self {
358 component_type: ComponentType::DynamicChild {
359 collection_name: FS_COLLECTION_NAME.to_string(),
360 },
361 ..Default::default()
362 }
363 }
364}
365
366impl FSConfig for Fvm {
367 fn options(&self) -> Options<'_> {
368 Options {
369 component_name: "fvm2",
370 reuse_component_after_serving: true,
371 format_options: FormatOptions {
372 fvm_slice_size: if self.slice_size > 0 { Some(self.slice_size) } else { None },
373 ..FormatOptions::default()
374 },
375 start_options: StartOptions::default(),
376 component_type: self.component_type.clone(),
377 }
378 }
379
380 fn is_multi_volume(&self) -> bool {
381 true
382 }
383
384 fn disk_format(&self) -> format::DiskFormat {
385 format::DiskFormat::Fvm
386 }
387}
388
389#[derive(Clone)]
391pub struct Gpt {
392 pub component_type: ComponentType,
393 pub merge_super_and_userdata: bool,
394}
395
396impl Default for Gpt {
397 fn default() -> Self {
398 Self { component_type: Default::default(), merge_super_and_userdata: false }
399 }
400}
401
402impl Gpt {
403 pub fn new<B: BlockConnector + 'static>(block_connector: B) -> filesystem::Filesystem {
405 filesystem::Filesystem::new(block_connector, Self::default())
406 }
407
408 pub fn dynamic_child() -> Self {
410 Self {
411 component_type: ComponentType::DynamicChild {
412 collection_name: FS_COLLECTION_NAME.to_string(),
413 },
414 ..Default::default()
415 }
416 }
417}
418
419impl FSConfig for Gpt {
420 fn options(&self) -> Options<'_> {
421 Options {
422 component_name: "gpt2",
423 reuse_component_after_serving: true,
424 format_options: FormatOptions::default(),
425 start_options: StartOptions {
426 merge_super_and_userdata: Some(self.merge_super_and_userdata),
427 ..Default::default()
428 },
429 component_type: self.component_type.clone(),
430 }
431 }
432
433 fn is_multi_volume(&self) -> bool {
434 true
435 }
436
437 fn disk_format(&self) -> format::DiskFormat {
438 format::DiskFormat::Gpt
439 }
440}