mirror of https://github.com/minio/minio.git
Make isIndexedMetaV2 return errors (#15012)
Indexed streams would be decoded by the legacy loader if there was an error loading it. Return an error when the stream is indexed and it cannot be loaded. Fixes "unknown minor metadata version" on corrupted xl.meta files and returns an actual error.
This commit is contained in:
parent
7b2198f7e5
commit
f7cecf0945
|
@ -168,8 +168,10 @@ func (e *metaCacheEntry) isLatestDeletemarker() bool {
|
|||
if !isXL2V1Format(e.metadata) {
|
||||
return false
|
||||
}
|
||||
if meta, _ := isIndexedMetaV2(e.metadata); meta != nil {
|
||||
if meta, _, err := isIndexedMetaV2(e.metadata); meta != nil {
|
||||
return meta.IsLatestDeleteMarker()
|
||||
} else if err != nil {
|
||||
return true
|
||||
}
|
||||
// Fall back...
|
||||
xlMeta, err := e.xlmeta()
|
||||
|
|
|
@ -50,7 +50,9 @@ func getAllFileInfoVersions(xlMetaBuf []byte, volume, path string) (FileInfoVers
|
|||
var versions []FileInfo
|
||||
var err error
|
||||
|
||||
if buf, _ := isIndexedMetaV2(xlMetaBuf); buf != nil {
|
||||
if buf, _, e := isIndexedMetaV2(xlMetaBuf); e != nil {
|
||||
return FileInfoVersions{}, e
|
||||
} else if buf != nil {
|
||||
versions, err = buf.ListVersions(volume, path)
|
||||
} else {
|
||||
var xlMeta xlMetaV2
|
||||
|
@ -87,7 +89,9 @@ func getFileInfo(xlMetaBuf []byte, volume, path, versionID string, data bool) (F
|
|||
var fi FileInfo
|
||||
var err error
|
||||
var inData xlMetaInlineData
|
||||
if buf, data := isIndexedMetaV2(xlMetaBuf); buf != nil {
|
||||
if buf, data, e := isIndexedMetaV2(xlMetaBuf); e != nil {
|
||||
return FileInfo{}, e
|
||||
} else if buf != nil {
|
||||
inData = data
|
||||
fi, err = buf.ToFileInfo(volume, path, versionID)
|
||||
if len(buf) != 0 && errors.Is(err, errFileNotFound) {
|
||||
|
|
|
@ -793,34 +793,32 @@ func decodeVersions(buf []byte, versions int, fn func(idx int, hdr, meta []byte)
|
|||
}
|
||||
|
||||
// isIndexedMetaV2 returns non-nil result if metadata is indexed.
|
||||
// If data doesn't validate nil is also returned.
|
||||
func isIndexedMetaV2(buf []byte) (meta xlMetaBuf, data xlMetaInlineData) {
|
||||
// Returns 3x nil if not XLV2 or not indexed.
|
||||
// If indexed and unable to parse an error will be returned.
|
||||
func isIndexedMetaV2(buf []byte) (meta xlMetaBuf, data xlMetaInlineData, err error) {
|
||||
buf, major, minor, err := checkXL2V1(buf)
|
||||
if err != nil {
|
||||
return nil, nil
|
||||
}
|
||||
if major != 1 || minor < 3 {
|
||||
return nil, nil
|
||||
if err != nil || major != 1 || minor < 3 {
|
||||
return nil, nil, nil
|
||||
}
|
||||
meta, buf, err = msgp.ReadBytesZC(buf)
|
||||
if err != nil {
|
||||
return nil, nil
|
||||
return nil, nil, err
|
||||
}
|
||||
if crc, nbuf, err := msgp.ReadUint32Bytes(buf); err == nil {
|
||||
// Read metadata CRC
|
||||
buf = nbuf
|
||||
if got := uint32(xxhash.Sum64(meta)); got != crc {
|
||||
return nil, nil
|
||||
return nil, nil, fmt.Errorf("xlMetaV2.Load version(%d), CRC mismatch, want 0x%x, got 0x%x", minor, crc, got)
|
||||
}
|
||||
} else {
|
||||
return nil, nil
|
||||
return nil, nil, err
|
||||
}
|
||||
data = buf
|
||||
if data.validate() != nil {
|
||||
data.repair()
|
||||
}
|
||||
|
||||
return meta, data
|
||||
return meta, data, nil
|
||||
}
|
||||
|
||||
type xlMetaV2ShallowVersion struct {
|
||||
|
@ -865,7 +863,9 @@ func (x *xlMetaV2) LoadOrConvert(buf []byte) error {
|
|||
// Load all versions of the stored data.
|
||||
// Note that references to the incoming buffer will be kept.
|
||||
func (x *xlMetaV2) Load(buf []byte) error {
|
||||
if meta, data := isIndexedMetaV2(buf); meta != nil {
|
||||
if meta, data, err := isIndexedMetaV2(buf); err != nil {
|
||||
return err
|
||||
} else if meta != nil {
|
||||
return x.loadIndexed(meta, data)
|
||||
}
|
||||
// Convert older format.
|
||||
|
|
|
@ -514,7 +514,7 @@ func BenchmarkXlMetaV2Shallow(b *testing.B) {
|
|||
b.ResetTimer()
|
||||
b.ReportAllocs()
|
||||
for i := 0; i < b.N; i++ {
|
||||
buf, _ := isIndexedMetaV2(enc)
|
||||
buf, _, _ := isIndexedMetaV2(enc)
|
||||
if buf == nil {
|
||||
b.Fatal("buf == nil")
|
||||
}
|
||||
|
@ -529,7 +529,7 @@ func BenchmarkXlMetaV2Shallow(b *testing.B) {
|
|||
b.ResetTimer()
|
||||
b.ReportAllocs()
|
||||
for i := 0; i < b.N; i++ {
|
||||
buf, _ := isIndexedMetaV2(enc)
|
||||
buf, _, _ := isIndexedMetaV2(enc)
|
||||
if buf == nil {
|
||||
b.Fatal("buf == nil")
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue