Only mark chunks as checked when not repaired (re #14)

pull/10/head
Dennis Schwerdel 2017-04-17 15:55:27 +02:00
parent bd23aac64c
commit 001a36a1eb
1 changed files with 16 additions and 15 deletions

View File

@ -75,12 +75,14 @@ impl Repository {
res res
} }
fn check_chunks(&self, checked: &mut Bitmap, chunks: &[Chunk]) -> Result<bool, RepositoryError> { fn check_chunks(&self, checked: &mut Bitmap, chunks: &[Chunk], mark: bool) -> Result<bool, RepositoryError> {
let mut new = false; let mut new = false;
for &(hash, _len) in chunks { for &(hash, _len) in chunks {
if let Some(pos) = self.index.pos(&hash) { if let Some(pos) = self.index.pos(&hash) {
new |= !checked.get(pos); new |= !checked.get(pos);
checked.set(pos); if mark {
checked.set(pos);
}
} else { } else {
return Err(IntegrityError::MissingChunk(hash).into()) return Err(IntegrityError::MissingChunk(hash).into())
} }
@ -92,13 +94,13 @@ impl Repository {
match inode.data { match inode.data {
None | Some(FileData::Inline(_)) => (), None | Some(FileData::Inline(_)) => (),
Some(FileData::ChunkedDirect(ref chunks)) => { Some(FileData::ChunkedDirect(ref chunks)) => {
try!(self.check_chunks(checked, chunks)); try!(self.check_chunks(checked, chunks, true));
}, },
Some(FileData::ChunkedIndirect(ref chunks)) => { Some(FileData::ChunkedIndirect(ref chunks)) => {
if try!(self.check_chunks(checked, chunks)) { if try!(self.check_chunks(checked, chunks, true)) {
let chunk_data = try!(self.get_data(&chunks)); let chunk_data = try!(self.get_data(&chunks));
let chunks = ChunkList::read_from(&chunk_data); let chunks = ChunkList::read_from(&chunk_data);
try!(self.check_chunks(checked, &chunks)); try!(self.check_chunks(checked, &chunks, true));
} }
} }
} }
@ -107,7 +109,7 @@ impl Repository {
fn check_subtree(&mut self, path: PathBuf, chunks: &[Chunk], checked: &mut Bitmap, repair: bool) -> Result<Option<ChunkList>, RepositoryError> { fn check_subtree(&mut self, path: PathBuf, chunks: &[Chunk], checked: &mut Bitmap, repair: bool) -> Result<Option<ChunkList>, RepositoryError> {
let mut modified = false; let mut modified = false;
match self.check_chunks(checked, chunks) { match self.check_chunks(checked, chunks, false) {
Ok(false) => return Ok(None), Ok(false) => return Ok(None),
Ok(true) => (), Ok(true) => (),
Err(err) => return Err(IntegrityError::BrokenInode(path, Box::new(err)).into()) Err(err) => return Err(IntegrityError::BrokenInode(path, Box::new(err)).into())
@ -152,6 +154,7 @@ impl Repository {
if modified { if modified {
Ok(Some(try!(self.put_inode(&inode)))) Ok(Some(try!(self.put_inode(&inode))))
} else { } else {
try!(self.check_chunks(checked, chunks, true));
Ok(None) Ok(None)
} }
} }
@ -234,15 +237,13 @@ impl Repository {
*chunks = c; *chunks = c;
modified = true; modified = true;
}, },
Err(err) => { Err(err) => if repair {
if repair { warn!("Problem detected: inode {:?} is corrupt\n\tcaused by: {}", path.join(name), err);
warn!("Problem detected: inode {:?} is corrupt\n\tcaused by: {}", path.join(name), err); info!("Removing broken inode from backup");
info!("Removing broken inode from backup"); removed.push(name.to_string());
removed.push(name.to_string()); modified = true;
modified = true; } else {
} else { return Err(err)
return Err(err)
}
} }
} }
} }