xlmeta: Recover corrupted metadata (#13205)

When unable to load existing metadata new versions 
would not be written. This would leave objects in a 
permanently unrecoverable state

Instead, start with clean metadata and write the incoming data.
This commit is contained in:
Klaus Post 2021-09-14 11:34:25 -07:00 committed by GitHub
parent af78c3925a
commit bf5bfe589f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -991,6 +991,7 @@ func (s *xlStorage) WriteMetadata(ctx context.Context, volume, path string, fi F
var xlMeta xlMetaV2 var xlMeta xlMetaV2
if !isXL2V1Format(buf) { if !isXL2V1Format(buf) {
// This is both legacy and without proper version.
err = xlMeta.AddVersion(fi) err = xlMeta.AddVersion(fi)
if err != nil { if err != nil {
logger.LogIf(ctx, err) logger.LogIf(ctx, err)
@ -1006,7 +1007,8 @@ func (s *xlStorage) WriteMetadata(ctx context.Context, volume, path string, fi F
} else { } else {
if err = xlMeta.Load(buf); err != nil { if err = xlMeta.Load(buf); err != nil {
logger.LogIf(ctx, err) logger.LogIf(ctx, err)
return err // Corrupted data, reset and write.
xlMeta = xlMetaV2{}
} }
if err = xlMeta.AddVersion(fi); err != nil { if err = xlMeta.AddVersion(fi); err != nil {
@ -1982,7 +1984,8 @@ func (s *xlStorage) RenameData(ctx context.Context, srcVolume, srcPath string, f
if isXL2V1Format(dstBuf) { if isXL2V1Format(dstBuf) {
if err = xlMeta.Load(dstBuf); err != nil { if err = xlMeta.Load(dstBuf); err != nil {
logger.LogIf(s.ctx, err) logger.LogIf(s.ctx, err)
return err // Data appears corrupt. Drop data.
xlMeta = xlMetaV2{}
} }
} else { } else {
// This code-path is to preserve the legacy data. // This code-path is to preserve the legacy data.
@ -1990,14 +1993,14 @@ func (s *xlStorage) RenameData(ctx context.Context, srcVolume, srcPath string, f
var json = jsoniter.ConfigCompatibleWithStandardLibrary var json = jsoniter.ConfigCompatibleWithStandardLibrary
if err := json.Unmarshal(dstBuf, xlMetaLegacy); err != nil { if err := json.Unmarshal(dstBuf, xlMetaLegacy); err != nil {
logger.LogIf(s.ctx, err) logger.LogIf(s.ctx, err)
return errFileCorrupt // Data appears corrupt. Drop data.
} } else {
if err = xlMeta.AddLegacy(xlMetaLegacy); err != nil { if err = xlMeta.AddLegacy(xlMetaLegacy); err != nil {
logger.LogIf(s.ctx, err) logger.LogIf(s.ctx, err)
return errFileCorrupt
} }
legacyPreserved = true legacyPreserved = true
} }
}
} else { } else {
s.RLock() s.RLock()
formatLegacy := s.formatLegacy formatLegacy := s.formatLegacy