src/pxar/decoder.rs: use trait object as reader
So that the Decoder is no longer genertic.
This commit is contained in:
parent
f701d0335e
commit
99b5b6cba9
|
@ -7,8 +7,6 @@ use std::path::Path;
|
||||||
use failure::*;
|
use failure::*;
|
||||||
use libc;
|
use libc;
|
||||||
|
|
||||||
use crate::backup::*;
|
|
||||||
use crate::client::*;
|
|
||||||
use crate::pxar::*;
|
use crate::pxar::*;
|
||||||
|
|
||||||
use super::catalog::{CatalogReader, DirEntry};
|
use super::catalog::{CatalogReader, DirEntry};
|
||||||
|
@ -21,7 +19,7 @@ pub struct Shell {
|
||||||
/// List of paths selected for a restore
|
/// List of paths selected for a restore
|
||||||
selected: HashSet<Vec<u8>>,
|
selected: HashSet<Vec<u8>>,
|
||||||
/// Decoder instance for the current pxar archive
|
/// Decoder instance for the current pxar archive
|
||||||
decoder: Decoder<BufferedDynamicReader<RemoteChunkReader>>,
|
decoder: Decoder,
|
||||||
/// Root directory for the give archive as stored in the catalog
|
/// Root directory for the give archive as stored in the catalog
|
||||||
root: Vec<DirEntry>,
|
root: Vec<DirEntry>,
|
||||||
}
|
}
|
||||||
|
@ -60,7 +58,7 @@ impl Shell {
|
||||||
pub fn new(
|
pub fn new(
|
||||||
mut catalog: CatalogReader<std::fs::File>,
|
mut catalog: CatalogReader<std::fs::File>,
|
||||||
archive_name: &str,
|
archive_name: &str,
|
||||||
decoder: Decoder<BufferedDynamicReader<RemoteChunkReader>>
|
decoder: Decoder,
|
||||||
) -> Result<Self, Error> {
|
) -> Result<Self, Error> {
|
||||||
let catalog_root = catalog.root()?;
|
let catalog_root = catalog.root()?;
|
||||||
// The root for the given archive as stored in the catalog
|
// The root for the given archive as stored in the catalog
|
||||||
|
|
|
@ -1707,7 +1707,6 @@ async fn mount_do(param: Value, pipe: Option<RawFd>) -> Result<Value, Error> {
|
||||||
let most_used = index.find_most_used_chunks(8);
|
let most_used = index.find_most_used_chunks(8);
|
||||||
let chunk_reader = RemoteChunkReader::new(client.clone(), crypt_config, most_used);
|
let chunk_reader = RemoteChunkReader::new(client.clone(), crypt_config, most_used);
|
||||||
let reader = BufferedDynamicReader::new(index, chunk_reader);
|
let reader = BufferedDynamicReader::new(index, chunk_reader);
|
||||||
//let decoder = pxar::Decoder::new(Box::<dyn pxar::fuse::ReadSeek>::new(reader))?;
|
|
||||||
let decoder = pxar::Decoder::new(reader)?;
|
let decoder = pxar::Decoder::new(reader)?;
|
||||||
let options = OsStr::new("ro,default_permissions");
|
let options = OsStr::new("ro,default_permissions");
|
||||||
let mut session = pxar::fuse::Session::from_decoder(decoder, &options, pipe.is_none())
|
let mut session = pxar::fuse::Session::from_decoder(decoder, &options, pipe.is_none())
|
||||||
|
|
|
@ -26,9 +26,13 @@ pub struct DirectoryEntry {
|
||||||
pub entry: PxarEntry,
|
pub entry: PxarEntry,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Trait to create ReadSeek Decoder trait objects.
|
||||||
|
trait ReadSeek: Read + Seek {}
|
||||||
|
impl <R: Read + Seek> ReadSeek for R {}
|
||||||
|
|
||||||
// This one needs Read+Seek
|
// This one needs Read+Seek
|
||||||
pub struct Decoder<R: Read + Seek> {
|
pub struct Decoder {
|
||||||
inner: SequentialDecoder<R>,
|
inner: SequentialDecoder<Box<dyn ReadSeek>>,
|
||||||
root_start: u64,
|
root_start: u64,
|
||||||
root_end: u64,
|
root_end: u64,
|
||||||
}
|
}
|
||||||
|
@ -36,10 +40,11 @@ pub struct Decoder<R: Read + Seek> {
|
||||||
const HEADER_SIZE: u64 = std::mem::size_of::<PxarHeader>() as u64;
|
const HEADER_SIZE: u64 = std::mem::size_of::<PxarHeader>() as u64;
|
||||||
const GOODBYE_ITEM_SIZE: u64 = std::mem::size_of::<PxarGoodbyeItem>() as u64;
|
const GOODBYE_ITEM_SIZE: u64 = std::mem::size_of::<PxarGoodbyeItem>() as u64;
|
||||||
|
|
||||||
impl<R: Read + Seek> Decoder<R> {
|
impl Decoder {
|
||||||
pub fn new(mut reader: R) -> Result<Self, Error> {
|
pub fn new<R: Read + Seek + 'static>(mut reader: R) -> Result<Self, Error> {
|
||||||
let root_end = reader.seek(SeekFrom::End(0))?;
|
let root_end = reader.seek(SeekFrom::End(0))?;
|
||||||
let inner = SequentialDecoder::new(reader, super::flags::DEFAULT);
|
let boxed_reader: Box<dyn ReadSeek + 'static> = Box::new(reader);
|
||||||
|
let inner = SequentialDecoder::new(boxed_reader, super::flags::DEFAULT);
|
||||||
|
|
||||||
Ok(Self { inner, root_start: 0, root_end })
|
Ok(Self { inner, root_start: 0, root_end })
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,7 +6,7 @@ use std::collections::HashMap;
|
||||||
use std::convert::TryFrom;
|
use std::convert::TryFrom;
|
||||||
use std::ffi::{CStr, CString, OsStr};
|
use std::ffi::{CStr, CString, OsStr};
|
||||||
use std::fs::File;
|
use std::fs::File;
|
||||||
use std::io::{BufReader, Read, Seek};
|
use std::io::BufReader;
|
||||||
use std::os::unix::ffi::{OsStrExt, OsStringExt};
|
use std::os::unix::ffi::{OsStrExt, OsStringExt};
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
use std::sync::Mutex;
|
use std::sync::Mutex;
|
||||||
|
@ -83,8 +83,8 @@ struct FuseArgs {
|
||||||
|
|
||||||
/// `Context` for callback functions providing the decoder, caches and the
|
/// `Context` for callback functions providing the decoder, caches and the
|
||||||
/// 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<R: Read + Seek> {
|
struct Context {
|
||||||
decoder: Decoder<R>,
|
decoder: Decoder,
|
||||||
goodbye_cache: Option<(Inode, Vec<(PxarGoodbyeItem, Offset, Offset)>)>,
|
goodbye_cache: Option<(Inode, Vec<(PxarGoodbyeItem, Offset, Offset)>)>,
|
||||||
attr_cache: Option<(Inode, PxarAttributes)>,
|
attr_cache: Option<(Inode, PxarAttributes)>,
|
||||||
ino_offset: Offset,
|
ino_offset: Offset,
|
||||||
|
@ -92,10 +92,9 @@ struct Context<R: Read + Seek> {
|
||||||
|
|
||||||
/// `Session` stores a pointer to the session context and is used to mount the
|
/// `Session` stores a pointer to the session context and is used to mount the
|
||||||
/// archive to the given mountpoint.
|
/// archive to the given mountpoint.
|
||||||
pub struct Session<R: Read + Seek> {
|
pub struct Session {
|
||||||
ptr: MutPtr,
|
ptr: MutPtr,
|
||||||
verbose: bool,
|
verbose: bool,
|
||||||
_phantom: std::marker::PhantomData<R>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// `Operations` defines the callback function table of supported operations.
|
/// `Operations` defines the callback function table of supported operations.
|
||||||
|
@ -151,7 +150,9 @@ struct Operations {
|
||||||
copy_file_range: Option<extern fn(req: Request, ino_in: u64, off_in: c_int, fi_in: MutPtr, ino_out: u64, off_out: c_int, fi_out: MutPtr, len: size_t, flags: c_int)>,
|
copy_file_range: Option<extern fn(req: Request, ino_in: u64, off_in: c_int, fi_in: MutPtr, ino_out: u64, off_out: c_int, fi_out: MutPtr, len: size_t, flags: c_int)>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Session<BufReader<File>> {
|
|
||||||
|
impl Session {
|
||||||
|
|
||||||
/// Create a new low level fuse session.
|
/// Create a new low level fuse session.
|
||||||
///
|
///
|
||||||
/// `Session` is created using the provided mount options and sets the
|
/// `Session` is created using the provided mount options and sets the
|
||||||
|
@ -169,9 +170,7 @@ impl Session<BufReader<File>> {
|
||||||
let decoder = Decoder::new(reader)?;
|
let decoder = Decoder::new(reader)?;
|
||||||
Self::setup_session(decoder, args, oprs, verbose)
|
Self::setup_session(decoder, args, oprs, verbose)
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
impl <R: Read + Seek> Session<R> {
|
|
||||||
fn setup_args(options: &OsStr, verbose: bool) -> Result<Vec<CString>, Error> {
|
fn setup_args(options: &OsStr, verbose: bool) -> Result<Vec<CString>, Error> {
|
||||||
// First argument should be the executable name
|
// First argument should be the executable name
|
||||||
let mut arguments = vec![
|
let mut arguments = vec![
|
||||||
|
@ -202,7 +201,7 @@ impl <R: Read + Seek> Session<R> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn setup_session(
|
fn setup_session(
|
||||||
decoder: Decoder<R>,
|
decoder: Decoder,
|
||||||
args: Vec<CString>,
|
args: Vec<CString>,
|
||||||
oprs: Operations,
|
oprs: Operations,
|
||||||
verbose: bool,
|
verbose: bool,
|
||||||
|
@ -244,7 +243,6 @@ impl <R: Read + Seek> Session<R> {
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
ptr: session_ptr,
|
ptr: session_ptr,
|
||||||
verbose,
|
verbose,
|
||||||
_phantom: std::marker::PhantomData,
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -255,7 +253,7 @@ impl <R: Read + Seek> Session<R> {
|
||||||
/// 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 from_decoder(
|
pub fn from_decoder(
|
||||||
decoder: Decoder<R>,
|
decoder: Decoder,
|
||||||
options: &OsStr,
|
options: &OsStr,
|
||||||
verbose: bool,
|
verbose: bool,
|
||||||
) -> Result<Self, Error> {
|
) -> Result<Self, Error> {
|
||||||
|
@ -319,10 +317,10 @@ impl <R: Read + Seek> Session<R> {
|
||||||
/// The error code will be used to reply to libfuse.
|
/// The error code will be used to reply to libfuse.
|
||||||
fn run_in_context<F>(req: Request, inode: u64, code: F)
|
fn run_in_context<F>(req: Request, inode: u64, code: F)
|
||||||
where
|
where
|
||||||
F: FnOnce(&mut Context<R>) -> Result<(), i32>,
|
F: FnOnce(&mut Context) -> Result<(), i32>,
|
||||||
{
|
{
|
||||||
let boxed_ctx = unsafe {
|
let boxed_ctx = unsafe {
|
||||||
let ptr = fuse_req_userdata(req) as *mut Mutex<Context<R>>;
|
let ptr = fuse_req_userdata(req) as *mut Mutex<Context>;
|
||||||
Box::from_raw(ptr)
|
Box::from_raw(ptr)
|
||||||
};
|
};
|
||||||
let result = boxed_ctx
|
let result = boxed_ctx
|
||||||
|
@ -532,7 +530,7 @@ impl <R: Read + Seek> Session<R> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl <R: Read + Seek> Drop for Session<R> {
|
impl Drop for Session {
|
||||||
fn drop(&mut self) {
|
fn drop(&mut self) {
|
||||||
unsafe {
|
unsafe {
|
||||||
fuse_session_unmount(self.ptr);
|
fuse_session_unmount(self.ptr);
|
||||||
|
@ -593,7 +591,7 @@ struct EntryParam {
|
||||||
|
|
||||||
/// Update the goodbye table to the one corresponding to the i-node offset, both
|
/// Update the goodbye table to the one corresponding to the i-node offset, both
|
||||||
/// given in the `Context`.
|
/// given in the `Context`.
|
||||||
fn update_goodbye_cache<R: Read + Seek>(mut ctx: &mut Context<R>) -> Result<(), i32> {
|
fn update_goodbye_cache(mut ctx: &mut Context) -> Result<(), i32> {
|
||||||
if let Some((off, _)) = &ctx.goodbye_cache {
|
if let Some((off, _)) = &ctx.goodbye_cache {
|
||||||
if *off == ctx.ino_offset {
|
if *off == ctx.ino_offset {
|
||||||
// Cache contains already the correct goodbye table
|
// Cache contains already the correct goodbye table
|
||||||
|
@ -623,8 +621,8 @@ fn update_goodbye_cache<R: Read + Seek>(mut ctx: &mut Context<R>) -> Result<(),
|
||||||
/// The matching items archive offset, entry and payload size are returned.
|
/// The matching items archive offset, entry and payload size are returned.
|
||||||
/// If there is no entry with matching `filename` and `hash` a `libc::ENOENT` is
|
/// If there is no entry with matching `filename` and `hash` a `libc::ENOENT` is
|
||||||
/// returned.
|
/// returned.
|
||||||
fn find_goodbye_entry<R: Read + Seek>(
|
fn find_goodbye_entry(
|
||||||
mut ctx: &mut Context<R>,
|
mut ctx: &mut Context,
|
||||||
filename: &CStr,
|
filename: &CStr,
|
||||||
hash: u64,
|
hash: u64,
|
||||||
) -> Result<(u64, PxarEntry, PxarAttributes, u64), i32> {
|
) -> Result<(u64, PxarEntry, PxarAttributes, u64), i32> {
|
||||||
|
|
Loading…
Reference in New Issue