mirror of
https://github.com/rustfs/rustfs.git
synced 2026-08-20 19:42:17 +00:00
fix: handle duplicate part numbers in CompleteMultipartUpload (#1584)
Co-authored-by: loverustfs <hello@rustfs.com> Co-authored-by: houseme <housemecn@gmail.com>
This commit is contained in:
@@ -5718,17 +5718,20 @@ impl StorageAPI for SetDisks {
|
||||
..Default::default()
|
||||
};
|
||||
|
||||
// Build a lookup map for O(1) part resolution instead of O(n) find() in the loop
|
||||
// This optimizes from O(n^2) to O(n) when processing many parts
|
||||
use std::collections::HashMap;
|
||||
let part_lookup: HashMap<usize, &rustfs_filemeta::ObjectPartInfo> =
|
||||
curr_fi.parts.iter().map(|part| (part.number, part)).collect();
|
||||
|
||||
for (i, p) in uploaded_parts.iter().enumerate() {
|
||||
let has_part = curr_fi.parts.iter().find(|v| v.number == p.part_num);
|
||||
if has_part.is_none() {
|
||||
let Some(ext_part) = part_lookup.get(&p.part_num) else {
|
||||
error!(
|
||||
"complete_multipart_upload has_part.is_none() {:?}, part_id={}, bucket={}, object={}",
|
||||
has_part, p.part_num, bucket, object
|
||||
"complete_multipart_upload part not found: part_id={}, bucket={}, object={}",
|
||||
p.part_num, bucket, object
|
||||
);
|
||||
return Err(Error::InvalidPart(p.part_num, "".to_owned(), p.etag.clone().unwrap_or_default()));
|
||||
}
|
||||
|
||||
let ext_part = &curr_fi.parts[i];
|
||||
};
|
||||
info!(target:"rustfs_ecstore::set_disk", part_number = p.part_num, part_size = ext_part.size, part_actual_size = ext_part.actual_size, "Completing multipart part");
|
||||
|
||||
// Normalize ETags by removing quotes before comparison (PR #592 compatibility)
|
||||
|
||||
Reference in New Issue
Block a user