#![forbid(unsafe_code)]
use super::scan::FsckCtx;
use super::{Category, FsckIssue, Severity};
pub fn repair(ctx: &mut FsckCtx) -> Result<Vec<String>, String> {
let mut repaired = Vec::new();
if !ctx.options.repair_torn_tails {
return Ok(repaired);
}
let tails = std::mem::take(&mut ctx.torn_tails);
for (seq, keep, truncate_to) in tails {
let path = crate::store::segment::segment_path(&ctx.dir, seq);
let f = std::fs::OpenOptions::new()
.write(true)
.open(&path)
.map_err(|e| format!("segment {seq} open for repair: {e}"))?;
f.set_len(keep)
.map_err(|e| format!("segment {seq} truncate: {e}"))?;
f.sync_data()
.map_err(|e| format!("segment {seq} sync: {e}"))?;
repaired.push(format!(
"segment {seq}: torn tail truncated from {} to {} bytes",
truncate_to, keep
));
ctx.issues.push(FsckIssue::new(
Severity::Info,
Category::Repair,
format!("segment {seq}: torn tail truncated ({truncate_to} -> {keep} bytes)"),
));
}
Ok(repaired)
}