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:
@@ -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");
|
||||||
|
|||||||
Reference in New Issue
Block a user