feat(fuse): return virtual size in getattr for overlay files

- Add overlay_reader field to MusicFs struct
- Add with_overlay() builder method
- Update getattr() to call estimate_virtual_size()
- Graceful fallback to original size
- All tests pass, backward compatible
This commit is contained in:
Alexander
2026-05-17 17:41:50 +02:00
parent c826bcf35f
commit 487b119935
+32 -2
View File
@@ -3,7 +3,9 @@ use fuser::{
FileAttr, FileType, Filesystem, ReplyAttr, ReplyData, ReplyDirectory, ReplyEntry, ReplyOpen, FileAttr, FileType, Filesystem, ReplyAttr, ReplyData, ReplyDirectory, ReplyEntry, ReplyOpen,
Request, 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_cas::FileReader;
use musicfs_core::{Result, VirtualPath}; use musicfs_core::{Result, VirtualPath};
use parking_lot::RwLock; use parking_lot::RwLock;
@@ -23,6 +25,7 @@ pub struct MusicFs {
tree: Arc<RwLock<VirtualTree>>, tree: Arc<RwLock<VirtualTree>>,
reader: Option<Arc<FileReader>>, reader: Option<Arc<FileReader>>,
db: Option<Arc<Database>>, db: Option<Arc<Database>>,
overlay_reader: Option<Arc<OverlayReader>>,
runtime_handle: Handle, runtime_handle: Handle,
search_ops: Option<SearchOps>, search_ops: Option<SearchOps>,
query_inodes: RwLock<HashMap<String, u64>>, query_inodes: RwLock<HashMap<String, u64>>,
@@ -38,6 +41,7 @@ impl MusicFs {
tree, tree,
reader: None, reader: None,
db: None, db: None,
overlay_reader: None,
runtime_handle, runtime_handle,
search_ops: None, search_ops: None,
query_inodes: RwLock::new(HashMap::new()), query_inodes: RwLock::new(HashMap::new()),
@@ -57,6 +61,7 @@ impl MusicFs {
tree, tree,
reader: Some(reader), reader: Some(reader),
db: None, db: None,
overlay_reader: None,
runtime_handle, runtime_handle,
search_ops: None, search_ops: None,
query_inodes: RwLock::new(HashMap::new()), query_inodes: RwLock::new(HashMap::new()),
@@ -72,6 +77,11 @@ impl MusicFs {
self self
} }
pub fn with_overlay(mut self, overlay: Arc<OverlayReader>) -> Self {
self.overlay_reader = Some(overlay);
self
}
pub fn with_search(mut self, search_ops: SearchOps) -> Self { pub fn with_search(mut self, search_ops: SearchOps) -> Self {
self.search_ops = Some(search_ops); self.search_ops = Some(search_ops);
self self
@@ -282,7 +292,27 @@ impl Filesystem for MusicFs {
if let Some(node) = tree.get(ino) { if let Some(node) = tree.get(ino) {
trace!(ino, "inode found in tree"); 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); reply.attr(&TTL, &attr);
} else { } else {
trace!(ino, "inode not found"); trace!(ino, "inode not found");