diff --git a/crates/musicfs-fuse/src/filesystem.rs b/crates/musicfs-fuse/src/filesystem.rs index b048820..137354b 100644 --- a/crates/musicfs-fuse/src/filesystem.rs +++ b/crates/musicfs-fuse/src/filesystem.rs @@ -3,7 +3,9 @@ use fuser::{ FileAttr, FileType, Filesystem, ReplyAttr, ReplyData, ReplyDirectory, ReplyEntry, ReplyOpen, Request, }; -use musicfs_cache::{Database, RemoveError, RenameError, VirtualNode, VirtualTree, ROOT_INODE}; +use musicfs_cache::{ + Database, OverlayReader, RemoveError, RenameError, VirtualNode, VirtualTree, ROOT_INODE, +}; use musicfs_cas::FileReader; use musicfs_core::{Result, VirtualPath}; use parking_lot::RwLock; @@ -23,6 +25,7 @@ pub struct MusicFs { tree: Arc>, reader: Option>, db: Option>, + overlay_reader: Option>, runtime_handle: Handle, search_ops: Option, query_inodes: RwLock>, @@ -38,6 +41,7 @@ impl MusicFs { tree, reader: None, db: None, + overlay_reader: None, runtime_handle, search_ops: None, query_inodes: RwLock::new(HashMap::new()), @@ -57,6 +61,7 @@ impl MusicFs { tree, reader: Some(reader), db: None, + overlay_reader: None, runtime_handle, search_ops: None, query_inodes: RwLock::new(HashMap::new()), @@ -72,6 +77,11 @@ impl MusicFs { self } + pub fn with_overlay(mut self, overlay: Arc) -> Self { + self.overlay_reader = Some(overlay); + self + } + pub fn with_search(mut self, search_ops: SearchOps) -> Self { self.search_ops = Some(search_ops); self @@ -282,7 +292,27 @@ impl Filesystem for MusicFs { if let Some(node) = tree.get(ino) { trace!(ino, "inode found in tree"); - let attr = self.node_to_attr(node); + let mut attr = self.node_to_attr(node); + + if let VirtualNode::File(file) = node { + if let Some(ref overlay) = self.overlay_reader { + match overlay.estimate_virtual_size(file.file_id) { + Ok(Some(virtual_size)) => { + trace!(ino, file_id = ?file.file_id, virtual_size, "using overlay virtual size"); + attr.size = virtual_size; + attr.blocks = + (virtual_size + BLOCK_SIZE as u64 - 1) / BLOCK_SIZE as u64; + } + Ok(None) => { + trace!(ino, file_id = ?file.file_id, "no overlay, using original size"); + } + Err(e) => { + warn!(ino, file_id = ?file.file_id, error = %e, "overlay size estimation failed, using original"); + } + } + } + } + reply.attr(&TTL, &attr); } else { trace!(ino, "inode not found");