mod error;
pub mod filesystem;
pub mod format;
pub mod partition;
use fidl_fuchsia_fs_startup::{
CompressionAlgorithm, EvictionPolicyOverride, FormatOptions, StartOptions,
};
use std::convert::From;
use std::sync::Arc;
pub use error::{QueryError, ShutdownError};
pub const BLOBFS_TYPE_GUID: [u8; 16] = [
0x0e, 0x38, 0x67, 0x29, 0x4c, 0x13, 0xbb, 0x4c, 0xb6, 0xda, 0x17, 0xe7, 0xce, 0x1c, 0xa4, 0x5d,
];
pub const DATA_TYPE_GUID: [u8; 16] = [
0x0c, 0x5f, 0x18, 0x08, 0x2d, 0x89, 0x8a, 0x42, 0xa7, 0x89, 0xdb, 0xee, 0xc8, 0xf5, 0x5e, 0x6a,
];
pub const FVM_TYPE_GUID: [u8; 16] = [
0xb8, 0x7c, 0xfd, 0x49, 0x15, 0xdf, 0x73, 0x4e, 0xb9, 0xd9, 0x99, 0x20, 0x70, 0x12, 0x7f, 0x0f,
];
pub const FVM_TYPE_GUID_STR: &str = "49fd7cb8-df15-4e73-b9d9-992070127f0f";
pub const FS_COLLECTION_NAME: &'static str = "fs-collection";
#[derive(Clone)]
pub enum ComponentType {
StaticChild,
DynamicChild { collection_name: String },
}
impl Default for ComponentType {
fn default() -> Self {
ComponentType::DynamicChild { collection_name: "fs-collection".to_string() }
}
}
pub struct Options<'a> {
pub component_name: &'a str,
pub reuse_component_after_serving: bool,
pub format_options: FormatOptions,
pub start_options: StartOptions,
pub component_type: ComponentType,
}
pub trait FSConfig: Send + Sync + 'static {
fn options(&self) -> Options<'_>;
fn is_multi_volume(&self) -> bool {
false
}
fn disk_format(&self) -> format::DiskFormat {
format::DiskFormat::Unknown
}
}
#[derive(Clone)]
pub enum BlobLayout {
DeprecatedPadded,
Compact,
}
#[derive(Clone, Default)]
pub enum BlobCompression {
#[default]
ZSTDChunked,
Uncompressed,
}
impl From<&str> for BlobCompression {
fn from(value: &str) -> Self {
match value {
"zstd_chunked" => Self::ZSTDChunked,
"uncompressed" => Self::Uncompressed,
_ => Default::default(),
}
}
}
#[derive(Clone, Default)]
pub enum BlobEvictionPolicy {
#[default]
NeverEvict,
EvictImmediately,
}
impl From<&str> for BlobEvictionPolicy {
fn from(value: &str) -> Self {
match value {
"never_evict" => Self::NeverEvict,
"evict_immediately" => Self::EvictImmediately,
_ => Default::default(),
}
}
}
#[derive(Clone, Default)]
pub struct Blobfs {
pub verbose: bool,
pub deprecated_padded_blobfs_format: bool,
pub num_inodes: u64,
pub readonly: bool,
pub write_compression_algorithm: BlobCompression,
pub write_compression_level: Option<i32>,
pub cache_eviction_policy_override: BlobEvictionPolicy,
pub component_type: ComponentType,
}
impl Blobfs {
pub fn new(block_device: fidl_fuchsia_device::ControllerProxy) -> filesystem::Filesystem {
filesystem::Filesystem::new(block_device, Self::default())
}
pub fn dynamic_child() -> Self {
Self {
component_type: ComponentType::DynamicChild {
collection_name: FS_COLLECTION_NAME.to_string(),
},
..Default::default()
}
}
}
impl FSConfig for Blobfs {
fn options(&self) -> Options<'_> {
Options {
component_name: "blobfs",
reuse_component_after_serving: false,
format_options: FormatOptions {
verbose: Some(self.verbose),
deprecated_padded_blobfs_format: Some(self.deprecated_padded_blobfs_format),
num_inodes: if self.num_inodes > 0 { Some(self.num_inodes) } else { None },
..Default::default()
},
start_options: {
let mut start_options = StartOptions {
read_only: self.readonly,
verbose: self.verbose,
fsck_after_every_transaction: false,
write_compression_level: self.write_compression_level.unwrap_or(-1),
write_compression_algorithm: CompressionAlgorithm::ZstdChunked,
cache_eviction_policy_override: EvictionPolicyOverride::None,
startup_profiling_seconds: 0,
};
start_options.write_compression_algorithm = match &self.write_compression_algorithm
{
BlobCompression::ZSTDChunked => CompressionAlgorithm::ZstdChunked,
BlobCompression::Uncompressed => CompressionAlgorithm::Uncompressed,
};
start_options.cache_eviction_policy_override =
match &self.cache_eviction_policy_override {
BlobEvictionPolicy::NeverEvict => EvictionPolicyOverride::NeverEvict,
BlobEvictionPolicy::EvictImmediately => {
EvictionPolicyOverride::EvictImmediately
}
};
start_options
},
component_type: self.component_type.clone(),
}
}
fn disk_format(&self) -> format::DiskFormat {
format::DiskFormat::Blobfs
}
}
#[derive(Clone, Default)]
pub struct Minfs {
pub verbose: bool,
pub fvm_data_slices: u32,
pub readonly: bool,
pub fsck_after_every_transaction: bool,
pub component_type: ComponentType,
}
impl Minfs {
pub fn new(block_device: fidl_fuchsia_device::ControllerProxy) -> filesystem::Filesystem {
filesystem::Filesystem::new(block_device, Self::default())
}
pub fn dynamic_child() -> Self {
Self {
component_type: ComponentType::DynamicChild {
collection_name: FS_COLLECTION_NAME.to_string(),
},
..Default::default()
}
}
}
impl FSConfig for Minfs {
fn options(&self) -> Options<'_> {
Options {
component_name: "minfs",
reuse_component_after_serving: false,
format_options: FormatOptions {
verbose: Some(self.verbose),
fvm_data_slices: Some(self.fvm_data_slices),
..Default::default()
},
start_options: StartOptions {
read_only: self.readonly,
verbose: self.verbose,
fsck_after_every_transaction: self.fsck_after_every_transaction,
write_compression_level: -1,
write_compression_algorithm: CompressionAlgorithm::ZstdChunked,
cache_eviction_policy_override: EvictionPolicyOverride::None,
startup_profiling_seconds: 0,
},
component_type: self.component_type.clone(),
}
}
fn disk_format(&self) -> format::DiskFormat {
format::DiskFormat::Minfs
}
}
pub type CryptClientFn = Arc<dyn Fn() -> zx::Channel + Send + Sync>;
#[derive(Clone)]
pub struct Fxfs {
pub readonly: bool,
pub fsck_after_every_transaction: bool,
pub component_type: ComponentType,
pub startup_profiling_seconds: Option<u32>,
}
impl Default for Fxfs {
fn default() -> Self {
Self {
readonly: false,
fsck_after_every_transaction: false,
component_type: Default::default(),
startup_profiling_seconds: None,
}
}
}
impl Fxfs {
pub fn new(block_device: fidl_fuchsia_device::ControllerProxy) -> filesystem::Filesystem {
filesystem::Filesystem::new(block_device, Self::default())
}
pub fn dynamic_child() -> Self {
Self {
component_type: ComponentType::DynamicChild {
collection_name: FS_COLLECTION_NAME.to_string(),
},
..Default::default()
}
}
}
impl FSConfig for Fxfs {
fn options(&self) -> Options<'_> {
Options {
component_name: "fxfs",
reuse_component_after_serving: true,
format_options: FormatOptions { verbose: Some(false), ..Default::default() },
start_options: StartOptions {
read_only: self.readonly,
verbose: false,
fsck_after_every_transaction: self.fsck_after_every_transaction,
write_compression_level: -1,
write_compression_algorithm: CompressionAlgorithm::ZstdChunked,
cache_eviction_policy_override: EvictionPolicyOverride::None,
startup_profiling_seconds: self.startup_profiling_seconds.unwrap_or(0),
},
component_type: self.component_type.clone(),
}
}
fn is_multi_volume(&self) -> bool {
true
}
fn disk_format(&self) -> format::DiskFormat {
format::DiskFormat::Fxfs
}
}
#[derive(Clone, Default)]
pub struct F2fs {
pub component_type: ComponentType,
}
impl F2fs {
pub fn new(block_device: fidl_fuchsia_device::ControllerProxy) -> filesystem::Filesystem {
filesystem::Filesystem::new(block_device, Self::default())
}
pub fn dynamic_child() -> Self {
Self {
component_type: ComponentType::DynamicChild {
collection_name: FS_COLLECTION_NAME.to_string(),
},
..Default::default()
}
}
}
impl FSConfig for F2fs {
fn options(&self) -> Options<'_> {
Options {
component_name: "f2fs",
reuse_component_after_serving: false,
format_options: FormatOptions::default(),
start_options: StartOptions {
read_only: false,
verbose: false,
fsck_after_every_transaction: false,
write_compression_level: -1,
write_compression_algorithm: CompressionAlgorithm::ZstdChunked,
cache_eviction_policy_override: EvictionPolicyOverride::None,
startup_profiling_seconds: 0,
},
component_type: self.component_type.clone(),
}
}
fn is_multi_volume(&self) -> bool {
false
}
fn disk_format(&self) -> format::DiskFormat {
format::DiskFormat::F2fs
}
}
#[derive(Clone)]
pub struct Fvm {
pub component_type: ComponentType,
}
impl Default for Fvm {
fn default() -> Self {
Self { component_type: Default::default() }
}
}
impl Fvm {
pub fn new(block_device: fidl_fuchsia_device::ControllerProxy) -> filesystem::Filesystem {
filesystem::Filesystem::new(block_device, Self::default())
}
pub fn dynamic_child() -> Self {
Self {
component_type: ComponentType::DynamicChild {
collection_name: FS_COLLECTION_NAME.to_string(),
},
..Default::default()
}
}
}
impl FSConfig for Fvm {
fn options(&self) -> Options<'_> {
Options {
component_name: "fvm",
reuse_component_after_serving: true,
format_options: FormatOptions::default(),
start_options: StartOptions {
read_only: false,
verbose: false,
fsck_after_every_transaction: false,
write_compression_level: -1,
write_compression_algorithm: CompressionAlgorithm::ZstdChunked,
cache_eviction_policy_override: EvictionPolicyOverride::None,
startup_profiling_seconds: 0,
},
component_type: self.component_type.clone(),
}
}
fn is_multi_volume(&self) -> bool {
true
}
fn disk_format(&self) -> format::DiskFormat {
format::DiskFormat::Fvm
}
}
#[derive(Clone)]
pub struct Gpt {
pub component_type: ComponentType,
}
impl Default for Gpt {
fn default() -> Self {
Self { component_type: Default::default() }
}
}
impl Gpt {
pub fn new(block_device: fidl_fuchsia_device::ControllerProxy) -> filesystem::Filesystem {
filesystem::Filesystem::new(block_device, Self::default())
}
pub fn dynamic_child() -> Self {
Self {
component_type: ComponentType::DynamicChild {
collection_name: FS_COLLECTION_NAME.to_string(),
},
..Default::default()
}
}
}
impl FSConfig for Gpt {
fn options(&self) -> Options<'_> {
Options {
component_name: "storage-host",
reuse_component_after_serving: true,
format_options: FormatOptions::default(),
start_options: StartOptions {
read_only: false,
verbose: false,
fsck_after_every_transaction: false,
write_compression_level: -1,
write_compression_algorithm: CompressionAlgorithm::ZstdChunked,
cache_eviction_policy_override: EvictionPolicyOverride::None,
startup_profiling_seconds: 0,
},
component_type: self.component_type.clone(),
}
}
fn is_multi_volume(&self) -> bool {
true
}
fn disk_format(&self) -> format::DiskFormat {
format::DiskFormat::Gpt
}
}