mirror of
https://github.com/minio/minio.git
synced 2024-12-24 06:05:55 -05:00
fix: ReadFileStream should return an error when size mismatches (#13435)
offset+length should match the Size() of the individual parts return 'errFileCorrupt' otherwise, to trigger healing of the individual parts do not error out prematurely when healing such bitrot's upon successful parts being written to the client. another issue this PR fixes is to not return and error to the client if we have just triggered a heal on a specific part of the object, instead continue to read all the content and let the heal happen asynchronously later.
This commit is contained in:
parent
bedf739d16
commit
d693431183
@ -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 {
|
||||
|
@ -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 {
|
||||
|
Loading…
Reference in New Issue
Block a user