From 4c659b6f41c3593a0ce6b9a5c07d28d14db515bc Mon Sep 17 00:00:00 2001 From: Chris Lu Date: Tue, 17 Mar 2026 19:00:48 -0700 Subject: [PATCH] Fix free_volume_count to use EC shard count matching Go Was counting EC volumes instead of EC shards, which underestimates EC space usage. One EC volume with 14 shards uses ~1.4 volume slots, not 1. Now uses Go's formula: ((max - volumes) * DataShardsCount - ecShardCount) / DataShardsCount. --- seaweed-volume/src/storage/disk_location.rs | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/seaweed-volume/src/storage/disk_location.rs b/seaweed-volume/src/storage/disk_location.rs index 9358cedea..b336d0dd4 100644 --- a/seaweed-volume/src/storage/disk_location.rs +++ b/seaweed-volume/src/storage/disk_location.rs @@ -450,13 +450,17 @@ impl DiskLocation { } /// Number of free volume slots. - /// Matches Go's FindFreeLocation: accounts for both regular volumes - /// and EC shards when computing available slots. + /// Matches Go's FindFreeLocation formula: + /// free = ((MaxVolumeCount - VolumesLen()) * DataShardsCount - EcShardCount()) / DataShardsCount pub fn free_volume_count(&self) -> i32 { + use crate::storage::erasure_coding::ec_shard::DATA_SHARDS_COUNT; let max = self.max_volume_count.load(Ordering::Relaxed); - let used = self.volumes.len() as i32 + self.ec_volumes.len() as i32; - if max > used { - max - used + let free_count = (max as i64 - self.volumes.len() as i64) + * DATA_SHARDS_COUNT as i64 + - self.ec_shard_count() as i64; + let effective_free = free_count / DATA_SHARDS_COUNT as i64; + if effective_free > 0 { + effective_free as i32 } else { 0 }