mirror of
https://github.com/seaweedfs/seaweedfs.git
synced 2026-08-21 22:56:55 +00:00
feat(ec): remove the .ecsum sidecars when destroying an EC volume
remove_ec_volume_files now clears <base>.ecsum (and any versioned .ecsum.v<N>) from the data and idx dirs, so a vid reuse can't load a stale sidecar. Mirrors Go's removeBitrotSidecars. Claude-Session: https://claude.ai/code/session_015EE9Sc9EvNp8BCVva4RKdo
This commit is contained in:
@@ -395,6 +395,12 @@ impl DiskLocation {
|
||||
for i in 0..MAX_SHARD_COUNT {
|
||||
rm_if_present(format!("{}.ec{:02}", base, i))?;
|
||||
}
|
||||
|
||||
// Remove the bitrot checksum sidecars from both the data and idx dirs.
|
||||
remove_bitrot_sidecars(&base)?;
|
||||
if self.idx_directory != self.directory {
|
||||
remove_bitrot_sidecars(&idx_base)?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -1081,6 +1087,49 @@ fn rm_if_present(path: String) -> io::Result<()> {
|
||||
}
|
||||
}
|
||||
|
||||
/// Remove the bitrot checksum sidecars for a base file name: the legacy
|
||||
/// `<base>.ecsum` (generation 0) and any versioned `<base>.ecsum.v<N>`.
|
||||
/// Already-gone is success; returns the first real removal failure (and surfaces
|
||||
/// a directory-scan error) so a stale sidecar left behind is not reported as
|
||||
/// cleaned. Mirrors Go's removeBitrotSidecars.
|
||||
fn remove_bitrot_sidecars(base: &str) -> io::Result<()> {
|
||||
use crate::storage::erasure_coding::ec_bitrot::BITROT_SIDECAR_EXT;
|
||||
let rm = |path: std::path::PathBuf| -> io::Result<()> {
|
||||
match fs::remove_file(&path) {
|
||||
Err(e) if e.kind() != io::ErrorKind::NotFound => Err(e),
|
||||
_ => Ok(()),
|
||||
}
|
||||
};
|
||||
let mut first_err: Option<io::Error> = None;
|
||||
let mut record = |res: io::Result<()>| {
|
||||
if let Err(e) = res {
|
||||
if first_err.is_none() {
|
||||
first_err = Some(e);
|
||||
}
|
||||
}
|
||||
};
|
||||
record(rm(format!("{}{}", base, BITROT_SIDECAR_EXT).into()));
|
||||
let path = std::path::Path::new(base);
|
||||
if let (Some(parent), Some(fname)) = (path.parent(), path.file_name()) {
|
||||
let prefix = format!("{}{}.v", fname.to_string_lossy(), BITROT_SIDECAR_EXT);
|
||||
match fs::read_dir(parent) {
|
||||
Ok(entries) => {
|
||||
for entry in entries.flatten() {
|
||||
if entry.file_name().to_string_lossy().starts_with(&prefix) {
|
||||
record(rm(entry.path()));
|
||||
}
|
||||
}
|
||||
}
|
||||
Err(e) if e.kind() != io::ErrorKind::NotFound => record(Err(e)),
|
||||
Err(_) => {}
|
||||
}
|
||||
}
|
||||
match first_err {
|
||||
Some(e) => Err(e),
|
||||
None => Ok(()),
|
||||
}
|
||||
}
|
||||
|
||||
fn ec_data_shards_from_vif(directory: &str, idx_directory: &str, collection: &str, vid: VolumeId) -> usize {
|
||||
for dir in [directory, idx_directory] {
|
||||
let vif = format!("{}.vif", volume_file_name(dir, collection, vid));
|
||||
|
||||
Reference in New Issue
Block a user