fix: preserve data on self metadata copy (#2819)

Co-authored-by: cxymds <Cxymds@qq.com>
This commit is contained in:
安正超
2026-05-06 14:28:36 +08:00
committed by GitHub
parent 7692c0c3bd
commit 50ddec3ffc
7 changed files with 199 additions and 17 deletions
+1 -1
View File
@@ -2665,7 +2665,7 @@ impl DiskAPI for LocalDisk {
let mut xl_meta = FileMeta::load(buf.as_ref())?;
xl_meta.update_object_version(fi)?;
xl_meta.update_object_version_with_opts(fi, opts.replace_user_metadata)?;
let wbuf = xl_meta.marshal_msg()?;
+6 -1
View File
@@ -559,6 +559,7 @@ pub struct CheckPartsResp {
#[derive(Debug, Serialize, Deserialize, Default)]
pub struct UpdateMetadataOpts {
pub no_persistence: bool,
pub replace_user_metadata: bool,
}
pub struct DiskLocation {
@@ -914,9 +915,13 @@ mod tests {
/// Test UpdateMetadataOpts structure
#[test]
fn test_update_metadata_opts() {
let opts = UpdateMetadataOpts { no_persistence: true };
let opts = UpdateMetadataOpts {
no_persistence: true,
..Default::default()
};
assert!(opts.no_persistence);
assert!(!opts.replace_user_metadata);
}
/// Test DiskOption structure
+36 -14
View File
@@ -1446,7 +1446,6 @@ impl ObjectOperations for SetDisks {
}
};
let inline_data = fi.inline_data();
fi.metadata = src_info.user_defined.clone();
if let Some(etag) = &src_info.etag {
@@ -1454,27 +1453,50 @@ impl ObjectOperations for SetDisks {
}
let mod_time = OffsetDateTime::now_utc();
fi.mod_time = Some(mod_time);
fi.version_id = version_id;
fi.versioned = src_opts.versioned || src_opts.version_suspended;
for fi in metas.iter_mut() {
if fi.is_valid() {
fi.metadata = src_info.user_defined.clone();
fi.mod_time = Some(mod_time);
fi.version_id = version_id;
fi.versioned = src_opts.versioned || src_opts.version_suspended;
if src_info.version_only {
let inline_data = fi.inline_data();
if !fi.inline_data() {
fi.data = None;
}
for fi in metas.iter_mut() {
if fi.is_valid() {
fi.metadata = src_info.user_defined.clone();
if let Some(etag) = &src_info.etag {
fi.metadata.insert("etag".to_owned(), etag.clone());
}
fi.mod_time = Some(mod_time);
fi.version_id = version_id;
fi.versioned = src_opts.versioned || src_opts.version_suspended;
if inline_data {
fi.set_inline_data();
if !fi.inline_data() {
fi.data = None;
}
if inline_data {
fi.set_inline_data();
}
}
}
}
Self::write_unique_file_info(&online_disks, "", src_bucket, src_object, &metas, write_quorum)
Self::write_unique_file_info(&online_disks, "", src_bucket, src_object, &metas, write_quorum)
.await
.map_err(|e| to_object_err(e.into(), vec![src_bucket, src_object]))?;
} else {
self.update_object_meta_with_opts(
src_bucket,
src_object,
fi.clone(),
&online_disks,
&UpdateMetadataOpts {
replace_user_metadata: true,
..Default::default()
},
)
.await
.map_err(|e| to_object_err(e.into(), vec![src_bucket, src_object]))?;
}
Ok(ObjectInfo::from_file_info(
&fi,
+1 -1
View File
@@ -402,7 +402,7 @@ impl SetDisks {
disks: &[Option<DiskStore>],
opts: &UpdateMetadataOpts,
) -> disk::error::Result<()> {
if fi.metadata.is_empty() {
if fi.metadata.is_empty() && !opts.replace_user_metadata {
return Ok(());
}