fix(ec): pass per-volume data-shard count to the parity-shard split (#9781)

* fix(ec): pass per-volume data-shard count to the parity-shard split

ShardsInfo.DeleteParityShards/MinusParityShards looped ids 10..13, assuming
the fixed 10+4 layout. For a non-default ratio this splits data vs parity
wrong — a wide ratio (12+4, 16+6) drops real data ids >= 10, which breaks
ec.decode. They now take a dataShards argument (<= 0 falls back to
DataShardsCount) and clear ids dataShards..MaxShardCount. ec.decode threads
the data-shard count from collectEcNodeShardsInfo to both split call sites,
and admin LogicalSize passes DataShardsCount.

Also: EC cleanup now sets an explicit per-disk storage impact
(-len(ShardIds)) instead of falling back to the TotalShardsCount constant,
so freed-capacity accounting matches the shards actually removed.

OSS is always 10+4, so behavior is unchanged here; this keeps the split
ratio-correct and the API aligned with the enterprise per-volume override.
Adds parity-split ratio tests.

* ec: clear parity shards in one locked pass

Address review: DeleteParityShards looped si.Delete, taking the lock once per
id. shards is sorted by Id and shardBits is a bitmap, so mask off the high
bits and truncate the sorted slice at the first parity id (binary search) under
a single lock. Preserves the dataShards<=0 -> DataShardsCount default.
This commit is contained in:
Chris Lu
2026-06-01 19:25:15 -07:00
committed by GitHub
parent f410d975c7
commit ca81c0c525
8 changed files with 100 additions and 24 deletions
+1 -1
View File
@@ -359,7 +359,7 @@ func verifyEcShardsBeforeDelete(commandEnv *CommandEnv, volumeIds []needle.Volum
lastErr = nil
for _, vid := range volumeIds {
nodeShards := collectEcNodeShardsInfo(topoInfo, vid, diskType)
nodeShards, _ := collectEcNodeShardsInfo(topoInfo, vid, diskType)
var union erasure_coding.ShardBits
for _, info := range nodeShards {