From 249746fef43a12e0b5368d98006be51d3afa4d3a Mon Sep 17 00:00:00 2001 From: Roman Khimov Date: Thu, 29 May 2025 23:46:58 +0300 Subject: [PATCH] tx: add missing lock on meta page update metalock is supposed to protect meta page, but it looks like the only place where we're modifying it is not protected in fact. Since page update is not atomic a concurrent reader (RO transaction) can get an inconsistent page. It's likely to fall back to the other one in this case, but still we better not allow this to happen. Signed-off-by: Roman Khimov --- tx.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tx.go b/tx.go index 5eb383c4b..7123ded8f 100644 --- a/tx.go +++ b/tx.go @@ -561,10 +561,13 @@ func (tx *Tx) writeMeta() error { tx.meta.Write(p) // Write the meta page to file. + tx.db.metalock.Lock() if _, err := tx.db.ops.writeAt(buf, int64(p.Id())*int64(tx.db.pageSize)); err != nil { + tx.db.metalock.Unlock() lg.Errorf("writeAt failed, pgid: %d, pageSize: %d, error: %v", p.Id(), tx.db.pageSize, err) return err } + tx.db.metalock.Unlock() if !tx.db.NoSync || common.IgnoreNoSync { // gofail: var beforeSyncMetaPage struct{} if err := fdatasync(tx.db); err != nil {