Skip to content

Commit b2db689

Browse files
committed
backend/gcp: fix incorrect size result in range read
* GCP's `GetObjReader` was incorrectly implemented as returning the size from object attribute for the range-read request. * this caused size mismatches where caller (blob downloader) expected the range length but `res.Size` indicated the full object size. * fixed by setting `res.Size` to the requested length for range-read. * refactor the handling logic to clearly separate range-read and full-read paths. Signed-off-by: Tony Chen <a122774007@gmail.com>
1 parent 424abe8 commit b2db689

File tree

2 files changed

+35
-11
lines changed

2 files changed

+35
-11
lines changed

ais/backend/gcp.go

Lines changed: 34 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -344,6 +344,8 @@ func (*gsbp) GetObjReader(ctx context.Context, lom *core.LOM, offset, length int
344344
res.ErrCode, res.Err = gcpErrorToAISError(res.Err, cloudBck)
345345
return res
346346
}
347+
348+
// range read
347349
if length > 0 {
348350
rc, res.Err = o.NewRangeReader(ctx, offset, length)
349351
if res.Err != nil {
@@ -352,21 +354,43 @@ func (*gsbp) GetObjReader(ctx context.Context, lom *core.LOM, offset, length int
352354
}
353355
return res
354356
}
355-
} else {
356-
rc, res.Err = o.NewReader(ctx)
357-
if res.Err != nil {
357+
// NOTE: for range reads, use the requested length, not rc.Attrs.Size (which is the full object size)
358+
rsize := rc.Remain()
359+
if rsize < 0 {
360+
res.Err = errors.New("gcp: returned length is less than 0")
358361
return res
359362
}
360-
// custom metadata
361-
lom.SetCustomKey(cmn.SourceObjMD, apc.GCP)
362-
if cksumType, ok := attrs.Metadata[gcpChecksumType]; ok {
363-
if cksumValue, ok := attrs.Metadata[gcpChecksumVal]; ok {
364-
lom.SetCksum(cos.NewCksum(cksumType, cksumValue))
365-
}
363+
if length < rsize {
364+
res.Err = errors.New("gcp: returned length is more than the requested range-read length")
365+
return res
366366
}
367-
res.ExpCksum = setCustomGs(lom, attrs)
367+
debug.Assertf(offset+rsize <= attrs.Size, "offset + rsize %d > attrs.Size %d", offset+rsize, attrs.Size)
368+
res.Size = rsize
369+
res.R = rc
370+
return res
371+
}
372+
373+
// full read
374+
rc, res.Err = o.NewReader(ctx)
375+
if res.Err != nil {
376+
return res
377+
}
378+
// custom metadata
379+
lom.SetCustomKey(cmn.SourceObjMD, apc.GCP)
380+
if cksumType, ok := attrs.Metadata[gcpChecksumType]; ok {
381+
if cksumValue, ok := attrs.Metadata[gcpChecksumVal]; ok {
382+
cksum := cos.NewCksum(cksumType, cksumValue)
383+
lom.SetCksum(cksum)
384+
res.ExpCksum = cksum // Use custom checksum as expected checksum
385+
}
386+
}
387+
388+
expCksum := setCustomGs(lom, attrs)
389+
if res.ExpCksum == nil {
390+
res.ExpCksum = expCksum
368391
}
369392

393+
// For full reads, use rc.Attrs.Size
370394
res.Size = rc.Attrs.Size
371395
res.R = rc
372396
return res

ais/test/blob_download_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -204,7 +204,7 @@ func TestBlobDownloadAbort(t *testing.T) {
204204
tassert.CheckFatal(t, err)
205205

206206
chunks := m.findObjChunksOnDisk(bck, objName)
207-
tlog.Logfln("Found chunk files after abort", chunks)
207+
tlog.Logfln("Found chunk %d files after abort", len(chunks))
208208
tassert.Fatalf(t, len(chunks) == 0, "expected 0 chunk files after abort, found %d", len(chunks))
209209

210210
// Cleanup: delete the remote object

0 commit comments

Comments
 (0)