[PATCH proxmox v7 02/34] s3-client: add counters for upload/download traffic

Christian Ebner
2026-04-01T13:48:59Z

In addition to accounting for requests, also allow to track the
number of bytes uploaded or downloaded via the s3 clients. Just
like for request counters, zero them on reset.

With the intention to estimate shared upload/download bandwidth in
Proxmox Backup Server as well as easily estimate the total traffic
volume.

Signed-off-by: Christian Ebner <c.ebner@proxmox.com>
---
.../src/shared_request_counters.rs | 69 +++++++++++++++++++
1 file changed, 69 insertions(+)

diff --git a/proxmox-s3-client/src/shared_request_counters.rs b/proxmox-s3-client/src/shared_request_counters.rs
index e6820a04..1ffad4bc 100644
--- a/proxmox-s3-client/src/shared_request_counters.rs
+++ b/proxmox-s3-client/src/shared_request_counters.rs
@@ -37,6 +37,9 @@ struct RequestCounters {
put: AlignedAtomic,
head: AlignedAtomic,
post: AlignedAtomic,
+ // traffic in bytes
+ upload: AlignedAtomic,
+ download: AlignedAtomic,
}

impl Init for RequestCounters {
@@ -83,8 +86,34 @@ impl RequestCounters {
head: self.head.0.swap(0, ordering),
post: self.post.0.swap(0, ordering),
put: self.put.0.swap(0, ordering),
+ upload: self.upload.0.swap(0, ordering),
+ download: self.download.0.swap(0, ordering),
}
}
+
+ /// Account for new upload traffic.
+ ///
+ /// Returns the previously stored value.
+ pub fn add_upload_traffic(&self, count: u64, ordering: Ordering) -> u64 {
+ self.upload.0.fetch_add(count, ordering)
+ }
+
+ /// Returns upload traffic count.
+ pub fn get_upload_traffic(&self, ordering: Ordering) -> u64 {
+ self.upload.0.load(ordering)
+ }
+
+ /// Account for new download traffic.
+ ///
+ /// Returns the previously stored value.
+ pub fn add_download_traffic(&self, count: u64, ordering: Ordering) -> u64 {
+ self.download.0.fetch_add(count, ordering)
+ }
+
+ /// Returns download traffic count.
+ pub fn get_download_traffic(&self, ordering: Ordering) -> u64 {
+ self.download.0.load(ordering)
+ }
}

/// Size of the padding to align the mmapped request counters to 4k default
@@ -186,6 +215,42 @@ impl SharedRequestCounters {
pub fn reset(&self, ordering: Ordering) -> RequestCounterValues {
self.shared_memory.data().counters.reset(ordering)
}
+
+ /// Account for new upload traffic.
+ ///
+ /// Returns the previously stored value.
+ pub fn add_upload_traffic(&self, count: u64, ordering: Ordering) -> u64 {
+ self.shared_memory
+ .data()
+ .counters
+ .add_upload_traffic(count, ordering)
+ }
+
+ /// Returns upload traffic count.
+ pub fn get_upload_traffic(&self, ordering: Ordering) -> u64 {
+ self.shared_memory
+ .data()
+ .counters
+ .get_upload_traffic(ordering)
+ }
+
+ /// Account for new download traffic.
+ ///
+ /// Returns the previously stored value.
+ pub fn add_download_traffic(&self, count: u64, ordering: Ordering) -> u64 {
+ self.shared_memory
+ .data()
+ .counters
+ .add_download_traffic(count, ordering)
+ }
+
+ /// Returns download traffic count.
+ pub fn get_download_traffic(&self, ordering: Ordering) -> u64 {
+ self.shared_memory
+ .data()
+ .counters
+ .get_download_traffic(ordering)
+ }
}

/// Current value of the individual request counters.
@@ -202,4 +267,8 @@ pub struct RequestCounterValues {
pub head: u64,
/// number of POST requests
pub post: u64,
+ /// bytes uploaded
+ pub upload: u64,
+ /// bytes downloaded
+ pub download: u64,
}
--
2.47.3