[pbs-devel] [PATCH pxar 4/6] implement Entry v2
Wolfgang Bumiller
w.bumiller at proxmox.com
Tue Jul 28 12:33:19 CEST 2020
Signed-off-by: Wolfgang Bumiller <w.bumiller at proxmox.com>
---
src/decoder/mod.rs | 21 ++++++++++++++++-----
src/errors.rs | 25 -------------------------
src/format/mod.rs | 46 ++++++++++++++++++++++++++++++++++------------
src/lib.rs | 28 +++++++++++++++-------------
4 files changed, 65 insertions(+), 55 deletions(-)
delete mode 100644 src/errors.rs
diff --git a/src/decoder/mod.rs b/src/decoder/mod.rs
index 9410942..e5b6d2c 100644
--- a/src/decoder/mod.rs
+++ b/src/decoder/mod.rs
@@ -360,11 +360,22 @@ impl<I: SeqRead> DecoderImpl<I> {
self.entry.kind = EntryKind::Hardlink(self.read_hardlink().await?);
Ok(Some(self.entry.take()))
- } else if header.htype == format::PXAR_ENTRY {
- self.entry.metadata = Metadata {
- stat: seq_read_entry(&mut self.input).await?,
- ..Default::default()
- };
+ } else if header.htype == format::PXAR_ENTRY || header.htype == format::PXAR_ENTRY_V1 {
+ if header.htype == format::PXAR_ENTRY {
+ self.entry.metadata = Metadata {
+ stat: seq_read_entry(&mut self.input).await?,
+ ..Default::default()
+ };
+ } else if header.htype == format::PXAR_ENTRY_V1 {
+ let stat: format::Entry_V1 = seq_read_entry(&mut self.input).await?;
+
+ self.entry.metadata = Metadata {
+ stat: stat.into(),
+ ..Default::default()
+ };
+ } else {
+ unreachable!();
+ }
self.current_header = unsafe { mem::zeroed() };
diff --git a/src/errors.rs b/src/errors.rs
deleted file mode 100644
index 8983e98..0000000
--- a/src/errors.rs
+++ /dev/null
@@ -1,25 +0,0 @@
-use std::error::Error;
-use std::fmt;
-
-#[derive(Clone, Debug)]
-pub enum TimeError {
- Underflow(std::time::SystemTimeError),
- Overflow(std::time::Duration),
-}
-
-impl fmt::Display for TimeError {
- fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
- match self {
- TimeError::Underflow(st) => st.fmt(f),
- TimeError::Overflow(dur) => write!(f, "timestamp out of range: {:?}", dur),
- }
- }
-}
-
-impl Error for TimeError {}
-
-impl From<std::time::SystemTimeError> for TimeError {
- fn from(t: std::time::SystemTimeError) -> Self {
- TimeError::Underflow(t)
- }
-}
diff --git a/src/format/mod.rs b/src/format/mod.rs
index 085b8b9..ec61e15 100644
--- a/src/format/mod.rs
+++ b/src/format/mod.rs
@@ -78,7 +78,10 @@ pub mod mode {
pub const ISVTX : u64 = 0o0001000;
}
-pub const PXAR_ENTRY: u64 = 0x11da850a1c1cceff;
+/// Beginning of an entry (current version).
+pub const PXAR_ENTRY: u64 = 0xd5956474e588acef;
+/// Previous version of the entry struct
+pub const PXAR_ENTRY_V1: u64 = 0x11da850a1c1cceff;
pub const PXAR_FILENAME: u64 = 0x16701121063917b3;
pub const PXAR_SYMLINK: u64 = 0x27f971e7dbf5dc5f;
pub const PXAR_DEVICE: u64 = 0x9fc9e906586d5ce9;
@@ -300,7 +303,7 @@ fn test_statx_timestamp() {
#[derive(Clone, Debug, Default, Endian)]
#[cfg_attr(feature = "test-harness", derive(Eq, PartialEq))]
#[repr(C)]
-pub struct Entry {
+pub struct Entry_V1 {
pub mode: u64,
pub flags: u64,
pub uid: u32,
@@ -308,6 +311,29 @@ pub struct Entry {
pub mtime: u64,
}
+impl Into<Entry> for Entry_V1 {
+ fn into(self) -> Entry {
+ Entry {
+ mode: self.mode,
+ flags: self.flags,
+ uid: self.uid,
+ gid: self.gid,
+ mtime: StatxTimestamp::from_duration_since_epoch(Duration::from_nanos(self.mtime)),
+ }
+ }
+}
+
+#[derive(Clone, Debug, Default, Endian)]
+#[cfg_attr(feature = "test-harness", derive(Eq, PartialEq))]
+#[repr(C)]
+pub struct Entry {
+ pub mode: u64,
+ pub flags: u64,
+ pub uid: u32,
+ pub gid: u32,
+ pub mtime: StatxTimestamp,
+}
+
/// Builder pattern methods.
impl Entry {
pub const fn mode(self, mode: u64) -> Self {
@@ -326,7 +352,7 @@ impl Entry {
Self { gid, ..self }
}
- pub const fn mtime(self, mtime: u64) -> Self {
+ pub const fn mtime(self, mtime: StatxTimestamp) -> Self {
Self { mtime, ..self }
}
@@ -363,9 +389,10 @@ impl Entry {
/// Convenience accessor methods.
impl Entry {
- /// Get the mtime as duration since the epoch.
- pub fn mtime_as_duration(&self) -> std::time::Duration {
- std::time::Duration::from_nanos(self.mtime)
+ /// Get the mtime as duration since the epoch. an `Ok` value is a positive duration, an `Err`
+ /// value is a negative duration.
+ pub fn mtime_as_duration(&self) -> SignedDuration {
+ self.mtime.to_duration()
}
/// Get the file type portion of the mode bitfield.
@@ -449,12 +476,7 @@ impl From<&std::fs::Metadata> for Entry {
.mode(meta.mode() as u64);
let this = match meta.modified() {
- Ok(mtime) => this.mtime(
- mtime
- .duration_since(std::time::SystemTime::UNIX_EPOCH)
- .map(|dur| dur.as_nanos() as u64)
- .unwrap_or(0u64),
- ),
+ Ok(mtime) => this.mtime(mtime.into()),
Err(_) => this,
};
diff --git a/src/lib.rs b/src/lib.rs
index 5d1b781..a58ec30 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -2,7 +2,6 @@
//!
//! This implements a reader and writer for the proxmox archive format (.pxar).
-use std::convert::TryFrom;
use std::ffi::OsStr;
use std::mem;
use std::path::{Path, PathBuf};
@@ -20,7 +19,6 @@ pub mod accessor;
pub mod binary_tree_array;
pub mod decoder;
pub mod encoder;
-pub mod errors;
/// Reexport of `format::Entry`. Since this conveys mostly information found via the `stat` syscall
/// we mostly use this name for public interfaces.
@@ -125,8 +123,9 @@ impl Metadata {
self.stat.is_socket()
}
- /// Get the mtime as duration since the epoch.
- pub fn mtime_as_duration(&self) -> std::time::Duration {
+ /// Get the mtime as duration since the epoch. an `Ok` value is a positive duration, an `Err`
+ /// value is a negative duration.
+ pub fn mtime_as_duration(&self) -> format::SignedDuration {
self.stat.mtime_as_duration()
}
@@ -165,7 +164,7 @@ impl MetadataBuilder {
flags: 0,
uid: 0,
gid: 0,
- mtime: 0,
+ mtime: format::StatxTimestamp::zero(),
},
xattrs: Vec::new(),
acl: Acl {
@@ -198,17 +197,20 @@ impl MetadataBuilder {
self
}
- /// Set the modification time from a system time.
- pub fn mtime(self, mtime: std::time::SystemTime) -> Result<Self, errors::TimeError> {
- self.mtime_unix(mtime.duration_since(std::time::SystemTime::UNIX_EPOCH)?)
+ /// Set the modification time from a statx timespec value.
+ pub fn mtime_full(mut self, mtime: format::StatxTimestamp) -> Self {
+ self.inner.stat.mtime = mtime;
+ self
}
/// Set the modification time from a duration since the epoch (`SystemTime::UNIX_EPOCH`).
- pub fn mtime_unix(mut self, mtime: std::time::Duration) -> Result<Self, errors::TimeError> {
- let nanos =
- u64::try_from(mtime.as_nanos()).map_err(|_| errors::TimeError::Overflow(mtime))?;
- self.inner.stat.mtime = nanos;
- Ok(self)
+ pub fn mtime_unix(self, mtime: std::time::Duration) -> Self {
+ self.mtime_full(format::StatxTimestamp::from_duration_since_epoch(mtime))
+ }
+
+ /// Set the modification time from a system time.
+ pub fn mtime(self, mtime: std::time::SystemTime) -> Self {
+ self.mtime_full(mtime.into())
}
/// Set the ownership information.
--
2.20.1
More information about the pbs-devel
mailing list