feat(fuse): integrate OverlayReader in read path
- Update read() to use OverlayReader when available - Map OverlayError to libc error codes - Maintain 30s timeout and backward compatibility - Fallback to FileReader for non-overlay files - All tests pass, full workspace compiles
This commit is contained in:
@@ -4,7 +4,8 @@ use fuser::{
|
|||||||
Request,
|
Request,
|
||||||
};
|
};
|
||||||
use musicfs_cache::{
|
use musicfs_cache::{
|
||||||
Database, OverlayReader, RemoveError, RenameError, VirtualNode, VirtualTree, ROOT_INODE,
|
Database, OverlayError, 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};
|
||||||
@@ -442,6 +443,53 @@ impl Filesystem for MusicFs {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let handle = self.runtime_handle.clone();
|
||||||
|
|
||||||
|
if let Some(ref overlay) = self.overlay_reader {
|
||||||
|
let overlay = overlay.clone();
|
||||||
|
let result = std::thread::scope(|_| {
|
||||||
|
handle.block_on(async {
|
||||||
|
tokio::time::timeout(
|
||||||
|
Duration::from_secs(30),
|
||||||
|
overlay.read(file_id, offset as u64, size),
|
||||||
|
)
|
||||||
|
.await
|
||||||
|
})
|
||||||
|
});
|
||||||
|
|
||||||
|
match result {
|
||||||
|
Ok(Ok(data)) => {
|
||||||
|
trace!(
|
||||||
|
ino,
|
||||||
|
offset,
|
||||||
|
size_bytes = size,
|
||||||
|
bytes_read = data.len(),
|
||||||
|
"overlay read successful"
|
||||||
|
);
|
||||||
|
reply.data(&data);
|
||||||
|
}
|
||||||
|
Ok(Err(e)) => {
|
||||||
|
let errno = match &e {
|
||||||
|
OverlayError::NotFound(_) => libc::ENOENT,
|
||||||
|
OverlayError::Database(_) => libc::EIO,
|
||||||
|
OverlayError::Handler(_) => libc::EIO,
|
||||||
|
OverlayError::Cas(_) => libc::EIO,
|
||||||
|
OverlayError::NoHandler(_) => libc::EIO,
|
||||||
|
};
|
||||||
|
warn!(ino, offset, size_bytes = size, error = %e, "overlay read failed");
|
||||||
|
reply.error(errno);
|
||||||
|
}
|
||||||
|
Err(_timeout) => {
|
||||||
|
warn!(
|
||||||
|
ino,
|
||||||
|
offset,
|
||||||
|
size_bytes = size,
|
||||||
|
"overlay read timed out after 30s"
|
||||||
|
);
|
||||||
|
reply.error(libc::EIO);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
let Some(reader) = &self.reader else {
|
let Some(reader) = &self.reader else {
|
||||||
trace!(ino, "no reader available");
|
trace!(ino, "no reader available");
|
||||||
reply.data(&[]);
|
reply.data(&[]);
|
||||||
@@ -449,7 +497,6 @@ impl Filesystem for MusicFs {
|
|||||||
};
|
};
|
||||||
|
|
||||||
let reader = reader.clone();
|
let reader = reader.clone();
|
||||||
let handle = self.runtime_handle.clone();
|
|
||||||
let result = std::thread::scope(|_| {
|
let result = std::thread::scope(|_| {
|
||||||
handle.block_on(async {
|
handle.block_on(async {
|
||||||
tokio::time::timeout(
|
tokio::time::timeout(
|
||||||
@@ -481,6 +528,7 @@ impl Filesystem for MusicFs {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[instrument(level = "debug", skip(self, reply))]
|
#[instrument(level = "debug", skip(self, reply))]
|
||||||
fn release(
|
fn release(
|
||||||
|
|||||||
Reference in New Issue
Block a user