From 31c4fdbf7971bb00ff6337df11b9278e111f4076 Mon Sep 17 00:00:00 2001 From: Harshavardhana Date: Mon, 6 Jun 2022 15:14:56 -0700 Subject: [PATCH] fix: resyncing 'null' version on pre-existing content (#15043) PR #15041 fixed replicating 'null' version however due to a regression from #14994 caused the target versions for these 'null' versioned objects to have different 'versions', this may cause confusion with bi-directional replication and cause double replication. This PR fixes this properly by making sure we replicate the correct versions on the objects. --- cmd/bucket-replication.go | 7 ++++++- cmd/erasure-server-pool.go | 7 +++++-- cmd/metacache-entries.go | 4 ++-- cmd/object-api-options.go | 3 ++- cmd/object-handlers.go | 6 +++++- 5 files changed, 20 insertions(+), 7 deletions(-) diff --git a/cmd/bucket-replication.go b/cmd/bucket-replication.go index b50afd86f..6f0a93e54 100644 --- a/cmd/bucket-replication.go +++ b/cmd/bucket-replication.go @@ -1045,8 +1045,13 @@ func replicateObjectToTarget(ctx context.Context, ri ReplicateObjectInfo, object return } + versioned := globalBucketVersioningSys.PrefixEnabled(bucket, object) + versionSuspended := globalBucketVersioningSys.PrefixSuspended(bucket, object) + gr, err = objectAPI.GetObjectNInfo(ctx, bucket, object, nil, http.Header{}, readLock, ObjectOptions{ - VersionID: objInfo.VersionID, + VersionID: objInfo.VersionID, + Versioned: versioned, + VersionSuspended: versionSuspended, }) if err != nil { sendEvent(eventArgs{ diff --git a/cmd/erasure-server-pool.go b/cmd/erasure-server-pool.go index c8ed788fb..5c4f912ed 100644 --- a/cmd/erasure-server-pool.go +++ b/cmd/erasure-server-pool.go @@ -1751,13 +1751,13 @@ func (z *erasureServerPools) Walk(ctx context.Context, bucket, prefix string, re return err } + vcfg, _ := globalBucketVersioningSys.Get(bucket) + ctx, cancel := context.WithCancel(ctx) go func() { defer cancel() defer close(results) - versioned := opts.Versioned || opts.VersionSuspended - for _, erasureSet := range z.serverPools { var wg sync.WaitGroup for _, set := range erasureSet.sets { @@ -1785,11 +1785,14 @@ func (z *erasureServerPools) Walk(ctx context.Context, bucket, prefix string, re if opts.WalkAscending { for i := len(fivs.Versions) - 1; i >= 0; i-- { version := fivs.Versions[i] + versioned := vcfg != nil && vcfg.Versioned(version.Name) + results <- version.ToObjectInfo(bucket, version.Name, versioned) } return } for _, version := range fivs.Versions { + versioned := vcfg != nil && vcfg.Versioned(version.Name) results <- version.ToObjectInfo(bucket, version.Name, versioned) } } diff --git a/cmd/metacache-entries.go b/cmd/metacache-entries.go index 3bad979cf..a8dbf43eb 100644 --- a/cmd/metacache-entries.go +++ b/cmd/metacache-entries.go @@ -441,7 +441,6 @@ func (m *metaCacheEntriesSorted) fileInfoVersions(bucket, prefix, delimiter, aft versions = make([]ObjectInfo, 0, m.len()) prevPrefix := "" vcfg, _ := globalBucketVersioningSys.Get(bucket) - versioned := vcfg != nil && vcfg.Versioned(prefix) for _, entry := range m.o { if entry.isObject() { @@ -478,6 +477,7 @@ func (m *metaCacheEntriesSorted) fileInfoVersions(bucket, prefix, delimiter, aft } for _, version := range fiVersions { + versioned := vcfg != nil && vcfg.Versioned(entry.name) versions = append(versions, version.ToObjectInfo(bucket, entry.name, versioned)) } @@ -516,7 +516,6 @@ func (m *metaCacheEntriesSorted) fileInfos(bucket, prefix, delimiter string) (ob prevPrefix := "" vcfg, _ := globalBucketVersioningSys.Get(bucket) - versioned := vcfg != nil && vcfg.Versioned(prefix) for _, entry := range m.o { if entry.isObject() { @@ -540,6 +539,7 @@ func (m *metaCacheEntriesSorted) fileInfos(bucket, prefix, delimiter string) (ob fi, err := entry.fileInfo(bucket) if err == nil { + versioned := vcfg != nil && vcfg.Versioned(entry.name) objects = append(objects, fi.ToObjectInfo(bucket, entry.name, versioned)) } continue diff --git a/cmd/object-api-options.go b/cmd/object-api-options.go index a7aeb40ee..3d9ae61b4 100644 --- a/cmd/object-api-options.go +++ b/cmd/object-api-options.go @@ -157,6 +157,7 @@ func getOpts(ctx context.Context, r *http.Request, bucket, object string) (Objec } } } + opts.Versioned = globalBucketVersioningSys.PrefixEnabled(bucket, object) opts.VersionSuspended = globalBucketVersioningSys.PrefixSuspended(bucket, object) return opts, nil } @@ -167,7 +168,7 @@ func delOpts(ctx context.Context, r *http.Request, bucket, object string) (opts return opts, err } opts.Versioned = globalBucketVersioningSys.PrefixEnabled(bucket, object) - opts.VersionSuspended = globalBucketVersioningSys.Suspended(bucket) + opts.VersionSuspended = globalBucketVersioningSys.PrefixSuspended(bucket, object) delMarker := strings.TrimSpace(r.Header.Get(xhttp.MinIOSourceDeleteMarker)) if delMarker != "" { switch delMarker { diff --git a/cmd/object-handlers.go b/cmd/object-handlers.go index 43d602680..04208ff91 100644 --- a/cmd/object-handlers.go +++ b/cmd/object-handlers.go @@ -1041,7 +1041,11 @@ func (api objectAPIHandlers) CopyObjectHandler(w http.ResponseWriter, r *http.Re srcOpts.VersionID = vid // convert copy src encryption options for GET calls - getOpts := ObjectOptions{VersionID: srcOpts.VersionID, Versioned: srcOpts.Versioned} + getOpts := ObjectOptions{ + VersionID: srcOpts.VersionID, + Versioned: srcOpts.Versioned, + VersionSuspended: srcOpts.VersionSuspended, + } getSSE := encrypt.SSE(srcOpts.ServerSideEncryption) if getSSE != srcOpts.ServerSideEncryption { getOpts.ServerSideEncryption = getSSE