use std::ffi::OsString;
use std::fs::File;
use std::path::PathBuf;
use std::sync::atomic::{AtomicU64, Ordering};
use std::time::Duration;
#[derive(Debug)]
#[allow(dead_code)]
pub(super) struct InodeData {
pub(super) path: PathBuf,
pub(super) refcount: AtomicU64,
pub(super) file_type: FileType,
pub(super) kernel_ino: u64,
}
impl InodeData {
pub(super) fn new(path: PathBuf, file_type: FileType, kernel_ino: u64) -> Self {
Self {
path,
refcount: AtomicU64::new(1),
file_type,
kernel_ino,
}
}
pub(super) fn inc_ref(&self) {
self.refcount.fetch_add(1, Ordering::Relaxed);
}
pub(super) fn dec_ref(&self) -> u64 {
self.refcount.fetch_sub(1, Ordering::Relaxed)
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum FileType {
Regular,
Directory,
Symlink,
BlockDevice,
CharDevice,
Fifo,
Socket,
Unknown,
}
impl FileType {
pub(super) fn from_mode(mode: u32) -> Self {
let file_type = mode & u32::from(libc::S_IFMT);
if file_type == u32::from(libc::S_IFREG) {
Self::Regular
} else if file_type == u32::from(libc::S_IFDIR) {
Self::Directory
} else if file_type == u32::from(libc::S_IFLNK) {
Self::Symlink
} else if file_type == u32::from(libc::S_IFBLK) {
Self::BlockDevice
} else if file_type == u32::from(libc::S_IFCHR) {
Self::CharDevice
} else if file_type == u32::from(libc::S_IFIFO) {
Self::Fifo
} else if file_type == u32::from(libc::S_IFSOCK) {
Self::Socket
} else {
Self::Unknown
}
}
#[allow(dead_code)]
fn is_dir(self) -> bool {
self == Self::Directory
}
#[must_use]
pub fn to_dirent_type(self) -> u32 {
match self {
Self::Regular => libc::DT_REG as u32,
Self::Directory => libc::DT_DIR as u32,
Self::Symlink => libc::DT_LNK as u32,
Self::BlockDevice => libc::DT_BLK as u32,
Self::CharDevice => libc::DT_CHR as u32,
Self::Fifo => libc::DT_FIFO as u32,
Self::Socket => libc::DT_SOCK as u32,
Self::Unknown => libc::DT_UNKNOWN as u32,
}
}
}
#[derive(Debug)]
#[allow(dead_code)]
pub(super) struct HandleData {
pub(super) file: File,
pub(super) inode: u64,
pub(super) flags: u32,
}
#[derive(Debug)]
pub(super) struct DirHandleData {
pub(super) inode: u64,
pub(super) entries: Vec<DirEntry>,
}
#[derive(Debug, Clone)]
pub struct DirEntry {
pub name: OsString,
pub ino: u64,
pub file_type: FileType,
}
#[derive(Debug, Clone)]
pub struct PassthroughConfig {
pub negative_cache_enabled: bool,
pub negative_cache_max_entries: usize,
pub negative_cache_timeout: Duration,
}
impl Default for PassthroughConfig {
fn default() -> Self {
Self::new()
}
}
impl PassthroughConfig {
#[must_use]
pub const fn new() -> Self {
Self {
negative_cache_enabled: true,
negative_cache_max_entries: 10_000,
negative_cache_timeout: Duration::from_secs(5),
}
}
}