From 0256dae6576af19f6357b7d97fa935e7a62058ce Mon Sep 17 00:00:00 2001 From: Harshavardhana Date: Fri, 4 Feb 2022 02:47:36 -0800 Subject: [PATCH] fix: quorum requirement for DeleteMarkers and parity upgraded objects (#14248) DeleteMarkers do not have a default quorum, i.e it is possible that DeleteMarkers were created with n/2+1 quorum as well to make sure that we satisfy situations such as those we need to make sure delete markers only expect n/2 read quorum. Additionally we should also look at additional metadata on the actual objects that might have been "erasure" upgraded with new parity when disks are down. In such a scenario do not default to the standard storage class parity, instead use the parityBlocks present on the FileInfo to ensure that we are dealing with the correct quorum for READs and DELETEs. --- cmd/erasure-metadata.go | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/cmd/erasure-metadata.go b/cmd/erasure-metadata.go index 7c1ae2314..365f43892 100644 --- a/cmd/erasure-metadata.go +++ b/cmd/erasure-metadata.go @@ -406,11 +406,27 @@ func objectQuorumFromMeta(ctx context.Context, partsMetaData []FileInfo, errs [] return 0, 0, err } + if latestFileInfo.Deleted { + // For delete markers do not use 'defaultParityCount' as it is not expected to be the case. + // Use maximum allowed read quorum instead, writeQuorum+1 is returned for compatibility sake + // but there are no callers that shall be using this. + readQuorum := len(partsMetaData) / 2 + return readQuorum, readQuorum + 1, nil + } + parityBlocks := globalStorageClass.GetParityForSC(latestFileInfo.Metadata[xhttp.AmzStorageClass]) if parityBlocks <= 0 { parityBlocks = defaultParityCount } + // For erasure code upgraded objects choose the parity + // blocks saved internally, instead of 'defaultParityCount' + if _, ok := latestFileInfo.Metadata[minIOErasureUpgraded]; ok { + if latestFileInfo.Erasure.ParityBlocks != 0 { + parityBlocks = latestFileInfo.Erasure.ParityBlocks + } + } + dataBlocks := latestFileInfo.Erasure.DataBlocks if dataBlocks == 0 { dataBlocks = len(partsMetaData) - parityBlocks