mirror of
https://github.com/rustfs/rustfs.git
synced 2026-09-07 04:25:54 +00:00
fix(scanner): recover legacy usage floor from backup (#6964)
* fix(scanner): recover legacy usage floor from backup Allow scanner usage-floor startup and leadership fencing to use a valid legacy backup when the legacy primary read fails with a corruption-shaped error. Keep v2 primary read failures, stale metadata, transient I/O, and missing or invalid backups fail-closed. Co-Authored-By: heihutu <heihutu@gmail.com> * fix(scanner): cover legacy backup fencing gaps (#6966) * fix(scanner): recover legacy usage from valid backup * fix(scanner): recover legacy usage floor from backup Allow scanner usage-floor startup and leadership fencing to use a valid legacy backup when the legacy primary read fails with a corruption-shaped error. Keep v2 primary read failures, stale metadata, transient I/O, and missing or invalid backups fail-closed. Co-Authored-By: heihutu <heihutu@gmail.com> * fix(scanner): cover legacy backup fencing gaps --------- Co-authored-by: houseme <housemecn@gmail.com> Co-authored-by: heihutu <heihutu@gmail.com> --------- Co-authored-by: heihutu <heihutu@gmail.com> Co-authored-by: Henry Guo <marshawcoco@gmail.com>
This commit is contained in:
@@ -131,6 +131,39 @@ pub(crate) async fn read_config_with_revision<S: ScannerObjectIO>(
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn usage_floor_primary_read_error_allows_backup(err: &Error) -> bool {
|
||||
match err {
|
||||
Error::FileCorrupt
|
||||
| Error::CorruptedFormat
|
||||
| Error::CorruptedBackend
|
||||
| Error::PartMissingOrCorrupt
|
||||
| Error::LessData
|
||||
| Error::MoreData => true,
|
||||
Error::Io(io_error) => {
|
||||
matches!(io_error.kind(), std::io::ErrorKind::InvalidData | std::io::ErrorKind::UnexpectedEof)
|
||||
|| error_chain_has_usage_floor_corruption_signature(io_error)
|
||||
}
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
||||
fn error_chain_has_usage_floor_corruption_signature(error: &(dyn std::error::Error + 'static)) -> bool {
|
||||
let mut current = Some(error);
|
||||
while let Some(err) = current {
|
||||
let message = err.to_string();
|
||||
if message.contains("InlineData value out of range")
|
||||
|| message.contains("InlineData key out of range")
|
||||
|| message.contains("insufficient data for metadata")
|
||||
|| message.contains("insufficient data for meta length")
|
||||
|| message.contains("insufficient data for CRC")
|
||||
{
|
||||
return true;
|
||||
}
|
||||
current = err.source();
|
||||
}
|
||||
false
|
||||
}
|
||||
|
||||
/// Read only the object revision without materializing its body.
|
||||
pub(crate) async fn read_config_revision<S: ScannerObjectIO>(store: Arc<S>, path: &str) -> StorageResult<DataUsageCacheRevision> {
|
||||
match store
|
||||
|
||||
Reference in New Issue
Block a user