pxar::fuse: Get rid of broken cacheing
Remove the current caching of attrs and goodbye tables as it is broken anyway. This will be replaced with a LRU cache. Signed-off-by: Christian Ebner <c.ebner@proxmox.com>
This commit is contained in:
parent
6d20a29d73
commit
caa201d895
|
@ -32,7 +32,6 @@ const FUSE_ROOT_ID: u64 = 1;
|
||||||
|
|
||||||
const GOODBYE_ITEM_SIZE: u64 = std::mem::size_of::<PxarGoodbyeItem>() as u64;
|
const GOODBYE_ITEM_SIZE: u64 = std::mem::size_of::<PxarGoodbyeItem>() as u64;
|
||||||
|
|
||||||
type Inode = u64;
|
|
||||||
type Offset = u64;
|
type Offset = u64;
|
||||||
/// FFI types for easier readability
|
/// FFI types for easier readability
|
||||||
type Request = *mut c_void;
|
type Request = *mut c_void;
|
||||||
|
@ -77,8 +76,6 @@ struct FuseArgs {
|
||||||
/// offset within the archive for the i-node given by the caller.
|
/// offset within the archive for the i-node given by the caller.
|
||||||
struct Context {
|
struct Context {
|
||||||
decoder: Decoder,
|
decoder: Decoder,
|
||||||
goodbye_cache: HashMap<Inode, Vec<(PxarGoodbyeItem, Offset, Offset)>>,
|
|
||||||
attr_cache: Option<(Inode, PxarAttributes)>,
|
|
||||||
ino_offset: Offset,
|
ino_offset: Offset,
|
||||||
/// HashMap holding the mapping from the child offsets to their parent
|
/// HashMap holding the mapping from the child offsets to their parent
|
||||||
/// offsets.
|
/// offsets.
|
||||||
|
@ -109,8 +106,9 @@ impl Context {
|
||||||
filename: &CStr,
|
filename: &CStr,
|
||||||
hash: u64,
|
hash: u64,
|
||||||
) -> Result<(u64, PxarEntry, PxarAttributes, u64), i32> {
|
) -> Result<(u64, PxarEntry, PxarAttributes, u64), i32> {
|
||||||
let gbt = self.goodbye_cache.get(&self.ino_offset)
|
let gbt = self.decoder
|
||||||
.ok_or_else(|| libc::EIO)?;
|
.goodbye_table(None, self.ino_offset + GOODBYE_ITEM_SIZE)
|
||||||
|
.map_err(|_| libc::EIO)?;
|
||||||
let mut start_idx = 0;
|
let mut start_idx = 0;
|
||||||
let mut skip_multiple = 0;
|
let mut skip_multiple = 0;
|
||||||
loop {
|
loop {
|
||||||
|
@ -228,23 +226,12 @@ impl Session {
|
||||||
/// default signal handlers.
|
/// default signal handlers.
|
||||||
/// Options have to be provided as comma separated OsStr, e.g.
|
/// Options have to be provided as comma separated OsStr, e.g.
|
||||||
/// ("ro,default_permissions").
|
/// ("ro,default_permissions").
|
||||||
pub fn new(
|
pub fn new(decoder: Decoder, options: &OsStr, verbose: bool) -> Result<Self, Error> {
|
||||||
mut decoder: Decoder,
|
|
||||||
options: &OsStr,
|
|
||||||
verbose: bool,
|
|
||||||
) -> Result<Self, Error> {
|
|
||||||
let args = Self::setup_args(options, verbose)?;
|
let args = Self::setup_args(options, verbose)?;
|
||||||
let oprs = Self::setup_callbacks();
|
let oprs = Self::setup_callbacks();
|
||||||
|
|
||||||
let root_ino_offset = decoder.root_end_offset() - GOODBYE_ITEM_SIZE;
|
|
||||||
let root_goodbye_table = decoder.goodbye_table(None, root_ino_offset + GOODBYE_ITEM_SIZE)?;
|
|
||||||
let mut goodbye_cache = HashMap::new();
|
|
||||||
goodbye_cache.insert(root_ino_offset, root_goodbye_table);
|
|
||||||
|
|
||||||
let ctx = Context {
|
let ctx = Context {
|
||||||
decoder,
|
decoder,
|
||||||
goodbye_cache,
|
|
||||||
attr_cache: None,
|
|
||||||
ino_offset: 0,
|
ino_offset: 0,
|
||||||
child_parent: HashMap::new(),
|
child_parent: HashMap::new(),
|
||||||
};
|
};
|
||||||
|
@ -414,11 +401,10 @@ impl Session {
|
||||||
let filename = unsafe { CStr::from_ptr(name) };
|
let filename = unsafe { CStr::from_ptr(name) };
|
||||||
let hash = super::format_definition::compute_goodbye_hash(filename.to_bytes());
|
let hash = super::format_definition::compute_goodbye_hash(filename.to_bytes());
|
||||||
|
|
||||||
Self::run_in_context(req, parent, |mut ctx| {
|
Self::run_in_context(req, parent, |ctx| {
|
||||||
// find_ goodbye_entry() will also update the goodbye cache
|
// find_ goodbye_entry() will also update the goodbye cache
|
||||||
let (child_offset, entry, attr, payload_size) =
|
let (child_offset, entry, _attr, payload_size) =
|
||||||
ctx.find_goodbye_entry(&filename, hash)?;
|
ctx.find_goodbye_entry(&filename, hash)?;
|
||||||
ctx.attr_cache = Some((child_offset, attr));
|
|
||||||
let child_inode = calculate_inode(child_offset, ctx.decoder.root_end_offset());
|
let child_inode = calculate_inode(child_offset, ctx.decoder.root_end_offset());
|
||||||
|
|
||||||
let e = EntryParam {
|
let e = EntryParam {
|
||||||
|
@ -440,11 +426,10 @@ impl Session {
|
||||||
|
|
||||||
extern "C" fn getattr(req: Request, inode: u64, _fileinfo: MutPtr) {
|
extern "C" fn getattr(req: Request, inode: u64, _fileinfo: MutPtr) {
|
||||||
Self::run_in_context(req, inode, |ctx| {
|
Self::run_in_context(req, inode, |ctx| {
|
||||||
let (_, entry, attr, payload_size) = ctx
|
let (_, entry, _, payload_size) = ctx
|
||||||
.decoder
|
.decoder
|
||||||
.attributes(ctx.ino_offset)
|
.attributes(ctx.ino_offset)
|
||||||
.map_err(|_| libc::EIO)?;
|
.map_err(|_| libc::EIO)?;
|
||||||
ctx.attr_cache = Some((ctx.ino_offset, attr));
|
|
||||||
let attr = stat(inode, &entry, payload_size)?;
|
let attr = stat(inode, &entry, payload_size)?;
|
||||||
let _res = unsafe {
|
let _res = unsafe {
|
||||||
// Since fs is read-only, the timeout can be max.
|
// Since fs is read-only, the timeout can be max.
|
||||||
|
@ -500,12 +485,7 @@ impl Session {
|
||||||
/// This simply checks if the inode references a valid directory, no internal
|
/// This simply checks if the inode references a valid directory, no internal
|
||||||
/// state identifies the directory as opened.
|
/// state identifies the directory as opened.
|
||||||
extern "C" fn opendir(req: Request, inode: u64, fileinfo: MutPtr) {
|
extern "C" fn opendir(req: Request, inode: u64, fileinfo: MutPtr) {
|
||||||
Self::run_in_context(req, inode, |ctx| {
|
Self::run_in_context(req, inode, |_ctx| {
|
||||||
let gbt = ctx.decoder
|
|
||||||
.goodbye_table(None, ctx.ino_offset + GOODBYE_ITEM_SIZE)
|
|
||||||
.map_err(|_| libc::EIO)?;
|
|
||||||
ctx.goodbye_cache.insert(ctx.ino_offset, gbt);
|
|
||||||
|
|
||||||
let _ret = unsafe { fuse_reply_open(req, fileinfo as MutPtr) };
|
let _ret = unsafe { fuse_reply_open(req, fileinfo as MutPtr) };
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -518,19 +498,18 @@ impl Session {
|
||||||
/// `size`, as requested by the caller.
|
/// `size`, as requested by the caller.
|
||||||
/// `offset` identifies the start index of entries to return. This is used on
|
/// `offset` identifies the start index of entries to return. This is used on
|
||||||
/// repeated calls, occurring if not all entries fitted into the buffer.
|
/// repeated calls, occurring if not all entries fitted into the buffer.
|
||||||
/// The goodbye table of the directory is cached in order to speedup repeated
|
|
||||||
/// calls occurring when not all entries fitted in the reply buffer.
|
|
||||||
extern "C" fn readdir(req: Request, inode: u64, size: size_t, offset: c_int, _fileinfo: MutPtr) {
|
extern "C" fn readdir(req: Request, inode: u64, size: size_t, offset: c_int, _fileinfo: MutPtr) {
|
||||||
let offset = offset as usize;
|
let offset = offset as usize;
|
||||||
|
|
||||||
Self::run_in_context(req, inode, |ctx| {
|
Self::run_in_context(req, inode, |ctx| {
|
||||||
let gb_table = ctx.goodbye_cache.get(&ctx.ino_offset)
|
let gbt = ctx.decoder
|
||||||
.ok_or_else(|| libc::EIO)?;
|
.goodbye_table(None, ctx.ino_offset + GOODBYE_ITEM_SIZE)
|
||||||
let n_entries = gb_table.len();
|
.map_err(|_| libc::EIO)?;
|
||||||
|
let n_entries = gbt.len();
|
||||||
let mut buf = ReplyBuf::new(req, size, offset);
|
let mut buf = ReplyBuf::new(req, size, offset);
|
||||||
|
|
||||||
if offset < n_entries {
|
if offset < n_entries {
|
||||||
for e in gb_table[offset..gb_table.len()].iter() {
|
for e in gbt[offset..gbt.len()].iter() {
|
||||||
let (filename, entry, _, payload_size) =
|
let (filename, entry, _, payload_size) =
|
||||||
ctx.decoder.attributes(e.1).map_err(|_| libc::EIO)?;
|
ctx.decoder.attributes(e.1).map_err(|_| libc::EIO)?;
|
||||||
let name = CString::new(filename.as_bytes()).map_err(|_| libc::EIO)?;
|
let name = CString::new(filename.as_bytes()).map_err(|_| libc::EIO)?;
|
||||||
|
@ -585,8 +564,7 @@ impl Session {
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" fn releasedir(req: Request, inode: u64, _fileinfo: MutPtr) {
|
extern "C" fn releasedir(req: Request, inode: u64, _fileinfo: MutPtr) {
|
||||||
Self::run_in_context(req, inode, |ctx| {
|
Self::run_in_context(req, inode, |_ctx| {
|
||||||
let _gbt = ctx.goodbye_cache.remove(&ctx.ino_offset);
|
|
||||||
Ok(())
|
Ok(())
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue