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;
|
||||
|
||||
type Inode = u64;
|
||||
type Offset = u64;
|
||||
/// FFI types for easier readability
|
||||
type Request = *mut c_void;
|
||||
|
@ -77,8 +76,6 @@ struct FuseArgs {
|
|||
/// offset within the archive for the i-node given by the caller.
|
||||
struct Context {
|
||||
decoder: Decoder,
|
||||
goodbye_cache: HashMap<Inode, Vec<(PxarGoodbyeItem, Offset, Offset)>>,
|
||||
attr_cache: Option<(Inode, PxarAttributes)>,
|
||||
ino_offset: Offset,
|
||||
/// HashMap holding the mapping from the child offsets to their parent
|
||||
/// offsets.
|
||||
|
@ -109,8 +106,9 @@ impl Context {
|
|||
filename: &CStr,
|
||||
hash: u64,
|
||||
) -> Result<(u64, PxarEntry, PxarAttributes, u64), i32> {
|
||||
let gbt = self.goodbye_cache.get(&self.ino_offset)
|
||||
.ok_or_else(|| libc::EIO)?;
|
||||
let gbt = self.decoder
|
||||
.goodbye_table(None, self.ino_offset + GOODBYE_ITEM_SIZE)
|
||||
.map_err(|_| libc::EIO)?;
|
||||
let mut start_idx = 0;
|
||||
let mut skip_multiple = 0;
|
||||
loop {
|
||||
|
@ -228,23 +226,12 @@ impl Session {
|
|||
/// default signal handlers.
|
||||
/// Options have to be provided as comma separated OsStr, e.g.
|
||||
/// ("ro,default_permissions").
|
||||
pub fn new(
|
||||
mut decoder: Decoder,
|
||||
options: &OsStr,
|
||||
verbose: bool,
|
||||
) -> Result<Self, Error> {
|
||||
pub fn new(decoder: Decoder, options: &OsStr, verbose: bool) -> Result<Self, Error> {
|
||||
let args = Self::setup_args(options, verbose)?;
|
||||
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 {
|
||||
decoder,
|
||||
goodbye_cache,
|
||||
attr_cache: None,
|
||||
ino_offset: 0,
|
||||
child_parent: HashMap::new(),
|
||||
};
|
||||
|
@ -414,11 +401,10 @@ impl Session {
|
|||
let filename = unsafe { CStr::from_ptr(name) };
|
||||
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
|
||||
let (child_offset, entry, attr, payload_size) =
|
||||
let (child_offset, entry, _attr, payload_size) =
|
||||
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 e = EntryParam {
|
||||
|
@ -440,11 +426,10 @@ impl Session {
|
|||
|
||||
extern "C" fn getattr(req: Request, inode: u64, _fileinfo: MutPtr) {
|
||||
Self::run_in_context(req, inode, |ctx| {
|
||||
let (_, entry, attr, payload_size) = ctx
|
||||
let (_, entry, _, payload_size) = ctx
|
||||
.decoder
|
||||
.attributes(ctx.ino_offset)
|
||||
.map_err(|_| libc::EIO)?;
|
||||
ctx.attr_cache = Some((ctx.ino_offset, attr));
|
||||
let attr = stat(inode, &entry, payload_size)?;
|
||||
let _res = unsafe {
|
||||
// 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
|
||||
/// state identifies the directory as opened.
|
||||
extern "C" fn opendir(req: Request, inode: u64, fileinfo: MutPtr) {
|
||||
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);
|
||||
|
||||
Self::run_in_context(req, inode, |_ctx| {
|
||||
let _ret = unsafe { fuse_reply_open(req, fileinfo as MutPtr) };
|
||||
|
||||
Ok(())
|
||||
|
@ -518,19 +498,18 @@ impl Session {
|
|||
/// `size`, as requested by the caller.
|
||||
/// `offset` identifies the start index of entries to return. This is used on
|
||||
/// 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) {
|
||||
let offset = offset as usize;
|
||||
|
||||
Self::run_in_context(req, inode, |ctx| {
|
||||
let gb_table = ctx.goodbye_cache.get(&ctx.ino_offset)
|
||||
.ok_or_else(|| libc::EIO)?;
|
||||
let n_entries = gb_table.len();
|
||||
let gbt = ctx.decoder
|
||||
.goodbye_table(None, ctx.ino_offset + GOODBYE_ITEM_SIZE)
|
||||
.map_err(|_| libc::EIO)?;
|
||||
let n_entries = gbt.len();
|
||||
let mut buf = ReplyBuf::new(req, size, offset);
|
||||
|
||||
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) =
|
||||
ctx.decoder.attributes(e.1).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) {
|
||||
Self::run_in_context(req, inode, |ctx| {
|
||||
let _gbt = ctx.goodbye_cache.remove(&ctx.ino_offset);
|
||||
Self::run_in_context(req, inode, |_ctx| {
|
||||
Ok(())
|
||||
});
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue