all lists on lists.proxmox.com
 help / color / mirror / Atom feed
From: Wolfgang Bumiller <w.bumiller@proxmox.com>
To: pbs-devel@lists.proxmox.com
Subject: [pbs-devel] [PATCH pxar 4/6] implement Entry v2
Date: Tue, 28 Jul 2020 12:33:19 +0200	[thread overview]
Message-ID: <20200728103321.16843-6-w.bumiller@proxmox.com> (raw)
In-Reply-To: <20200728103321.16843-1-w.bumiller@proxmox.com>

Signed-off-by: Wolfgang Bumiller <w.bumiller@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





  parent reply	other threads:[~2020-07-28 10:33 UTC|newest]

Thread overview: 11+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-07-28 10:33 [pbs-devel] [PATCH pxar/backup 0/6] bump timestamps to 96 bit Wolfgang Bumiller
2020-07-28 10:33 ` [pbs-devel] [PATCH pxar 1/6] add format description to format module Wolfgang Bumiller
2020-07-28 10:33 ` [pbs-devel] [PATCH backup] update to pxar 0.3 to support negative timestamps Wolfgang Bumiller
2020-07-29  6:32   ` [pbs-devel] applied: " Dietmar Maurer
2020-07-28 10:33 ` [pbs-devel] [PATCH pxar 2/6] introduce StatxTimestamp helper type Wolfgang Bumiller
2020-07-28 14:05   ` [pbs-devel] [PATCH pxar v2 " Wolfgang Bumiller
2020-07-28 10:33 ` [pbs-devel] [PATCH pxar 3/6] update mk-format-hashes for a new ENTRY Wolfgang Bumiller
2020-07-28 10:33 ` Wolfgang Bumiller [this message]
2020-07-28 10:33 ` [pbs-devel] [PATCH pxar 5/6] add entry v1 compatiblity test Wolfgang Bumiller
2020-07-28 10:33 ` [pbs-devel] [PATCH pxar 6/6] bump version to 0.3.0-1 Wolfgang Bumiller
2020-07-29  6:14 ` [pbs-devel] applied: [PATCH pxar/backup 0/6] bump timestamps to 96 bit Dietmar Maurer

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20200728103321.16843-6-w.bumiller@proxmox.com \
    --to=w.bumiller@proxmox.com \
    --cc=pbs-devel@lists.proxmox.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.
Service provided by Proxmox Server Solutions GmbH | Privacy | Legal