diff options
Diffstat (limited to 'meta.go')
-rw-r--r-- | meta.go | 28 |
1 files changed, 20 insertions, 8 deletions
@@ -2,6 +2,8 @@ package bolt import ( "errors" + "hash/fnv" + "unsafe" ) const magic uint32 = 0xED0CDAED @@ -13,6 +15,9 @@ var ( // ErrVersionMismatch is returned when the data file was created with a // different version of Bolt. ErrVersionMismatch = errors.New("version mismatch") + + // ErrChecksum is returned when either meta page checksum does not match. + ErrChecksum = errors.New("checksum error") ) type meta struct { @@ -24,11 +29,14 @@ type meta struct { freelist pgid pgid pgid txid txid + checksum uint64 } // validate checks the marker bytes and version of the meta page to ensure it matches this binary. func (m *meta) validate() error { - if m.magic != magic { + if m.checksum != 0 && m.checksum != m.sum64() { + return ErrChecksum + } else if m.magic != magic { return ErrInvalid } else if m.version != version { return ErrVersionMismatch @@ -38,13 +46,7 @@ func (m *meta) validate() error { // copy copies one meta object to another. func (m *meta) copy(dest *meta) { - dest.magic = m.magic - dest.version = m.version - dest.pageSize = m.pageSize - dest.buckets = m.buckets - dest.freelist = m.freelist - dest.pgid = m.pgid - dest.txid = m.txid + *dest = *m } // write writes the meta onto a page. @@ -53,5 +55,15 @@ func (m *meta) write(p *page) { p.id = pgid(m.txid % 2) p.flags |= metaPageFlag + // Calculate the checksum. + m.checksum = m.sum64() + m.copy(p.meta()) } + +// generates the checksum for the meta. +func (m *meta) sum64() uint64 { + var h = fnv.New64a() + _, _ = h.Write((*[unsafe.Offsetof(meta{}.checksum)]byte)(unsafe.Pointer(m))[:]) + return h.Sum64() +} |