From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from gate001.proxmox.com (gate001.proxmox.com [IPv6:2a0f:8001:1:32::40]) by lore.proxmox.com (Postfix) with ESMTPS id 9765C1FF0AA for ; Fri, 21 Aug 2026 16:03:04 +0200 (CEST) Received: from gate001.proxmox.com (localhost.localdomain [127.0.0.1]) by gate001.proxmox.com (Proxmox) with ESMTP id 7778821617; Fri, 21 Aug 2026 16:03:00 +0200 (CEST) From: "Max R. Carrara" To: pbs-devel@lists.proxmox.com Subject: [PATCH proxmox-backup v2 07/10] tape: tape block: make `payload` field private Date: Fri, 21 Aug 2026 16:02:31 +0200 Message-ID: <20260821140238.615302-8-m.carrara@proxmox.com> X-Mailer: git-send-email 2.47.3 In-Reply-To: <20260821140238.615302-1-m.carrara@proxmox.com> References: <20260821140238.615302-1-m.carrara@proxmox.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Bm-Milter-Handled: 55990f41-d878-4baa-be0a-ee34c49e34d2 X-Bm-Transport-Timestamp: 1787320946341 X-SPAM-LEVEL: Spam detection results: 0 AWL 0.675 Adjusted score from AWL reputation of From: address DMARC_MISSING 0.1 Missing DMARC policy KAM_DMARC_STATUS 0.01 Test Rule for DKIM or SPF Failure with Strict Alignment (newer systems) RCVD_IN_DNSWL_MED -2.3 Sender listed at https://www.dnswl.org/, medium trust SPF_HELO_NONE 0.001 SPF: HELO does not publish an SPF Record SPF_PASS -0.001 SPF: sender matches SPF record Message-ID-Hash: TUG7YCSV3SLKEE4UXK7AG2KN6FMN3MTZ X-Message-ID-Hash: TUG7YCSV3SLKEE4UXK7AG2KN6FMN3MTZ X-MailFrom: m.carrara@proxmox.com X-Mailman-Rule-Misses: dmarc-mitigation; no-senders; approved; loop; banned-address; emergency; member-moderation; nonmember-moderation; administrivia; implicit-dest; max-recipients; max-size; news-moderation; no-subject; digests; suspicious-header X-Mailman-Version: 3.3.10 Precedence: list List-Id: Proxmox Backup Server development discussion List-Help: List-Owner: List-Post: List-Subscribe: List-Unsubscribe: While all cases where we directly use the `payload` field are fine, direct field access should IMO be used as sparingly as possible, as the field *itself* is otherwise part of a type's public API. Therefore, make the `payload` field of `TapeBlock` private and add corresponding getters to allow obtaining it as a (mutable) slice. Signed-off-by: Max R. Carrara --- pbs-tape/src/blocked_reader.rs | 11 +++++------ pbs-tape/src/blocked_writer.rs | 13 ++++++++----- pbs-tape/src/tape_block.rs | 12 +++++++++++- 3 files changed, 24 insertions(+), 12 deletions(-) diff --git a/pbs-tape/src/blocked_reader.rs b/pbs-tape/src/blocked_reader.rs index cf8150ba3..6b1e3c692 100644 --- a/pbs-tape/src/blocked_reader.rs +++ b/pbs-tape/src/blocked_reader.rs @@ -81,11 +81,11 @@ impl BlockedReader { let size = tape_block.size(); let found_end_marker = tape_block.flags().contains(TapeBlockFlags::END_OF_STREAM); - if size > tape_block.payload.len() { + if size > tape_block.payload().len() { proxmox_lang::io_bail!( "detected tape block with wrong payload size ({} > {}", size, - tape_block.payload.len() + tape_block.payload().len() ); } else if size == 0 && !found_end_marker { proxmox_lang::io_bail!("detected tape block with zero payload size"); @@ -130,7 +130,7 @@ impl BlockedReader { Ok(()) => { /* ok */ } Err(BlockReadError::EndOfFile) => { self.got_eod = true; - self.read_pos = self.tape_block.payload.len(); + self.read_pos = self.tape_block.payload().len(); if !self.found_end_marker && check_end_marker { proxmox_lang::io_bail!("detected tape stream without end marker"); } @@ -228,9 +228,8 @@ impl Read for BlockedReader { } else { rest as usize }; - buffer[..copy_len].copy_from_slice( - &self.tape_block.payload[self.read_pos..(self.read_pos + copy_len)], - ); + let payload = self.tape_block.payload(); + buffer[..copy_len].copy_from_slice(&payload[self.read_pos..(self.read_pos + copy_len)]); self.read_pos += copy_len; Ok(copy_len) } diff --git a/pbs-tape/src/blocked_writer.rs b/pbs-tape/src/blocked_writer.rs index 5e94f54b8..0d5d10147 100644 --- a/pbs-tape/src/blocked_writer.rs +++ b/pbs-tape/src/blocked_writer.rs @@ -69,16 +69,18 @@ impl BlockedWriter { return Ok(0); } - let rest = self.tape_block.payload.len() - self.buffer_pos; + let payload = self.tape_block.payload_mut(); + let payload_len = payload.len(); + + let rest = payload_len - self.buffer_pos; let bytes = if data.len() < rest { data.len() } else { rest }; - self.tape_block.payload[self.buffer_pos..(self.buffer_pos + bytes)] - .copy_from_slice(&data[..bytes]); + payload[self.buffer_pos..(self.buffer_pos + bytes)].copy_from_slice(&data[..bytes]); let rest = rest - bytes; if rest == 0 { self.tape_block.set_flags(TapeBlockFlags::empty()); - self.tape_block.set_size(self.tape_block.payload.len()); + self.tape_block.set_size(payload_len); self.tape_block.set_seq_nr(self.seq_nr); self.seq_nr += 1; let leom = Self::write_block(&self.tape_block, &mut self.writer)?; @@ -115,7 +117,8 @@ impl TapeWrite for BlockedWriter { /// Note: This may write an empty block just including the /// END_OF_STREAM flag. fn finish(&mut self, incomplete: bool) -> Result { - vec::clear(&mut self.tape_block.payload[self.buffer_pos..]); + let payload = self.tape_block.payload_mut(); + vec::clear(&mut payload[self.buffer_pos..]); let mut flags = TapeBlockFlags::END_OF_STREAM; if incomplete { flags |= TapeBlockFlags::INCOMPLETE; diff --git a/pbs-tape/src/tape_block.rs b/pbs-tape/src/tape_block.rs index 2db5ed137..c73efafa7 100644 --- a/pbs-tape/src/tape_block.rs +++ b/pbs-tape/src/tape_block.rs @@ -33,7 +33,7 @@ static_assert_size!(TapeBlockHeader, 16); #[repr(C, packed)] pub struct TapeBlock { header: TapeBlockHeader, - pub payload: [u8], + payload: [u8], } bitflags! { @@ -107,4 +107,14 @@ impl TapeBlock { pub fn set_seq_nr(&mut self, seq_nr: u32) { self.header.seq_nr = seq_nr.to_le(); } + + /// Returns the tape block's data payload as a byte slice. + pub fn payload(&self) -> &[u8] { + &self.payload + } + + /// Returns the tape block's data payload as a mutable byte slice. + pub fn payload_mut(&mut self) -> &mut [u8] { + &mut self.payload + } } -- 2.47.3