From ec04ea81f2e738f91785e63fd878b54bbf43d8de Mon Sep 17 00:00:00 2001 From: Christian Ebner Date: Fri, 6 Sep 2019 11:38:27 +0200 Subject: [PATCH] src/pxar/fuse.rs: Refactor run_in_context and remove inode_to_offset and offset_to_inode as their functionality is used only once so it makes more sense to keep them inline. Signed-off-by: Christian Ebner --- src/pxar/fuse.rs | 75 +++++++++++++++++------------------------------- 1 file changed, 27 insertions(+), 48 deletions(-) diff --git a/src/pxar/fuse.rs b/src/pxar/fuse.rs index 5927a54c..56dbf60d 100644 --- a/src/pxar/fuse.rs +++ b/src/pxar/fuse.rs @@ -27,6 +27,7 @@ use super::format_definition::PxarGoodbyeItem; /// required. const FUSE_ROOT_ID: u64 = 1; +const GOODBYE_ITEM_SIZE: u64 = std::mem::size_of::() as u64; /// Callback function for `super::decoder::Decoder`. /// /// At the moment, this is only needed to satisfy the `SequentialDecoder`. @@ -252,47 +253,19 @@ impl Drop for Session { } } -const GOODBYE_ITEM_SIZE: u64 = std::mem::size_of::() as u64; - -/// Converts the inode to the file offset -/// -/// Since the inodes are defined as the file offset, -/// this simply returns the inode value. -/// The only exception to this is the inode of root, -/// which is defined as `FUSE_ROOT_ID` by libfuse and therefore mapped -/// to the roots goodbye table tail. -fn inode_to_offset(inode: u64, root_end: u64) -> u64 { - if inode == FUSE_ROOT_ID { - root_end - GOODBYE_ITEM_SIZE - } else { - inode - } -} - -/// Converts the file offset to an inode -/// -/// Since the inodes are defined as the file offset, -/// this simply returns the offset value. -/// The only exception to this is the inode of root, -/// which is defined as `FUSE_ROOT_ID` by libfuse, so the roots goodbye tail -/// offset gets mapped to `FUSE_ROOT_ID`. -pub(crate) fn offset_to_inode(offset: u64, root_end: u64) -> u64 { - if offset == root_end - GOODBYE_ITEM_SIZE { - FUSE_ROOT_ID - } else { - offset - } -} - /// Creates a context providing an exclusive mutable reference to the decoder. /// /// Each callback function needing access to the decoder can easily get an /// exclusive handle by running the code inside this context. /// Responses with error code can easily be generated by returning with the /// error code. -fn run_in_context(req: Request, code: F) +/// The error code will be used to reply to libfuse. +fn run_in_context(req: Request, inode: u64, code: F) where - F: FnOnce(&mut Decoder, fn(&Path) -> Result<(), Error>>) -> Result<(), i32>, + F: FnOnce( + &mut Decoder, fn(&Path) -> Result<(), Error>>, + u64, + ) -> Result<(), i32>, { let ptr = unsafe { fuse_req_userdata(req) @@ -301,8 +274,14 @@ where let boxed_decoder = unsafe { Box::from_raw(ptr) }; let result = boxed_decoder .lock() - .map(|mut decoder| code(&mut decoder)) - .unwrap_or(Err(libc::ENOENT)); + .map(|mut decoder| { + let ino_offset = match inode { + FUSE_ROOT_ID => decoder.root_end_offset() - GOODBYE_ITEM_SIZE, + _ => inode, + }; + code(&mut decoder, ino_offset) + }) + .unwrap_or(Err(libc::EIO)); if let Err(err) = result { unsafe { @@ -327,48 +306,48 @@ extern "C" fn destroy(decoder: MutPtr) { } } -extern "C" fn lookup(req: Request, _parent: u64, _name: StrPtr) { - run_in_context(req, |_decoder| { +extern "C" fn lookup(req: Request, parent: u64, _name: StrPtr) { + run_in_context(req, parent, |_decoder, _ino_offset| { // code goes here Err(libc::ENOENT) }); } -extern "C" fn getattr(req: Request, _inode: u64, _fileinfo: MutPtr) { - run_in_context(req, |_decoder| { +extern "C" fn getattr(req: Request, inode: u64, _fileinfo: MutPtr) { + run_in_context(req, inode, |_decoder, _ino_offset| { // code goes here Err(libc::ENOENT) }); } -extern "C" fn open(req: Request, _inode: u64, _fileinfo: MutPtr) { - run_in_context(req, |_decoder| { +extern "C" fn open(req: Request, inode: u64, _fileinfo: MutPtr) { + run_in_context(req, inode, |_decoder, _ino_offset| { // code goes here Err(libc::ENOENT) }); } -extern "C" fn read(req: Request, _inode: u64, _size: size_t, _offset: c_int, _fileinfo: MutPtr) { - run_in_context(req, |_decoder| { +extern "C" fn read(req: Request, inode: u64, _size: size_t, _offset: c_int, _fileinfo: MutPtr) { + run_in_context(req, inode, |_decoder, _ino_offset| { // code goes here Err(libc::ENOENT) }); } -extern "C" fn opendir(req: Request, _inode: u64, _fileinfo: MutPtr) { - run_in_context(req, |_decoder| { +extern "C" fn opendir(req: Request, inode: u64, _fileinfo: MutPtr) { + run_in_context(req, inode, |_decoder, _ino_offset| { // code goes here Err(libc::ENOENT) }); } -extern "C" fn readdir(req: Request, _inode: u64, _size: size_t, _offset: c_int, _fileinfo: MutPtr) { - run_in_context(req, |_decoder| { +extern "C" fn readdir(req: Request, inode: u64, _size: size_t, _offset: c_int, _fileinfo: MutPtr) { + run_in_context(req, inode, |_decoder, _ino_offset| { // code goes here Err(libc::ENOENT)