fix(ecstore): map missing metadata to not found (#2944)

Co-authored-by: houseme <housemecn@gmail.com>
This commit is contained in:
cxymds
2026-05-13 21:03:15 +08:00
committed by GitHub
parent 4ea805cbc0
commit c65d4071a3
2 changed files with 56 additions and 0 deletions
+30
View File
@@ -5559,6 +5559,36 @@ mod tests {
assert_eq!(result, None); // No UUID meets quorum of 2
}
#[test]
fn test_object_quorum_from_meta_returns_not_found_when_all_metadata_is_missing() {
let errs = vec![
Some(DiskError::FileNotFound),
Some(DiskError::VolumeNotFound),
Some(DiskError::DiskNotFound),
Some(DiskError::FileNotFound),
];
let err = SetDisks::object_quorum_from_meta(&vec![FileInfo::default(); errs.len()], &errs, 2)
.expect_err("missing metadata should map to FileNotFound");
assert_eq!(err, DiskError::FileNotFound);
}
#[test]
fn test_object_quorum_from_meta_preserves_read_quorum_for_mixed_failures() {
let errs = vec![
Some(DiskError::FileNotFound),
Some(DiskError::VolumeNotFound),
Some(DiskError::FileCorrupt),
Some(DiskError::DiskNotFound),
];
let err = SetDisks::object_quorum_from_meta(&vec![FileInfo::default(); errs.len()], &errs, 2)
.expect_err("mixed metadata failures should keep quorum semantics");
assert_eq!(err, DiskError::ErasureReadQuorum);
}
#[test]
fn test_shuffle_parts_metadata() {
// Test metadata shuffling
+26
View File
@@ -15,6 +15,28 @@
use super::*;
impl SetDisks {
pub(super) fn all_not_found_metadata(errs: &[Option<DiskError>]) -> bool {
!errs.is_empty()
&& errs.iter().all(|err| match err {
Some(err) => {
matches!(
err,
DiskError::FileNotFound
| DiskError::FileVersionNotFound
| DiskError::VolumeNotFound
| DiskError::DiskNotFound
) || OBJECT_OP_IGNORED_ERRS.contains(err)
}
None => false,
})
&& errs.iter().any(|err| {
matches!(
err,
Some(DiskError::FileNotFound | DiskError::FileVersionNotFound | DiskError::VolumeNotFound)
)
})
}
pub(super) fn reduce_common_data_dir(data_dirs: &Vec<Option<Uuid>>, write_quorum: usize) -> Option<Uuid> {
let mut data_dirs_count = HashMap::new();
@@ -237,6 +259,10 @@ impl SetDisks {
errs: &[Option<DiskError>],
default_parity_count: usize,
) -> disk::error::Result<(i32, i32)> {
if Self::all_not_found_metadata(errs) {
return Err(DiskError::FileNotFound);
}
let expected_rquorum = if default_parity_count == 0 {
parts_metadata.len()
} else {