public inbox for pbs-devel@lists.proxmox.com
 help / color / mirror / Atom feed
From: "Max R. Carrara" <m.carrara@proxmox.com>
To: pbs-devel@lists.proxmox.com
Subject: [PATCH proxmox-backup v2 03/10] tape: move tape block structs into separate file module
Date: Fri, 21 Aug 2026 16:02:27 +0200	[thread overview]
Message-ID: <20260821140238.615302-4-m.carrara@proxmox.com> (raw)
In-Reply-To: <20260821140238.615302-1-m.carrara@proxmox.com>

Move `BlockHeader` and `BlockHeaderFlags` into a separate file for
overall better organization and to make future changes a little easier
to follow.

Also, re-export both types as `pub(crate)`, since there is not really
any reason for them to be completely public.

Signed-off-by: Max R. Carrara <m.carrara@proxmox.com>
---
 pbs-tape/src/lib.rs        | 79 ++------------------------------------
 pbs-tape/src/tape_block.rs | 79 ++++++++++++++++++++++++++++++++++++++
 2 files changed, 82 insertions(+), 76 deletions(-)
 create mode 100644 pbs-tape/src/tape_block.rs

diff --git a/pbs-tape/src/lib.rs b/pbs-tape/src/lib.rs
index 0fe55a749..6cff175dd 100644
--- a/pbs-tape/src/lib.rs
+++ b/pbs-tape/src/lib.rs
@@ -1,7 +1,6 @@
 use std::collections::HashSet;
 
 use anyhow::{Error, bail};
-use bitflags::bitflags;
 use endian_trait::Endian;
 use serde::{Deserialize, Serialize};
 use serde_json::Value;
@@ -20,6 +19,9 @@ pub use blocked_reader::BlockedReader;
 mod blocked_writer;
 pub use blocked_writer::BlockedWriter;
 
+mod tape_block;
+pub(crate) use tape_block::{BlockHeader, BlockHeaderFlags};
+
 mod tape_write;
 pub use tape_write::*;
 
@@ -49,41 +51,6 @@ pub const PROXMOX_BACKUP_MEDIA_LABEL_MAGIC_1_0: [u8; 8] = [42, 5, 191, 60, 176,
 // openssl::sha::sha256(b"Proxmox Backup MediaSet Label v1.0")
 pub const PROXMOX_BACKUP_MEDIA_SET_LABEL_MAGIC_1_0: [u8; 8] = [8, 96, 99, 249, 47, 151, 83, 216];
 
-/// Tape Block Header with data payload
-///
-/// All tape files are written as sequence of blocks.
-///
-/// Note: this struct is large, never put this on the stack!
-/// so we use an unsized type to avoid that.
-///
-/// Tape data block are always read/written with a fixed size
-/// (`PROXMOX_TAPE_BLOCK_SIZE`). But they may contain less data, so the
-/// header has an additional size field. For streams of blocks, there
-/// is a sequence number (`seq_nr`) which may be use for additional
-/// error checking.
-#[repr(C, packed)]
-pub struct BlockHeader {
-    /// fixed value `PROXMOX_TAPE_BLOCK_HEADER_MAGIC_1_0`
-    pub magic: [u8; 8],
-    pub flags: BlockHeaderFlags,
-    /// size as 3 bytes unsigned, little endian
-    pub size: [u8; 3],
-    /// block sequence number
-    pub seq_nr: u32,
-    pub payload: [u8],
-}
-
-bitflags! {
-    /// Header flags (e.g. `END_OF_STREAM` or `INCOMPLETE`)
-    #[derive(Clone, Copy, Debug, Default, Eq, PartialEq)]
-    pub struct BlockHeaderFlags: u8 {
-        /// Marks the last block in a stream.
-        const END_OF_STREAM = 0b00000001;
-        /// Mark multivolume streams (when set in the last block)
-        const INCOMPLETE    = 0b00000010;
-    }
-}
-
 #[derive(Endian, Copy, Clone, Debug)]
 #[repr(C, packed)]
 /// Media Content Header
@@ -152,46 +119,6 @@ impl MediaContentHeader {
     }
 }
 
-impl BlockHeader {
-    pub const SIZE: usize = PROXMOX_TAPE_BLOCK_SIZE;
-
-    /// Allocates a new instance on the heap
-    pub fn new() -> Box<Self> {
-        use std::alloc::{Layout, alloc_zeroed};
-
-        // align to PAGESIZE, so that we can use it with SG_IO
-        let page_size = unsafe { libc::sysconf(libc::_SC_PAGESIZE) } as usize;
-
-        let mut buffer = unsafe {
-            let ptr = alloc_zeroed(Layout::from_size_align(Self::SIZE, page_size).unwrap());
-            Box::from_raw(core::ptr::slice_from_raw_parts_mut(ptr, Self::SIZE - 16) as *mut Self)
-        };
-        buffer.magic = PROXMOX_TAPE_BLOCK_HEADER_MAGIC_1_0;
-        buffer
-    }
-
-    /// Set the `size` field
-    pub fn set_size(&mut self, size: usize) {
-        let size = size.to_le_bytes();
-        self.size.copy_from_slice(&size[..3]);
-    }
-
-    /// Returns the `size` field
-    pub fn size(&self) -> usize {
-        (self.size[0] as usize) + ((self.size[1] as usize) << 8) + ((self.size[2] as usize) << 16)
-    }
-
-    /// Set the `seq_nr` field
-    pub fn set_seq_nr(&mut self, seq_nr: u32) {
-        self.seq_nr = seq_nr.to_le();
-    }
-
-    /// Returns the `seq_nr` field
-    pub fn seq_nr(&self) -> u32 {
-        u32::from_le(self.seq_nr)
-    }
-}
-
 /// Changer element status.
 ///
 /// Drive and slots may be `Empty`, or contain some media, either
diff --git a/pbs-tape/src/tape_block.rs b/pbs-tape/src/tape_block.rs
new file mode 100644
index 000000000..4f9c2192f
--- /dev/null
+++ b/pbs-tape/src/tape_block.rs
@@ -0,0 +1,79 @@
+use bitflags::bitflags;
+
+use crate::PROXMOX_TAPE_BLOCK_HEADER_MAGIC_1_0;
+use crate::PROXMOX_TAPE_BLOCK_SIZE;
+
+/// Tape Block Header with data payload
+///
+/// All tape files are written as sequence of blocks.
+///
+/// Note: this struct is large, never put this on the stack!
+/// so we use an unsized type to avoid that.
+///
+/// Tape data block are always read/written with a fixed size
+/// (`PROXMOX_TAPE_BLOCK_SIZE`). But they may contain less data, so the
+/// header has an additional size field. For streams of blocks, there
+/// is a sequence number (`seq_nr`) which may be use for additional
+/// error checking.
+#[repr(C, packed)]
+pub struct BlockHeader {
+    /// fixed value `PROXMOX_TAPE_BLOCK_HEADER_MAGIC_1_0`
+    pub magic: [u8; 8],
+    pub flags: BlockHeaderFlags,
+    /// size as 3 bytes unsigned, little endian
+    pub size: [u8; 3],
+    /// block sequence number
+    pub seq_nr: u32,
+    pub payload: [u8],
+}
+
+bitflags! {
+    /// Header flags (e.g. `END_OF_STREAM` or `INCOMPLETE`)
+    #[derive(Clone, Copy, Debug, Default, Eq, PartialEq)]
+    pub struct BlockHeaderFlags: u8 {
+        /// Marks the last block in a stream.
+        const END_OF_STREAM = 0b00000001;
+        /// Mark multivolume streams (when set in the last block)
+        const INCOMPLETE    = 0b00000010;
+    }
+}
+
+impl BlockHeader {
+    pub const SIZE: usize = PROXMOX_TAPE_BLOCK_SIZE;
+
+    /// Allocates a new instance on the heap
+    pub fn new() -> Box<Self> {
+        use std::alloc::{Layout, alloc_zeroed};
+
+        // align to PAGESIZE, so that we can use it with SG_IO
+        let page_size = unsafe { libc::sysconf(libc::_SC_PAGESIZE) } as usize;
+
+        let mut buffer = unsafe {
+            let ptr = alloc_zeroed(Layout::from_size_align(Self::SIZE, page_size).unwrap());
+            Box::from_raw(core::ptr::slice_from_raw_parts_mut(ptr, Self::SIZE - 16) as *mut Self)
+        };
+        buffer.magic = PROXMOX_TAPE_BLOCK_HEADER_MAGIC_1_0;
+        buffer
+    }
+
+    /// Set the `size` field
+    pub fn set_size(&mut self, size: usize) {
+        let size = size.to_le_bytes();
+        self.size.copy_from_slice(&size[..3]);
+    }
+
+    /// Returns the `size` field
+    pub fn size(&self) -> usize {
+        (self.size[0] as usize) + ((self.size[1] as usize) << 8) + ((self.size[2] as usize) << 16)
+    }
+
+    /// Set the `seq_nr` field
+    pub fn set_seq_nr(&mut self, seq_nr: u32) {
+        self.seq_nr = seq_nr.to_le();
+    }
+
+    /// Returns the `seq_nr` field
+    pub fn seq_nr(&self) -> u32 {
+        u32::from_le(self.seq_nr)
+    }
+}
-- 
2.47.3





  parent reply	other threads:[~2026-08-21 14:02 UTC|newest]

Thread overview: 11+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-08-21 14:02 [PATCH proxmox{,-backup} v2 00/10] Fix Undefined Behavior in Tape Block Header Deallocation Max R. Carrara
2026-08-21 14:02 ` [PATCH proxmox v2 01/10] proxmox-alloc: introduce proxmox-alloc with `LayoutAwareBox<T>` type Max R. Carrara
2026-08-21 14:02 ` [PATCH proxmox v2 02/10] proxmox-alloc: document undefined behavior regarding custom allocs Max R. Carrara
2026-08-21 14:02 ` Max R. Carrara [this message]
2026-08-21 14:02 ` [PATCH proxmox-backup v2 04/10] tape: rename `BlockHeader` and `BlockHeaderFlags` Max R. Carrara
2026-08-21 14:02 ` [PATCH proxmox-backup v2 05/10] tape: blocked_{reader,writer}: rename `buffer` to `tape_block` Max R. Carrara
2026-08-21 14:02 ` [PATCH proxmox-backup v2 06/10] tape: tape block: represent tape block header with its own struct Max R. Carrara
2026-08-21 14:02 ` [PATCH proxmox-backup v2 07/10] tape: tape block: make `payload` field private Max R. Carrara
2026-08-21 14:02 ` [PATCH proxmox-backup v2 08/10] tape: blocked_{reader,writer}: remove haphazard `unsafe` blocks Max R. Carrara
2026-08-21 14:02 ` [PATCH proxmox-backup v2 09/10] tape: tape block: fix undefined behavior on tape block deallocation Max R. Carrara
2026-08-21 14:02 ` [PATCH proxmox-backup v2 10/10] tape: sgutils2: fix undefined behavior in dealloc of buffer Max R. Carrara

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=20260821140238.615302-4-m.carrara@proxmox.com \
    --to=m.carrara@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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
Service provided by Proxmox Server Solutions GmbH | Privacy | Legal