diff --git a/Cargo.toml b/Cargo.toml index 5eddd4933..fb345f85b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -86,7 +86,7 @@ proxmox-uuid = "1" # other proxmox crates pathpatterns = "0.3" proxmox-acme = "0.5" -pxar = "0.11.1" +pxar = "0.12" # PBS workspace pbs-api-types = { path = "pbs-api-types" } diff --git a/debian/control b/debian/control index cbf9fbd0f..6445680f9 100644 --- a/debian/control +++ b/debian/control @@ -103,7 +103,7 @@ Build-Depends: bash-completion, librust-proxmox-time-1+default-dev (>= 1.1.6-~~), librust-proxmox-uuid-1+default-dev, librust-proxmox-uuid-1+serde-dev, - librust-pxar-0.11+default-dev (>= 0.11.1-~~), + librust-pxar-0.12+default-dev, librust-regex-1+default-dev (>= 1.5.5-~~), librust-rustyline-9+default-dev, librust-serde-1+default-dev, diff --git a/pbs-client/src/pxar/extract.rs b/pbs-client/src/pxar/extract.rs index 38d4ca89a..e1192c73f 100644 --- a/pbs-client/src/pxar/extract.rs +++ b/pbs-client/src/pxar/extract.rs @@ -373,26 +373,22 @@ where Ok(()) } } - (true, EntryKind::File { size, .. }) => { - let contents = self.decoder.contents(); - - if let Some(mut contents) = contents { - self.extractor.extract_file( - &file_name, - metadata, - *size, - &mut contents, - self.extractor - .overwrite_flags - .contains(OverwriteFlags::FILE), - ) - } else { - Err(format_err!( - "found regular file entry without contents in archive" - )) - } - .context(PxarExtractContext::ExtractFile) + (true, EntryKind::File { size, .. }) => match self.decoder.contents() { + Ok(Some(mut contents)) => self.extractor.extract_file( + &file_name, + metadata, + *size, + &mut contents, + self.extractor + .overwrite_flags + .contains(OverwriteFlags::FILE), + ), + Ok(None) => Err(format_err!( + "found regular file entry without contents in archive" + )), + Err(err) => Err(err.into()), } + .context(PxarExtractContext::ExtractFile), (false, _) => Ok(()), // skip this }; @@ -872,7 +868,8 @@ where match entry.kind() { EntryKind::File { .. } => { let size = decoder.content_size().unwrap_or(0); - tar_add_file(&mut tarencoder, decoder.contents(), size, metadata, path).await? + let contents = decoder.contents().await?; + tar_add_file(&mut tarencoder, contents, size, metadata, path).await? } EntryKind::Hardlink(link) => { if !link.data.is_empty() { @@ -894,14 +891,9 @@ where path } else { let size = decoder.content_size().unwrap_or(0); - tar_add_file( - &mut tarencoder, - decoder.contents(), - size, - metadata, - path, - ) - .await?; + let contents = decoder.contents().await?; + tar_add_file(&mut tarencoder, contents, size, metadata, path) + .await?; hardlinks.insert(realpath.to_owned(), path.to_owned()); continue; } @@ -1038,7 +1030,8 @@ where metadata.stat.mode as u16, true, ); - zip.add_entry(entry, decoder.contents()) + let contents = decoder.contents().await?; + zip.add_entry(entry, contents) .await .context("could not send file entry")?; } @@ -1056,7 +1049,8 @@ where metadata.stat.mode as u16, true, ); - zip.add_entry(entry, decoder.contents()) + let contents = decoder.contents().await?; + zip.add_entry(entry, contents) .await .context("could not send file entry")?; } @@ -1279,14 +1273,16 @@ where .with_context(|| format!("error at entry {file_name_os:?}"))?; } EntryKind::File { size, .. } => { + let mut contents = decoder + .contents() + .await? + .context("found regular file entry without contents in archive")?; extractor .async_extract_file( &file_name, metadata, *size, - &mut decoder - .contents() - .context("found regular file entry without contents in archive")?, + &mut contents, extractor.overwrite_flags.contains(OverwriteFlags::FILE), ) .await? diff --git a/pbs-pxar-fuse/src/lib.rs b/pbs-pxar-fuse/src/lib.rs index 780a4ddbe..4c26de200 100644 --- a/pbs-pxar-fuse/src/lib.rs +++ b/pbs-pxar-fuse/src/lib.rs @@ -5,7 +5,6 @@ use std::ffi::{OsStr, OsString}; use std::future::Future; use std::io; use std::mem; -use std::ops::Range; use std::os::unix::ffi::OsStrExt; use std::path::Path; use std::pin::Pin; @@ -20,7 +19,7 @@ use futures::sink::SinkExt; use futures::stream::{StreamExt, TryStreamExt}; use proxmox_io::vec; -use pxar::accessor::{self, EntryRangeInfo, ReadAt}; +use pxar::accessor::{self, ContentRange, EntryRangeInfo, ReadAt}; use proxmox_fuse::requests::{self, FuseRequest}; use proxmox_fuse::{EntryParam, Fuse, ReplyBufState, Request, ROOT_ID}; @@ -130,7 +129,7 @@ struct Lookup { inode: u64, parent: u64, entry_range_info: EntryRangeInfo, - content_range: Option>, + content_range: Option, } impl Lookup { @@ -138,7 +137,7 @@ impl Lookup { inode: u64, parent: u64, entry_range_info: EntryRangeInfo, - content_range: Option>, + content_range: Option, ) -> Box { Box::new(Self { refs: AtomicUsize::new(1), @@ -433,13 +432,17 @@ impl SessionImpl { } } - fn open_content(&self, lookup: &LookupRef) -> Result { + async fn open_content<'a>(&'a self, lookup: &'a LookupRef<'a>) -> Result { if is_dir_inode(lookup.inode) { io_return!(libc::EISDIR); } - match lookup.content_range.clone() { - Some(range) => Ok(unsafe { self.accessor.open_contents_at_range(range) }), + match &lookup.content_range { + Some(range) => self + .accessor + .open_contents_at_range(range) + .await + .map_err(|err| err.into()), None => io_return!(libc::EBADF), } } @@ -581,7 +584,7 @@ impl SessionImpl { async fn read(&self, inode: u64, len: usize, offset: u64) -> Result, Error> { let file = self.get_lookup(inode)?; - let content = self.open_content(&file)?; + let content = self.open_content(&file).await?; let mut buf = vec::undefined(len); let mut pos = 0; // fuse' read is different from normal read - no short reads allowed except for EOF! diff --git a/src/api2/tape/restore.rs b/src/api2/tape/restore.rs index 382909647..2b2025f6d 100644 --- a/src/api2/tape/restore.rs +++ b/src/api2/tape/restore.rs @@ -1748,7 +1748,7 @@ fn try_restore_snapshot_archive( } let filename = entry.file_name(); - let mut contents = match decoder.contents() { + let mut contents = match decoder.contents()? { None => bail!("missing file content"), Some(contents) => contents, };