Browse Source

Match Go check_volume_data_integrity: verify all 10 entries, detect trailing corruption

rust-volume-server
Chris Lu 3 days ago
parent
commit
c285e596c1
  1. 38
      seaweed-volume/src/storage/volume.rs

38
seaweed-volume/src/storage/volume.rs

@ -1699,8 +1699,12 @@ impl Volume {
let version = self.super_block.version; let version = self.super_block.version;
// Check last 10 index entries (matching Go's loop: for i := 1; i <= 10 ...) // Check last 10 index entries (matching Go's loop: for i := 1; i <= 10 ...)
// Go does NOT break on first success; it tracks healthyIndexSize and only
// breaks on ErrorSizeMismatch. After the loop, it returns an error if
// healthyIndexSize < indexSize (detecting trailing corrupt entries).
let mut idx_file = File::open(&idx_path)?; let mut idx_file = File::open(&idx_path)?;
let max_entries = std::cmp::min(10, idx_size / NEEDLE_MAP_ENTRY_SIZE as i64); let max_entries = std::cmp::min(10, idx_size / NEEDLE_MAP_ENTRY_SIZE as i64);
let mut healthy_index_size: i64 = 0;
for i in 1..=max_entries { for i in 1..=max_entries {
let entry_offset = idx_size - i * NEEDLE_MAP_ENTRY_SIZE as i64; let entry_offset = idx_size - i * NEEDLE_MAP_ENTRY_SIZE as i64;
@ -1756,16 +1760,16 @@ impl Volume {
{ {
let (_, _, alt_size) = Needle::parse_header(&alt_header); let (_, _, alt_size) = Needle::parse_header(&alt_header);
if alt_size.0 == size.0 { if alt_size.0 == size.0 {
continue; // alternative offset worked
// Update healthy_index_size and continue
let pos = entry_offset + NEEDLE_MAP_ENTRY_SIZE as i64;
if pos > healthy_index_size {
healthy_index_size = pos;
}
continue;
} }
} }
return Err(VolumeError::Io(io::Error::new(
io::ErrorKind::InvalidData,
format!(
"needle size {} does not match index size {} at offset {}",
needle_size.0, size.0, actual_offset
),
)));
// Match Go: ErrorSizeMismatch breaks out of the loop
break;
} }
// If V3, try to read the append timestamp from the last verified entry // If V3, try to read the append timestamp from the last verified entry
@ -1780,8 +1784,22 @@ impl Volume {
} }
} }
// First successfully verified entry is enough
break;
// Track the highest verified index position
let pos = entry_offset + NEEDLE_MAP_ENTRY_SIZE as i64;
if pos > healthy_index_size {
healthy_index_size = pos;
}
}
// Match Go: if healthyIndexSize < indexSize, trailing entries are corrupt
if healthy_index_size < idx_size {
return Err(VolumeError::Io(io::Error::new(
io::ErrorKind::InvalidData,
format!(
"healthy index size {} is less than expected {}",
healthy_index_size, idx_size
),
)));
} }
Ok(()) Ok(())

Loading…
Cancel
Save