fix: copyObject on versioned bucket when updating metadata (#14971)

updating metadata with CopyObject on a versioned bucket
causes the latest version to be not readable, this PR fixes
this properly by handling the inline data bug fix introduced
in PR #14780.

This bug affects only inlined data.
This commit is contained in:
Harshavardhana 2022-05-24 17:27:45 -07:00 committed by GitHub
parent 80fe166902
commit 38caddffe7
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 19 additions and 10 deletions

View file

@ -133,15 +133,6 @@ func (er erasureObjects) CopyObject(ctx context.Context, srcBucket, srcObject, d
modTime = UTCNow()
}
// If the data is not inlined, we may end up incorrectly
// inlining the data here, that leads to an inconsistent
// situation where some objects are were not inlined
// were now inlined, make sure to `nil` the Data such
// that xl.meta is written as expected.
if !fi.InlineData() {
fi.Data = nil
}
fi.VersionID = versionID // set any new versionID we might have created
fi.ModTime = modTime // set modTime for the new versionID
if !dstOpts.MTime.IsZero() {
@ -151,12 +142,15 @@ func (er erasureObjects) CopyObject(ctx context.Context, srcBucket, srcObject, d
fi.Metadata = srcInfo.UserDefined
srcInfo.UserDefined["etag"] = srcInfo.ETag
inlineData := fi.InlineData()
freeVersionID := fi.TierFreeVersionID()
freeVersionMarker := fi.TierFreeVersion()
// Update `xl.meta` content on each disks.
for index := range metaArr {
if metaArr[index].IsValid() {
metaArr[index].ModTime = modTime
metaArr[index].VersionID = versionID
metaArr[index].Metadata = srcInfo.UserDefined
if !metaArr[index].InlineData() {
// If the data is not inlined, we may end up incorrectly
// inlining the data here, that leads to an inconsistent
@ -165,6 +159,17 @@ func (er erasureObjects) CopyObject(ctx context.Context, srcBucket, srcObject, d
// that xl.meta is written as expected.
metaArr[index].Data = nil
}
metaArr[index].Metadata = srcInfo.UserDefined
// Preserve existing values
if inlineData {
metaArr[index].SetInlineData()
}
if freeVersionID != "" {
metaArr[index].SetTierFreeVersionID(freeVersionID)
}
if freeVersionMarker {
metaArr[index].SetTierFreeVersion()
}
}
}

View file

@ -1424,6 +1424,10 @@ func (api objectAPIHandlers) CopyObjectHandler(w http.ResponseWriter, r *http.Re
srcInfo.metadataOnly = false
}
if srcInfo.metadataOnly {
gr.Close() // We are not interested in the reader stream at this point close it.
}
// Check if x-amz-metadata-directive or x-amz-tagging-directive was not set to REPLACE and source,
// destination are same objects. Apply this restriction also when
// metadataOnly is true indicating that we are not overwriting the object.