From d182be6a9e60f796b3d3b847665615c842cd91df Mon Sep 17 00:00:00 2001 From: Chris Lu Date: Mon, 26 Oct 2026 23:18:43 -0700 Subject: [PATCH] s3api: cap SOSAPI capacity by the reported physical disk bytes (#12118) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit calculateClusterCapacity multiplies advertised volume slots by the volume size limit. Slot counts are an admission bound rather than a capacity measurement — an explicit -max can be set higher than the volumes a disk actually fills — so a small disk can report more total and available capacity than it physically has. Bound both numbers by the per-disk filesystem counters the volume server already reports in its heartbeat, falling back to the slot estimate only when they are absent. Generated with [Devin](https://devin.ai) Co-authored-by: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com> --- weed/s3api/s3api_sosapi.go | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/weed/s3api/s3api_sosapi.go b/weed/s3api/s3api_sosapi.go index f1c635e7ae..67d1eac813 100644 --- a/weed/s3api/s3api_sosapi.go +++ b/weed/s3api/s3api_sosapi.go @@ -216,14 +216,23 @@ func collectBucketUsageFromTopology(t *master_pb.TopologyInfo, collectionName st } // calculateClusterCapacity sums up the total and available capacity of the entire cluster. +// Slot counts are an admission bound, not a capacity measurement — -max can +// be set higher than the volumes a disk actually fills — so a disk that +// reports physical counters is capped by them. func calculateClusterCapacity(t *master_pb.TopologyInfo, volumeSizeLimitMb uint64) (total, available int64) { volumeSize := int64(volumeSizeLimitMb) * 1024 * 1024 for _, dc := range t.DataCenterInfos { for _, r := range dc.RackInfos { for _, dn := range r.DataNodeInfos { for _, disk := range dn.DiskInfos { - total += int64(disk.MaxVolumeCount) * volumeSize - available += int64(disk.FreeVolumeCount) * volumeSize + slotTotal := int64(disk.MaxVolumeCount) * volumeSize + slotFree := int64(disk.FreeVolumeCount) * volumeSize + if disk.DiskTotalBytes > 0 { + slotTotal = min(slotTotal, int64(disk.DiskTotalBytes)) + slotFree = min(slotFree, int64(disk.DiskFreeBytes)) + } + total += slotTotal + available += slotFree } } }