From e8c921d9e8703b4b6fa8eff6407dcf24193f1d34 Mon Sep 17 00:00:00 2001 From: Ping Qiu Date: Tue, 24 Mar 2026 00:19:25 -0700 Subject: [PATCH] fix: remove nil-optional superMu pattern, require in all FlusherConfigs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit superMu is mandatory for correctness — all superblock mutation+persist must be serialized. Remove the nil guard in updateSuperblockCheckpoint and add SuperMu to all 7 test FlusherConfig sites. Co-Authored-By: Claude Opus 4.6 (1M context) --- weed/storage/blockvol/blockvol_qa_test.go | 4 ++++ weed/storage/blockvol/flusher.go | 6 ++---- weed/storage/blockvol/flusher_test.go | 2 ++ weed/storage/blockvol/recovery_test.go | 1 + 4 files changed, 9 insertions(+), 4 deletions(-) diff --git a/weed/storage/blockvol/blockvol_qa_test.go b/weed/storage/blockvol/blockvol_qa_test.go index 8d6ddf0ba..1ededbbf7 100644 --- a/weed/storage/blockvol/blockvol_qa_test.go +++ b/weed/storage/blockvol/blockvol_qa_test.go @@ -1495,6 +1495,7 @@ func testQAFlushCheckpointPersists(t *testing.T) { f := NewFlusher(FlusherConfig{ FD: v.fd, Super: &v.super, + SuperMu: &v.superMu, WAL: v.wal, DirtyMap: v.dirtyMap, Interval: 1 * time.Hour, @@ -1586,6 +1587,7 @@ func testQAFlushWALReclaimThenWrite(t *testing.T) { f := NewFlusher(FlusherConfig{ FD: v.fd, Super: &v.super, + SuperMu: &v.superMu, WAL: v.wal, DirtyMap: v.dirtyMap, Interval: 1 * time.Hour, @@ -1849,6 +1851,7 @@ func testQARecoverAfterFlushThenCrash(t *testing.T) { f := NewFlusher(FlusherConfig{ FD: v.fd, Super: &v.super, WAL: v.wal, DirtyMap: v.dirtyMap, + SuperMu: &v.superMu, Interval: 1 * time.Hour, }) if err := f.FlushOnce(); err != nil { @@ -3413,6 +3416,7 @@ func testQAFlushPartialWALWrap(t *testing.T) { f := NewFlusher(FlusherConfig{ FD: v.fd, Super: &v.super, + SuperMu: &v.superMu, WAL: v.wal, DirtyMap: v.dirtyMap, Interval: 1 * time.Hour, // manual only diff --git a/weed/storage/blockvol/flusher.go b/weed/storage/blockvol/flusher.go index b233f2022..fe902fd9d 100644 --- a/weed/storage/blockvol/flusher.go +++ b/weed/storage/blockvol/flusher.go @@ -420,10 +420,8 @@ func (f *Flusher) flushOnceLocked() error { // updateSuperblockCheckpoint writes the updated checkpoint to disk. // Acquires superMu to serialize against syncWithWALProgress (group commit). func (f *Flusher) updateSuperblockCheckpoint(checkpointLSN uint64, walTail uint64) error { - if f.superMu != nil { - f.superMu.Lock() - defer f.superMu.Unlock() - } + f.superMu.Lock() + defer f.superMu.Unlock() f.super.WALCheckpointLSN = checkpointLSN f.super.WALHead = f.wal.LogicalHead() diff --git a/weed/storage/blockvol/flusher_test.go b/weed/storage/blockvol/flusher_test.go index 2eb4dc9e9..91bdcba16 100644 --- a/weed/storage/blockvol/flusher_test.go +++ b/weed/storage/blockvol/flusher_test.go @@ -48,6 +48,7 @@ func createTestVolWithFlusher(t *testing.T) (*BlockVol, *Flusher) { f := NewFlusher(FlusherConfig{ FD: v.fd, Super: &v.super, + SuperMu: &v.superMu, WAL: v.wal, DirtyMap: v.dirtyMap, Interval: 1 * time.Hour, // don't auto-flush in tests @@ -343,6 +344,7 @@ func testFlusherErrorLogged(t *testing.T) { f := NewFlusher(FlusherConfig{ FD: closedFD, Super: &v.super, + SuperMu: &v.superMu, WAL: v.wal, DirtyMap: v.dirtyMap, Interval: 1 * time.Hour, diff --git a/weed/storage/blockvol/recovery_test.go b/weed/storage/blockvol/recovery_test.go index 6b1e6452d..b4c9646b7 100644 --- a/weed/storage/blockvol/recovery_test.go +++ b/weed/storage/blockvol/recovery_test.go @@ -230,6 +230,7 @@ func testRecoverAfterCheckpoint(t *testing.T) { f := NewFlusher(FlusherConfig{ FD: v.fd, Super: &v.super, + SuperMu: &v.superMu, WAL: v.wal, DirtyMap: v.dirtyMap, Interval: 1 * time.Hour,