mirror of
https://github.com/pgsty/minio.git
synced 2026-11-12 02:25:34 +03:00
fix(copy): preserve compression index on pooled copy rewrites
Forward dstOpts.IndexCB into erasureServerPools.CopyObject's PutObject options so multi-block S2 compressed copies (> compMinIndexSize) rewritten across pools persist Parts[0].Index for O(1) block-level ranged GET seeking. Signed-off-by: Feng Ruohang <rh@vonng.com>
This commit is contained in:
@@ -1831,6 +1831,7 @@ func (z *erasureServerPools) CopyObject(ctx context.Context, srcBucket, srcObjec
|
|||||||
MTime: dstOpts.MTime,
|
MTime: dstOpts.MTime,
|
||||||
NoLock: true,
|
NoLock: true,
|
||||||
EncryptFn: dstOpts.EncryptFn,
|
EncryptFn: dstOpts.EncryptFn,
|
||||||
|
IndexCB: dstOpts.IndexCB,
|
||||||
WantChecksum: dstOpts.WantChecksum,
|
WantChecksum: dstOpts.WantChecksum,
|
||||||
WantServerSideChecksumType: dstOpts.WantServerSideChecksumType,
|
WantServerSideChecksumType: dstOpts.WantServerSideChecksumType,
|
||||||
ReplicationRequest: dstOpts.ReplicationRequest,
|
ReplicationRequest: dstOpts.ReplicationRequest,
|
||||||
|
|||||||
@@ -84,7 +84,12 @@ func TestAPICopyHistoricalVersionAcrossPools(t *testing.T) {
|
|||||||
if mode == "sse-c" {
|
if mode == "sse-c" {
|
||||||
maps.Copy(sourceHeaders, customer(0x11))
|
maps.Copy(sourceHeaders, customer(0x11))
|
||||||
}
|
}
|
||||||
data := bytes.Repeat([]byte("historical encrypted compressed content-"), 8192)
|
pattern := []byte("historical encrypted compressed content-")
|
||||||
|
repeats := 8192
|
||||||
|
if mode == "plain" {
|
||||||
|
repeats = compMinIndexSize/len(pattern) + 1
|
||||||
|
}
|
||||||
|
data := bytes.Repeat(pattern, repeats)
|
||||||
sourceHeaders[xhttp.AmzChecksumCRC32] = mustChecksum(t, hash.ChecksumCRC32, data)
|
sourceHeaders[xhttp.AmzChecksumCRC32] = mustChecksum(t, hash.ChecksumCRC32, data)
|
||||||
key := fmt.Sprintf("copy-%s-%s-%d.txt", mode, tc.movement, sourcePool)
|
key := fmt.Sprintf("copy-%s-%s-%d.txt", mode, tc.movement, sourcePool)
|
||||||
placed.uploadPool = sourcePool
|
placed.uploadPool = sourcePool
|
||||||
@@ -145,6 +150,22 @@ func TestAPICopyHistoricalVersionAcrossPools(t *testing.T) {
|
|||||||
if copied.IsCompressed() != (!compressed && mode != "sse-c") {
|
if copied.IsCompressed() != (!compressed && mode != "sse-c") {
|
||||||
t.Fatalf("copy did not use destination compression setting: %v", copied.IsCompressed())
|
t.Fatalf("copy did not use destination compression setting: %v", copied.IsCompressed())
|
||||||
}
|
}
|
||||||
|
if copied.IsCompressed() && len(data) > compMinIndexSize {
|
||||||
|
if len(copied.Parts) == 0 || len(copied.Parts[0].Index) == 0 {
|
||||||
|
t.Fatalf("compressed multi-block copy lost seek index: %+v", copied.Parts)
|
||||||
|
}
|
||||||
|
rangeHeaders := maps.Clone(getHeaders)
|
||||||
|
rangeHeaders["Range"] = "bytes=6000000-6000127"
|
||||||
|
req, err := newTestSignedRequestV4(http.MethodGet, getGetObjectURL("", bucket, key)+"?versionId="+copied.VersionID, 0, nil, globalActiveCred.AccessKey, globalActiveCred.SecretKey, rangeHeaders)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
rrec := httptest.NewRecorder()
|
||||||
|
router.ServeHTTP(rrec, req)
|
||||||
|
if rrec.Code != http.StatusPartialContent || !bytes.Equal(rrec.Body.Bytes(), data[6000000:6000128]) {
|
||||||
|
t.Fatalf("ranged GET on compressed copy: %d len=%d", rrec.Code, rrec.Body.Len())
|
||||||
|
}
|
||||||
|
}
|
||||||
if mode == "sse-kms" {
|
if mode == "sse-kms" {
|
||||||
assertFederationKMSContext(t, copied, headers[xhttp.AmzServerSideEncryptionKmsContext])
|
assertFederationKMSContext(t, copied, headers[xhttp.AmzServerSideEncryptionKmsContext])
|
||||||
assertFederationKMSContext(t, original, sourceHeaders[xhttp.AmzServerSideEncryptionKmsContext])
|
assertFederationKMSContext(t, original, sourceHeaders[xhttp.AmzServerSideEncryptionKmsContext])
|
||||||
|
|||||||
Reference in New Issue
Block a user