From c49a80db412027ae49637f2e3696175f90a9360d Mon Sep 17 00:00:00 2001 From: Krishna Srinivas <634494+krishnasrinivas@users.noreply.github.com> Date: Mon, 26 Oct 2020 16:19:42 -0700 Subject: [PATCH] fix: use meta.Erasure.Index for GetObject() to reconstruct object (#10764) --- cmd/erasure-metadata-utils.go | 24 ++++++++++++++++++++++++ cmd/erasure-metadata.go | 3 ++- cmd/erasure-metadata_test.go | 3 +++ cmd/erasure-object.go | 5 +++-- 4 files changed, 32 insertions(+), 3 deletions(-) diff --git a/cmd/erasure-metadata-utils.go b/cmd/erasure-metadata-utils.go index dca0212bc..e3c0ab295 100644 --- a/cmd/erasure-metadata-utils.go +++ b/cmd/erasure-metadata-utils.go @@ -153,6 +153,30 @@ func readVersionFromDisks(ctx context.Context, disks []StorageAPI, bucket, objec return metadataArray, g.Wait() } +// Return disks ordered by the meta.Erasure.Index information. +func shuffleDisksByIndex(disks []StorageAPI, metaArr []FileInfo) (shuffledDisks []StorageAPI) { + shuffledDisks = make([]StorageAPI, len(disks)) + for i, meta := range metaArr { + if disks[i] == nil { + continue + } + shuffledDisks[meta.Erasure.Index-1] = disks[i] + } + return shuffledDisks +} + +// Return FileInfo slice ordered by the meta.Erasure.Index information. +func shufflePartsMetadataByIndex(disks []StorageAPI, metaArr []FileInfo) []FileInfo { + newMetaArr := make([]FileInfo, len(disks)) + for i, meta := range metaArr { + if disks[i] == nil { + continue + } + newMetaArr[meta.Erasure.Index-1] = metaArr[i] + } + return newMetaArr +} + // Return shuffled partsMetadata depending on distribution. func shufflePartsMetadata(partsMetadata []FileInfo, distribution []int) (shuffledPartsMetadata []FileInfo) { if distribution == nil { diff --git a/cmd/erasure-metadata.go b/cmd/erasure-metadata.go index abd538558..5d8fc6def 100644 --- a/cmd/erasure-metadata.go +++ b/cmd/erasure-metadata.go @@ -91,7 +91,8 @@ func (fi FileInfo) IsValid() bool { dataBlocks := fi.Erasure.DataBlocks parityBlocks := fi.Erasure.ParityBlocks return ((dataBlocks >= parityBlocks) && - (dataBlocks != 0) && (parityBlocks != 0)) + (dataBlocks != 0) && (parityBlocks != 0) && + (fi.Erasure.Index > 0 && fi.Erasure.Distribution != nil)) } // ToObjectInfo - Converts metadata to object info. diff --git a/cmd/erasure-metadata_test.go b/cmd/erasure-metadata_test.go index 438955e7e..f8da2931e 100644 --- a/cmd/erasure-metadata_test.go +++ b/cmd/erasure-metadata_test.go @@ -47,6 +47,7 @@ func TestAddObjectPart(t *testing.T) { // Setup. fi := newFileInfo("test-object", 8, 8) + fi.Erasure.Index = 1 if !fi.IsValid() { t.Fatalf("unable to get xl meta") } @@ -80,6 +81,7 @@ func TestObjectPartIndex(t *testing.T) { // Setup. fi := newFileInfo("test-object", 8, 8) + fi.Erasure.Index = 1 if !fi.IsValid() { t.Fatalf("unable to get xl meta") } @@ -108,6 +110,7 @@ func TestObjectPartIndex(t *testing.T) { func TestObjectToPartOffset(t *testing.T) { // Setup. fi := newFileInfo("test-object", 8, 8) + fi.Erasure.Index = 1 if !fi.IsValid() { t.Fatalf("unable to get xl meta") } diff --git a/cmd/erasure-object.go b/cmd/erasure-object.go index fe71dd134..f6a9bc4a8 100644 --- a/cmd/erasure-object.go +++ b/cmd/erasure-object.go @@ -215,11 +215,12 @@ func (er erasureObjects) GetObject(ctx context.Context, bucket, object string, s } func (er erasureObjects) getObjectWithFileInfo(ctx context.Context, bucket, object string, startOffset int64, length int64, writer io.Writer, etag string, opts ObjectOptions, fi FileInfo, metaArr []FileInfo, onlineDisks []StorageAPI) error { + tmpDisks := onlineDisks // Reorder online disks based on erasure distribution order. - onlineDisks = shuffleDisks(onlineDisks, fi.Erasure.Distribution) + onlineDisks = shuffleDisksByIndex(tmpDisks, metaArr) // Reorder parts metadata based on erasure distribution order. - metaArr = shufflePartsMetadata(metaArr, fi.Erasure.Distribution) + metaArr = shufflePartsMetadataByIndex(tmpDisks, metaArr) // For negative length read everything. if length < 0 {