From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from gate001.proxmox.com (gate001.proxmox.com [45.144.208.40]) by lore.proxmox.com (Postfix) with ESMTPS id 2F09C1FF0E1 for ; Mon, 13 Jul 2026 10:15:52 +0200 (CEST) Received: from gate001.proxmox.com (localhost.localdomain [127.0.0.1]) by gate001.proxmox.com (Proxmox) with ESMTP id C82EA2147E; Mon, 13 Jul 2026 10:15:46 +0200 (CEST) From: Shan Shaji To: pbs-devel@lists.proxmox.com Subject: [PATCH proxmox-backup 4/6] client: backup_stats: move `uploaded_len` counter to `UploadCounters` Date: Mon, 13 Jul 2026 10:15:27 +0200 Message-ID: <20260713081529.62859-5-s.shaji@proxmox.com> X-Mailer: git-send-email 2.47.3 In-Reply-To: <20260713081529.62859-1-s.shaji@proxmox.com> References: <20260713081529.62859-1-s.shaji@proxmox.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Bm-Milter-Handled: 55990f41-d878-4baa-be0a-ee34c49e34d2 X-Bm-Transport-Timestamp: 1783930528061 X-SPAM-LEVEL: Spam detection results: 0 AWL 0.321 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_LOW -0.7 Sender listed at https://www.dnswl.org/, low 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: GGTFXAH3J4VLUFZQKMKSE3OGKF6PK43P X-Message-ID-Hash: GGTFXAH3J4VLUFZQKMKSE3OGKF6PK43P X-MailFrom: s.shaji@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: earlier the uploaded size was tracked using `uploaded_len` Arc counter. Since the uploaded size needs to be accessible inside the progress logs in the later commit, move the `uploaded_len` field to `UploadCounters`. This was done, in order to avoid passing the variable as a separate parameter through the callback. Signed-off-by: Shan Shaji --- pbs-client/src/backup_stats.rs | 12 ++++++++++++ pbs-client/src/backup_writer.rs | 12 +++++------- 2 files changed, 17 insertions(+), 7 deletions(-) diff --git a/pbs-client/src/backup_stats.rs b/pbs-client/src/backup_stats.rs index d7c13784b..6aceee331 100644 --- a/pbs-client/src/backup_stats.rs +++ b/pbs-client/src/backup_stats.rs @@ -50,6 +50,7 @@ pub(crate) struct UploadCounters { injected_stream_len: Arc, reused_stream_len: Arc, total_stream_len: Arc, + uploaded_len: Arc, } impl UploadCounters { @@ -63,6 +64,7 @@ impl UploadCounters { injected_stream_len: Arc::new(AtomicUsize::new(0)), reused_stream_len: Arc::new(AtomicUsize::new(0)), total_stream_len: Arc::new(AtomicUsize::new(0)), + uploaded_len: Arc::new(AtomicUsize::new(0)), } } @@ -101,6 +103,16 @@ impl UploadCounters { self.total_stream_len.load(Ordering::SeqCst) } + #[inline(always)] + pub(crate) fn add_uploaded_len(&mut self, size: usize) { + self.uploaded_len.fetch_add(size, Ordering::SeqCst); + } + + #[inline(always)] + pub fn uploaded_len(&self) -> usize { + self.uploaded_len.load(Ordering::SeqCst) + } + /// Convert the counters to [`UploadStats`], including given archive checksum and runtime. #[inline(always)] pub(crate) fn to_upload_stats(&self, csum: [u8; 32], duration: Duration) -> UploadStats { diff --git a/pbs-client/src/backup_writer.rs b/pbs-client/src/backup_writer.rs index f0744ecaf..34d8db90b 100644 --- a/pbs-client/src/backup_writer.rs +++ b/pbs-client/src/backup_writer.rs @@ -1,6 +1,5 @@ use std::collections::HashSet; use std::future::Future; -use std::sync::atomic::{AtomicUsize, Ordering}; use std::sync::{Arc, Mutex}; use std::time::Instant; @@ -588,7 +587,7 @@ impl BackupWriter { h2: H2Client, wid: u64, path: String, - uploaded: Arc, + upload_counters: UploadCounters, ) -> (UploadQueueSender, UploadResultReceiver) { let (verify_queue_tx, verify_queue_rx) = mpsc::channel(64); let (verify_result_tx, verify_result_rx) = oneshot::channel(); @@ -606,10 +605,10 @@ impl BackupWriter { .map_err(Error::from) .and_then(H2Client::h2api_response) .and_then({ - let uploaded = uploaded.clone(); + let mut counters = upload_counters.clone(); move |_result| { // account for uploaded bytes for progress output - uploaded.fetch_add(response.size, Ordering::SeqCst); + counters.add_uploaded_len(response.size); future::ok(MergedChunkInfo::Known(list)) } }) @@ -871,10 +870,9 @@ impl BackupWriter { let upload_chunk_path = format!("{prefix}_chunk"); let start_time = std::time::Instant::now(); - let uploaded_len = Arc::new(AtomicUsize::new(0)); let (upload_queue, upload_result) = - Self::append_chunk_queue(h2.clone(), wid, append_chunk_path, uploaded_len.clone()); + Self::append_chunk_queue(h2.clone(), wid, append_chunk_path, counters.clone()); let progress_handle = if archive.ends_with(".img.fidx") || archive.ends_with(".pxar.didx") @@ -886,7 +884,7 @@ impl BackupWriter { tokio::time::sleep(tokio::time::Duration::from_secs(60)).await; let size = HumanByte::from(counters.total_stream_len()); - let size_uploaded = HumanByte::from(uploaded_len.load(Ordering::SeqCst)); + let size_uploaded = HumanByte::from(counters.uploaded_len()); let elapsed = TimeSpan::from(start_time.elapsed()); info!("processed {size} in {elapsed}, uploaded {size_uploaded}"); -- 2.47.3