mirror of
https://github.com/seaweedfs/seaweedfs.git
synced 2026-09-12 17:40:43 +02:00
Volumes written by versions before 3.09 (commit 056c480eb) store the
needle checksum using the deprecated CRC.Value() transform. When the
read path moved into readNeedleTail, the fallback that accepts both
encodings was dropped, so .dat files copied from old installs now fail
verification with "invalid CRC ... data on disk corrupted" even though
the data is intact. Restore the dual check, matching the surviving
fallback in volume_read.go.
50 lines
1.9 KiB
Go
50 lines
1.9 KiB
Go
package needle
|
|
|
|
import (
|
|
"fmt"
|
|
|
|
"github.com/seaweedfs/seaweedfs/weed/stats"
|
|
. "github.com/seaweedfs/seaweedfs/weed/storage/types"
|
|
"github.com/seaweedfs/seaweedfs/weed/util"
|
|
)
|
|
|
|
func (n *Needle) readNeedleTail(needleBody []byte, version Version) error {
|
|
// for all versions, we need to read the checksum
|
|
if len(n.Data) > 0 {
|
|
expectedChecksum := CRC(util.BytesToUint32(needleBody[0:NeedleChecksumSize]))
|
|
dataChecksum := NewCRC(n.Data)
|
|
if expectedChecksum != dataChecksum && uint32(expectedChecksum) != dataChecksum.Value() {
|
|
// crc.Value() is the deprecated legacy transform used before commit 056c480eb
|
|
// (volume server <3.09). Accept either encoding so .dat files written by older
|
|
// versions still verify after an upgrade.
|
|
stats.VolumeServerHandlerCounter.WithLabelValues(stats.ErrorCRC).Inc()
|
|
return fmt.Errorf("invalid CRC for needle %v (got %08x, want %08x), data on disk corrupted: %w", n.Id, dataChecksum, expectedChecksum, ErrorCorrupted)
|
|
}
|
|
n.Checksum = dataChecksum
|
|
} else {
|
|
// when data is skipped from reading, just read the checksum
|
|
n.Checksum = CRC(util.BytesToUint32(needleBody[0:NeedleChecksumSize]))
|
|
}
|
|
|
|
if version == Version3 {
|
|
tsOffset := NeedleChecksumSize
|
|
n.AppendAtNs = util.BytesToUint64(needleBody[tsOffset : tsOffset+TimestampSize])
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func PaddingLength(needleSize Size, version Version) Size {
|
|
if version == Version3 {
|
|
// this is same value as version2, but just listed here for clarity
|
|
return NeedlePaddingSize - ((NeedleHeaderSize + needleSize + NeedleChecksumSize + TimestampSize) % NeedlePaddingSize)
|
|
}
|
|
return NeedlePaddingSize - ((NeedleHeaderSize + needleSize + NeedleChecksumSize) % NeedlePaddingSize)
|
|
}
|
|
|
|
func NeedleBodyLength(needleSize Size, version Version) int64 {
|
|
if version == Version3 {
|
|
return int64(needleSize) + NeedleChecksumSize + TimestampSize + int64(PaddingLength(needleSize, version))
|
|
}
|
|
return int64(needleSize) + NeedleChecksumSize + int64(PaddingLength(needleSize, version))
|
|
}
|