* weed/server: verify data shards against bitrot sidecar before ec decode (#12422)
* ec.decode: verify data shards against the mounted volume's bitrot protection
The decode looked up only the generation-0 .ecsum beside the data base and
each location's data directory, so it missed a sidecar kept with the index
and ignored the generation the volume actually serves.
Take the protection the volume's per-disk runtimes resolved instead (On, else
Invalid, else Off), and test a corrupt block past the first.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* ec.decode: check for live entries before verifying the shards
A volume whose needles are all deleted gets its shards purged on the
no-live-entries status; a failing checksum must not keep it around.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* seaweed-volume: verify data shards against the bitrot protection before a decode
Mirrors the Go volume server: the decode takes the protection the volume's
per-disk runtimes resolved and refuses a data shard that fails its .ecsum
checksum, after the no-live-entries check.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* test: a decode refuses a data shard that fails its .ecsum checksum
Runs against both volume server implementations: the refused decode keeps
every shard and the sidecar, and the needle stays readable through EC.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* ec.decode: reload the bitrot sidecar before verifying the shards
A rebuild's backfill writes the sidecar without reloading the mounted
runtimes, which then still report no protection; resolve it again across
the EC metadata directories, as a shard mount does.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* seaweed-volume: reload the bitrot sidecar before verifying the shards
Mirrors the Go volume server: the decode job resolves the sidecar again on
every runtime of the volume before choosing its protection.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* test: a decode finds a sidecar written after the shards were mounted
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* test: read through the EC shards after the refused decode
The source volume stayed mounted, so the final read never touched the
shards it is meant to check.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* ec.decode: refuse when a sidecar reload reports another layout
ReloadBitrotSidecar logged and dropped the layout-mismatch error, so the
runtime stayed Off and the decode skipped the data-shard check. It now
returns that error and the decode refuses on it.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* seaweed-volume: refuse a decode when a sidecar reload reports another layout
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* test: a decode refuses a late sidecar that records another layout
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* ec.decode: refuse when an unmount left no runtime to resolve the sidecar
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* seaweed-volume: refuse a decode when an unmount left no runtime to resolve the sidecar
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
---------
Co-authored-by: Chris Lu <chrislusf@users.noreply.github.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>