fix(copy): plan historical version placement before transforms

Locate exact versions for in-place updates and rewrite cross-pool references through the encryption and compression pipeline selected before copying.

Fixes #343

Signed-off-by: Feng Ruohang <rh@vonng.com>
This commit is contained in:
Feng Ruohang
2026-11-11 12:29:28 +08:00
parent f746d07076
commit a8824b341f
4 changed files with 258 additions and 29 deletions
+12 -6
View File
@@ -1317,13 +1317,11 @@ func isRemoteCallRequired(ctx context.Context, bucket string, objAPI ObjectLayer
// copyRewritesObjectData reports whether the object layer stores new object data
// for this copy instead of updating metadata in place or adding a
// self-referential version. It mirrors the metadata-only decision taken by
// erasureServerPools.CopyObject and erasureSets.CopyObject. CopyObjectHandler
// has to predict that decision because the compression metadata it records must
// describe whichever bytes are finally stored. metadataOnly already excludes
// legacy sources, which the object layer always rewrites.
// self-referential version. The selected pool must contain the source data to
// add a reference. metadataOnly already excludes legacy sources, which the
// object layer always rewrites.
func copyRewritesObjectData(metadataOnly bool, srcOpts, dstOpts ObjectOptions) bool {
if !metadataOnly {
if !metadataOnly || dstOpts.copyPlan != nil && dstOpts.copyPlan.rewrite {
return true
}
switch {
@@ -1682,6 +1680,14 @@ func (api objectAPIHandlers) CopyObjectHandler(w http.ResponseWriter, r *http.Re
if dstOpts.Versioned && copySrcOpts.VersionID == "" {
copySrcOpts.VersionID = srcInfo.VersionID
}
if !remoteCallRequired {
plan, err := objectAPI.prepareCopyObject(lockCtx, srcBucket, srcObject, dstBucket, dstObject, srcInfo, copySrcOpts, dstOpts)
if err != nil {
writeErrorResponse(ctx, w, toAPIError(ctx, err), r.URL)
return
}
dstOpts.copyPlan = &plan
}
// A key rotation rewraps the object key held in metadata; it never
// re-encrypts the stored bytes. When the object layer stores new object