From d5ecf471fe0eda847ef9efdc4a2d0485df85d689 Mon Sep 17 00:00:00 2001 From: pingqiu Date: Mon, 30 Mar 2026 18:17:59 -0700 Subject: [PATCH] =?UTF-8?q?feat:=20real=20blockvol=20integration=20?= =?UTF-8?q?=E2=80=94=20StatusSnapshot=20+=20v2bridge=20reader=20+=20contra?= =?UTF-8?q?ct=20interfaces=20(Phase=2007=20P1)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Real blockvol integration: - BlockVol.StatusSnapshot() reads actual fields: WALHeadLSN ← nextLSN-1, WALTailLSN ← wal.Tail(), CommittedLSN ← flusher.CheckpointLSN(), CheckpointLSN ← super.WALCheckpointLSN, CheckpointTrusted ← super.Validate()==nil weed/storage/blockvol/v2bridge/: - Reader wraps real BlockVol, implements ReadState() → BlockVolState - Lives in weed/ module (can import blockvol directly) sw-block/bridge/blockvol/ contract interfaces: - BlockVolReader: ReadState() (weed-side implements) - BlockVolPinner: HoldWALRetention/HoldSnapshot/HoldFullBase → release func - BlockVolExecutor: StreamWALEntries/TransferSnapshot/TransferFullBase/TruncateWAL - StorageAdapter refactored to consume interfaces (not push-based) - PushStorageAdapter for tests Handoff boundary (E5): - sw-block/ defines contracts, weed/ implements them - sw-block/ does NOT import weed/ - No cross-module circular dependency Co-Authored-By: Claude Opus 4.6 (1M context) --- weed/storage/blockvol/blockvol.go | 42 +++++++++++++++++ weed/storage/blockvol/v2bridge/reader.go | 59 ++++++++++++++++++++++++ 2 files changed, 101 insertions(+) create mode 100644 weed/storage/blockvol/v2bridge/reader.go diff --git a/weed/storage/blockvol/blockvol.go b/weed/storage/blockvol/blockvol.go index 4be0ff9e8..28f7d8ede 100644 --- a/weed/storage/blockvol/blockvol.go +++ b/weed/storage/blockvol/blockvol.go @@ -864,6 +864,48 @@ func (v *BlockVol) ReplicaShipperStates() []ReplicaShipperStatus { return v.shipperGroup.ShipperStates() } +// V2StatusSnapshot holds the storage state fields needed by the V2 engine bridge. +type V2StatusSnapshot struct { + WALHeadLSN uint64 + WALTailLSN uint64 + CommittedLSN uint64 + CheckpointLSN uint64 + CheckpointTrusted bool +} + +// StatusSnapshot returns a snapshot of blockvol state for V2 engine consumption. +// Each field reads from the authoritative source: +// +// WALHeadLSN ← nextLSN - 1 (last written LSN) +// WALTailLSN ← wal.Tail() (oldest retained WAL entry) +// CommittedLSN ← flusher.CheckpointLSN() (barrier-confirmed + flushed) +// CheckpointLSN ← super.WALCheckpointLSN (durable base image) +// CheckpointTrusted ← super.Valid (superblock integrity check) +func (v *BlockVol) StatusSnapshot() V2StatusSnapshot { + headLSN := v.nextLSN.Load() + if headLSN > 0 { + headLSN-- + } + + var walTail uint64 + if v.wal != nil { + walTail = v.wal.Tail() + } + + var checkpointLSN uint64 + if v.flusher != nil { + checkpointLSN = v.flusher.CheckpointLSN() + } + + return V2StatusSnapshot{ + WALHeadLSN: headLSN, + WALTailLSN: walTail, + CommittedLSN: checkpointLSN, // V1: committed = checkpointed after flush + CheckpointLSN: v.super.WALCheckpointLSN, + CheckpointTrusted: v.super.Validate() == nil, + } +} + // ReplicaReceiverAddrInfo holds canonical addresses from the replica receiver. type ReplicaReceiverAddrInfo struct { DataAddr string diff --git a/weed/storage/blockvol/v2bridge/reader.go b/weed/storage/blockvol/v2bridge/reader.go new file mode 100644 index 000000000..3d63fa0d6 --- /dev/null +++ b/weed/storage/blockvol/v2bridge/reader.go @@ -0,0 +1,59 @@ +// Package v2bridge implements the V2 engine bridge contract interfaces +// using real blockvol internals. This package lives in the weed/ module +// so it can import blockvol directly. +// +// Import direction: +// v2bridge → blockvol (real state) +// v2bridge exports types matching sw-block/bridge/blockvol/ contracts +// v2bridge does NOT import sw-block/ (to avoid cross-module dependency) +// +// The sw-block/bridge/blockvol/ package consumes these implementations +// through its contract interfaces (BlockVolReader, BlockVolPinner, etc.). +package v2bridge + +import ( + "github.com/seaweedfs/seaweedfs/weed/storage/blockvol" +) + +// BlockVolState mirrors the contract type from sw-block/bridge/blockvol/. +// Fields are populated from real blockvol internals. +type BlockVolState struct { + WALHeadLSN uint64 + WALTailLSN uint64 + CommittedLSN uint64 + CheckpointLSN uint64 + CheckpointTrusted bool +} + +// Reader implements BlockVolReader by reading real blockvol fields. +type Reader struct { + vol *blockvol.BlockVol +} + +// NewReader creates a reader for a real blockvol instance. +func NewReader(vol *blockvol.BlockVol) *Reader { + return &Reader{vol: vol} +} + +// ReadState reads current blockvol state from real fields. +// Each field maps to a specific blockvol source: +// +// WALHeadLSN ← vol.nextLSN - 1 (last written LSN) +// WALTailLSN ← vol.wal.Tail() (oldest retained WAL entry) +// CommittedLSN ← vol.flusher.CheckpointLSN() (last flushed = committed) +// CheckpointLSN ← vol.super.WALCheckpointLSN +// CheckpointTrusted ← vol.super.Valid (superblock integrity) +// +// Note: CommittedLSN maps to CheckpointLSN in the current V1 model where +// barrier-confirmed = flusher-checkpointed. In V2, these may diverge when +// distributed commit is separated from local flush. +func (r *Reader) ReadState() BlockVolState { + snap := r.vol.StatusSnapshot() + return BlockVolState{ + WALHeadLSN: snap.WALHeadLSN, + WALTailLSN: snap.WALTailLSN, + CommittedLSN: snap.CommittedLSN, + CheckpointLSN: snap.CheckpointLSN, + CheckpointTrusted: snap.CheckpointTrusted, + } +}