From cacdeca8cc8357ecee3d8245707526011df781f3 Mon Sep 17 00:00:00 2001 From: Harshavardhana Date: Mon, 24 May 2021 18:31:56 -0700 Subject: [PATCH] fix: return error for unexpected quorum in pickValidFileInfo (#12363) --- cmd/erasure-metadata.go | 18 ++++++++++++++---- cmd/erasure-metadata_test.go | 36 +++++++++++++++++++++++------------- 2 files changed, 37 insertions(+), 17 deletions(-) diff --git a/cmd/erasure-metadata.go b/cmd/erasure-metadata.go index 095f3e657..ce6b9960a 100644 --- a/cmd/erasure-metadata.go +++ b/cmd/erasure-metadata.go @@ -239,7 +239,11 @@ func (fi FileInfo) ObjectToPartOffset(ctx context.Context, offset int64) (partIn return 0, 0, InvalidRange{} } -func findFileInfoInQuorum(ctx context.Context, metaArr []FileInfo, modTime time.Time, dataDir string, quorum int) (xmv FileInfo, e error) { +func findFileInfoInQuorum(ctx context.Context, metaArr []FileInfo, modTime time.Time, dataDir string, quorum int) (FileInfo, error) { + // with less quorum return error. + if quorum < 2 { + return FileInfo{}, errErasureReadQuorum + } metaHashes := make([]string, len(metaArr)) h := sha256.New() for i, meta := range metaArr { @@ -278,7 +282,9 @@ func findFileInfoInQuorum(ctx context.Context, metaArr []FileInfo, modTime time. for i, hash := range metaHashes { if hash == maxHash { - return metaArr[i], nil + if metaArr[i].IsValid() { + return metaArr[i], nil + } } } @@ -287,7 +293,7 @@ func findFileInfoInQuorum(ctx context.Context, metaArr []FileInfo, modTime time. // pickValidFileInfo - picks one valid FileInfo content and returns from a // slice of FileInfo. -func pickValidFileInfo(ctx context.Context, metaArr []FileInfo, modTime time.Time, dataDir string, quorum int) (xmv FileInfo, e error) { +func pickValidFileInfo(ctx context.Context, metaArr []FileInfo, modTime time.Time, dataDir string, quorum int) (FileInfo, error) { return findFileInfoInQuorum(ctx, metaArr, modTime, dataDir, quorum) } @@ -329,12 +335,16 @@ func objectQuorumFromMeta(ctx context.Context, partsMetaData []FileInfo, errs [] return 0, 0, err } - dataBlocks := latestFileInfo.Erasure.DataBlocks + if !latestFileInfo.IsValid() { + return 0, 0, errErasureReadQuorum + } + parityBlocks := globalStorageClass.GetParityForSC(latestFileInfo.Metadata[xhttp.AmzStorageClass]) if parityBlocks <= 0 { parityBlocks = defaultParityCount } + dataBlocks := len(partsMetaData) - parityBlocks writeQuorum := dataBlocks if dataBlocks == parityBlocks { writeQuorum++ diff --git a/cmd/erasure-metadata_test.go b/cmd/erasure-metadata_test.go index 723cda29b..8ec3d0d41 100644 --- a/cmd/erasure-metadata_test.go +++ b/cmd/erasure-metadata_test.go @@ -176,29 +176,39 @@ func TestFindFileInfoInQuorum(t *testing.T) { } tests := []struct { - fis []FileInfo - modTime time.Time - dataDir string - expectedErr error + fis []FileInfo + modTime time.Time + dataDir string + expectedErr error + expectedQuorum int }{ { - fis: getNFInfo(16, 16, 1603863445, "36a21454-a2ca-11eb-bbaa-93a81c686f21"), - modTime: time.Unix(1603863445, 0), - dataDir: "36a21454-a2ca-11eb-bbaa-93a81c686f21", - expectedErr: nil, + fis: getNFInfo(16, 16, 1603863445, "36a21454-a2ca-11eb-bbaa-93a81c686f21"), + modTime: time.Unix(1603863445, 0), + dataDir: "36a21454-a2ca-11eb-bbaa-93a81c686f21", + expectedErr: nil, + expectedQuorum: 8, }, { - fis: getNFInfo(16, 7, 1603863445, "36a21454-a2ca-11eb-bbaa-93a81c686f21"), - modTime: time.Unix(1603863445, 0), - dataDir: "36a21454-a2ca-11eb-bbaa-93a81c686f21", - expectedErr: errErasureReadQuorum, + fis: getNFInfo(16, 7, 1603863445, "36a21454-a2ca-11eb-bbaa-93a81c686f21"), + modTime: time.Unix(1603863445, 0), + dataDir: "36a21454-a2ca-11eb-bbaa-93a81c686f21", + expectedErr: errErasureReadQuorum, + expectedQuorum: 8, + }, + { + fis: getNFInfo(16, 16, 1603863445, "36a21454-a2ca-11eb-bbaa-93a81c686f21"), + modTime: time.Unix(1603863445, 0), + dataDir: "36a21454-a2ca-11eb-bbaa-93a81c686f21", + expectedErr: errErasureReadQuorum, + expectedQuorum: 0, }, } for _, test := range tests { test := test t.Run("", func(t *testing.T) { - _, err := findFileInfoInQuorum(context.Background(), test.fis, test.modTime, test.dataDir, 8) + _, err := findFileInfoInQuorum(context.Background(), test.fis, test.modTime, test.dataDir, test.expectedQuorum) if err != test.expectedErr { t.Errorf("Expected %s, got %s", test.expectedErr, err) }