diff --git a/Makefile b/Makefile index 1df37159d..4fa66a8cc 100644 --- a/Makefile +++ b/Makefile @@ -140,6 +140,8 @@ clean: ## cleanup all generated assets @echo "Cleaning up all the generated files" @find . -name '*.test' | xargs rm -fv @find . -name '*~' | xargs rm -fv + @find . -name '.#*#' | xargs rm -fv + @find . -name '#*#' | xargs rm -fv @rm -rvf minio @rm -rvf build @rm -rvf release diff --git a/cmd/erasure-healing-common.go b/cmd/erasure-healing-common.go index 8423ef74f..b91bb70e9 100644 --- a/cmd/erasure-healing-common.go +++ b/cmd/erasure-healing-common.go @@ -180,9 +180,15 @@ func listOnlineDisks(disks []StorageAPI, partsMetadata []FileInfo, errs []error) } // Returns the latest updated FileInfo files and error in case of failure. -func getLatestFileInfo(ctx context.Context, partsMetadata []FileInfo, errs []error) (FileInfo, error) { +func getLatestFileInfo(ctx context.Context, partsMetadata []FileInfo, defaultParityCount int, errs []error) (FileInfo, error) { // There should be atleast half correct entries, if not return failure - reducedErr := reduceReadQuorumErrs(ctx, errs, objectOpIgnoredErrs, len(partsMetadata)/2) + expectedRQuorum := len(partsMetadata) / 2 + if defaultParityCount == 0 { + // if parity count is '0', we expected all entries to be present. + expectedRQuorum = len(partsMetadata) + } + + reducedErr := reduceReadQuorumErrs(ctx, errs, objectOpIgnoredErrs, expectedRQuorum) if reducedErr != nil { return FileInfo{}, reducedErr } diff --git a/cmd/erasure-healing-common_test.go b/cmd/erasure-healing-common_test.go index 3701f2775..e3e50d4cf 100644 --- a/cmd/erasure-healing-common_test.go +++ b/cmd/erasure-healing-common_test.go @@ -194,7 +194,7 @@ func TestListOnlineDisks(t *testing.T) { } partsMetadata, errs := readAllFileInfo(ctx, erasureDisks, bucket, object, "", false) - fi, err := getLatestFileInfo(ctx, partsMetadata, errs) + fi, err := getLatestFileInfo(ctx, partsMetadata, z.serverPools[0].sets[0].defaultParityCount, errs) if err != nil { t.Fatalf("Failed to getLatestFileInfo %v", err) } @@ -370,7 +370,7 @@ func TestListOnlineDisksSmallObjects(t *testing.T) { } partsMetadata, errs := readAllFileInfo(ctx, erasureDisks, bucket, object, "", true) - _, err = getLatestFileInfo(ctx, partsMetadata, errs) + _, err = getLatestFileInfo(ctx, partsMetadata, z.serverPools[0].sets[0].defaultParityCount, errs) if err != nil { t.Fatalf("Failed to getLatestFileInfo %v", err) } @@ -429,7 +429,7 @@ func TestListOnlineDisksSmallObjects(t *testing.T) { } partsMetadata, errs = readAllFileInfo(ctx, erasureDisks, bucket, object, "", true) - fi, err := getLatestFileInfo(ctx, partsMetadata, errs) + fi, err := getLatestFileInfo(ctx, partsMetadata, z.serverPools[0].sets[0].defaultParityCount, errs) if !errors.Is(err, errErasureReadQuorum) { t.Fatalf("Failed to getLatestFileInfo, expected %v, got %v", errErasureReadQuorum, err) } @@ -495,7 +495,7 @@ func TestDisksWithAllParts(t *testing.T) { t.Fatalf("Failed to read xl meta data %v", err) } - fi, err := getLatestFileInfo(ctx, partsMetadata, errs) + fi, err := getLatestFileInfo(ctx, partsMetadata, s.defaultParityCount, errs) if err != nil { t.Fatalf("Failed to get quorum consistent fileInfo %v", err) } diff --git a/cmd/erasure-healing_test.go b/cmd/erasure-healing_test.go index ed84a0bc0..c10f51ea3 100644 --- a/cmd/erasure-healing_test.go +++ b/cmd/erasure-healing_test.go @@ -601,7 +601,7 @@ func TestHealCorrectQuorum(t *testing.T) { erasureDisks := er.getDisks() fileInfos, errs := readAllFileInfo(ctx, erasureDisks, bucket, object, "", false) - nfi, err := getLatestFileInfo(ctx, fileInfos, errs) + nfi, err := getLatestFileInfo(ctx, fileInfos, er.defaultParityCount, errs) if errors.Is(err, errFileNotFound) { continue } @@ -628,7 +628,7 @@ func TestHealCorrectQuorum(t *testing.T) { } fileInfos, errs = readAllFileInfo(ctx, erasureDisks, minioMetaBucket, cfgFile, "", false) - nfi, err = getLatestFileInfo(ctx, fileInfos, errs) + nfi, err = getLatestFileInfo(ctx, fileInfos, er.defaultParityCount, errs) if errors.Is(err, errFileNotFound) { continue } @@ -734,7 +734,7 @@ func TestHealObjectCorruptedPools(t *testing.T) { } fileInfos, errs := readAllFileInfo(ctx, erasureDisks, bucket, object, "", false) - fi, err := getLatestFileInfo(ctx, fileInfos, errs) + fi, err := getLatestFileInfo(ctx, fileInfos, er.defaultParityCount, errs) if err != nil { t.Fatalf("Failed to getLatestFileInfo - %v", err) } @@ -762,7 +762,7 @@ func TestHealObjectCorruptedPools(t *testing.T) { } fileInfos, errs = readAllFileInfo(ctx, erasureDisks, bucket, object, "", false) - nfi, err := getLatestFileInfo(ctx, fileInfos, errs) + nfi, err := getLatestFileInfo(ctx, fileInfos, er.defaultParityCount, errs) if err != nil { t.Fatalf("Failed to getLatestFileInfo - %v", err) } @@ -793,7 +793,7 @@ func TestHealObjectCorruptedPools(t *testing.T) { } fileInfos, errs = readAllFileInfo(ctx, erasureDisks, bucket, object, "", false) - nfi, err = getLatestFileInfo(ctx, fileInfos, errs) + nfi, err = getLatestFileInfo(ctx, fileInfos, er.defaultParityCount, errs) if err != nil { t.Fatalf("Failed to getLatestFileInfo - %v", err) } @@ -897,7 +897,7 @@ func TestHealObjectCorruptedXLMeta(t *testing.T) { // Test 1: Remove the object backend files from the first disk. fileInfos, errs := readAllFileInfo(ctx, erasureDisks, bucket, object, "", false) - fi, err := getLatestFileInfo(ctx, fileInfos, errs) + fi, err := getLatestFileInfo(ctx, fileInfos, er.defaultParityCount, errs) if err != nil { t.Fatalf("Failed to getLatestFileInfo - %v", err) } @@ -920,7 +920,7 @@ func TestHealObjectCorruptedXLMeta(t *testing.T) { } fileInfos, errs = readAllFileInfo(ctx, erasureDisks, bucket, object, "", false) - nfi1, err := getLatestFileInfo(ctx, fileInfos, errs) + nfi1, err := getLatestFileInfo(ctx, fileInfos, er.defaultParityCount, errs) if err != nil { t.Fatalf("Failed to getLatestFileInfo - %v", err) } @@ -943,7 +943,7 @@ func TestHealObjectCorruptedXLMeta(t *testing.T) { } fileInfos, errs = readAllFileInfo(ctx, erasureDisks, bucket, object, "", false) - nfi2, err := getLatestFileInfo(ctx, fileInfos, errs) + nfi2, err := getLatestFileInfo(ctx, fileInfos, er.defaultParityCount, errs) if err != nil { t.Fatalf("Failed to getLatestFileInfo - %v", err) } @@ -1041,7 +1041,7 @@ func TestHealObjectCorruptedParts(t *testing.T) { secondDisk := erasureDisks[1] fileInfos, errs := readAllFileInfo(ctx, erasureDisks, bucket, object, "", false) - fi, err := getLatestFileInfo(ctx, fileInfos, errs) + fi, err := getLatestFileInfo(ctx, fileInfos, er.defaultParityCount, errs) if err != nil { t.Fatalf("Failed to getLatestFileInfo - %v", err) } diff --git a/cmd/erasure-metadata.go b/cmd/erasure-metadata.go index c700391e6..04c9e369b 100644 --- a/cmd/erasure-metadata.go +++ b/cmd/erasure-metadata.go @@ -400,17 +400,17 @@ func writeUniqueFileInfo(ctx context.Context, disks []StorageAPI, bucket, prefix // readQuorum is the min required disks to read data. // writeQuorum is the min required disks to write data. func objectQuorumFromMeta(ctx context.Context, partsMetaData []FileInfo, errs []error, defaultParityCount int) (objectReadQuorum, objectWriteQuorum int, err error) { - if defaultParityCount == 0 { - return 1, 1, nil - } - // get the latest updated Metadata and a count of all the latest updated FileInfo(s) - latestFileInfo, err := getLatestFileInfo(ctx, partsMetaData, errs) + latestFileInfo, err := getLatestFileInfo(ctx, partsMetaData, defaultParityCount, errs) if err != nil { return 0, 0, err } if latestFileInfo.Deleted { + // special case when parity is '0' + if defaultParityCount == 0 { + return len(partsMetaData), len(partsMetaData), nil + } // 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.