pub mod cache;
pub mod dispatcher;
pub mod error;
pub mod fuse;
pub mod passthrough;
pub mod server;
pub use cache::{
AdaptiveTtlConfig, NegativeCache, NegativeCacheConfig, NegativeCacheStats, TtlRule,
};
pub use dispatcher::{DispatcherConfig, FuseDispatcher, RequestContext, ResponseBuilder};
pub use error::{FsError, Result};
pub use fuse::{FuseAttr, FuseInHeader, FuseOpcode, FuseOutHeader, StatFs};
pub use passthrough::{DirEntry, FileType, PassthroughConfig, PassthroughFs};
pub use server::FsServer;
pub trait DaxMapper: Send + Sync {
fn setup_mapping(
&self,
host_fd: i32,
file_offset: u64,
window_offset: u64,
length: u64,
writable: bool,
) -> std::result::Result<(), i32>;
fn remove_mapping(&self, window_offset: u64, length: u64) -> std::result::Result<(), i32>;
}
#[derive(Debug, Clone)]
pub enum CacheProfile {
Static,
Dynamic,
Custom {
entry_timeout_secs: u64,
attr_timeout_secs: u64,
},
}
impl CacheProfile {
#[must_use]
pub fn entry_timeout(&self) -> std::time::Duration {
match self {
Self::Static => std::time::Duration::from_secs(300),
Self::Dynamic => std::time::Duration::from_secs(1),
Self::Custom {
entry_timeout_secs, ..
} => std::time::Duration::from_secs(*entry_timeout_secs),
}
}
#[must_use]
pub fn attr_timeout(&self) -> std::time::Duration {
match self {
Self::Static => std::time::Duration::from_secs(300),
Self::Dynamic => std::time::Duration::from_secs(1),
Self::Custom {
attr_timeout_secs, ..
} => std::time::Duration::from_secs(*attr_timeout_secs),
}
}
}
#[derive(Debug, Clone)]
pub struct FsConfig {
pub tag: String,
pub source: String,
pub num_threads: usize,
pub writeback_cache: bool,
pub cache_profile: CacheProfile,
pub cache_timeout: u64,
pub negative_cache_ttl: u64,
}
impl Default for FsConfig {
fn default() -> Self {
Self {
tag: "arcbox".to_string(),
source: String::new(),
num_threads: 4,
writeback_cache: true,
cache_profile: CacheProfile::Custom {
entry_timeout_secs: 10,
attr_timeout_secs: 10,
},
cache_timeout: 10,
negative_cache_ttl: 5,
}
}
}
#[cfg(test)]
mod tests {
use super::*;
use std::time::Duration;
#[test]
fn test_cache_profile_static() {
let profile = CacheProfile::Static;
assert_eq!(profile.entry_timeout(), Duration::from_secs(300));
assert_eq!(profile.attr_timeout(), Duration::from_secs(300));
}
#[test]
fn test_cache_profile_dynamic() {
let profile = CacheProfile::Dynamic;
assert_eq!(profile.entry_timeout(), Duration::from_secs(1));
assert_eq!(profile.attr_timeout(), Duration::from_secs(1));
}
#[test]
fn test_cache_profile_custom() {
let profile = CacheProfile::Custom {
entry_timeout_secs: 42,
attr_timeout_secs: 7,
};
assert_eq!(profile.entry_timeout(), Duration::from_secs(42));
assert_eq!(profile.attr_timeout(), Duration::from_secs(7));
}
#[test]
fn test_fs_config_default_uses_custom_profile() {
let config = FsConfig::default();
assert_eq!(
config.cache_profile.entry_timeout(),
Duration::from_secs(10)
);
assert_eq!(config.cache_profile.attr_timeout(), Duration::from_secs(10));
}
}