diff --git a/cmd/erasure-object.go b/cmd/erasure-object.go index 61abb6438..3b5405a2f 100644 --- a/cmd/erasure-object.go +++ b/cmd/erasure-object.go @@ -313,19 +313,26 @@ func (er erasureObjects) getObjectWithFileInfo(ctx context.Context, bucket, obje // - attempt a heal to successfully heal them for future calls. if written == partLength { var scan madmin.HealScanMode - if errors.Is(err, errFileNotFound) { + switch { + case errors.Is(err, errFileNotFound): scan = madmin.HealNormalScan - logger.Info("Healing required, attempting to heal missing shards for %s", pathJoin(bucket, object, fi.VersionID)) - } else if errors.Is(err, errFileCorrupt) { + logger.Info("Healing required, triggering async heal missing shards for %s", pathJoin(bucket, object, fi.VersionID)) + case errors.Is(err, errFileCorrupt): scan = madmin.HealDeepScan - logger.Info("Healing required, attempting to heal bitrot for %s", pathJoin(bucket, object, fi.VersionID)) + logger.Info("Healing required, triggering async heal bitrot for %s", pathJoin(bucket, object, fi.VersionID)) } - if scan == madmin.HealNormalScan || scan == madmin.HealDeepScan { + switch scan { + case madmin.HealNormalScan, madmin.HealDeepScan: healOnce.Do(func() { if _, healing := er.getOnlineDisksWithHealing(); !healing { go healObject(bucket, object, fi.VersionID, scan) } }) + // Healing is triggered and we have written + // successfully the content to client for + // the specific part, we should `nil` this error + // and proceed forward, instead of throwing errors. + err = nil } } if err != nil { diff --git a/cmd/xl-storage.go b/cmd/xl-storage.go index d486c0a74..ded5c9a77 100644 --- a/cmd/xl-storage.go +++ b/cmd/xl-storage.go @@ -1454,6 +1454,13 @@ func (s *xlStorage) ReadFileStream(ctx context.Context, volume, path string, off return nil, errIsNotRegular } + if st.Size() < offset+length { + // Expected size cannot be satisfied for + // requested offset and length + file.Close() + return nil, errFileCorrupt + } + alignment := offset%xioutil.DirectioAlignSize == 0 if !alignment { if err = disk.DisableDirectIO(file); err != nil {