index: reindex on content-related I/O errors

If read_exact() or read_u32() reached to EOF, the index file should be
considered corrupted. File not found error is also treated as data corruption
because an invalid file name could be read from the child segment file. It
can't handle special file names like "..", though.
This commit is contained in:
Yuya Nishihara 2023-12-17 14:28:53 +09:00
parent e98104d6f0
commit 38ce914321
2 changed files with 8 additions and 3 deletions

View file

@ -63,8 +63,13 @@ impl ReadonlyIndexLoadError {
}
/// Returns true if the underlying error suggests data corruption.
pub(super) fn is_corrupt(&self) -> bool {
matches!(self.error.kind(), io::ErrorKind::InvalidData)
pub(super) fn is_corrupt_or_not_found(&self) -> bool {
// If the parent file name field is corrupt, the file wouldn't be found.
// And there's no need to distinguish it from an empty file.
matches!(
self.error.kind(),
io::ErrorKind::NotFound | io::ErrorKind::InvalidData | io::ErrorKind::UnexpectedEof
)
}
}

View file

@ -243,7 +243,7 @@ impl IndexStore for DefaultIndexStore {
store.change_id_length(),
op.id(),
) {
Err(DefaultIndexStoreError::LoadIndex(err)) if err.is_corrupt() => {
Err(DefaultIndexStoreError::LoadIndex(err)) if err.is_corrupt_or_not_found() => {
// If the index was corrupt (maybe it was written in a different format),
// we just reindex.
// TODO: Move this message to a callback or something.