Merge pull request #194 from rustfs/fix/metadata

fix: #189 #192
This commit is contained in:
weisd
2024-12-29 23:37:51 +08:00
committed by GitHub
9 changed files with 58 additions and 30 deletions
+3 -2
View File
@@ -14,7 +14,7 @@ use serde::{Deserialize, Serialize};
use std::collections::HashMap; use std::collections::HashMap;
use std::sync::Arc; use std::sync::Arc;
use time::OffsetDateTime; use time::OffsetDateTime;
use tracing::{error, warn}; use tracing::{error, info};
use crate::config::common::{read_config, save_config}; use crate::config::common::{read_config, save_config};
use crate::error::{Error, Result}; use crate::error::{Error, Result};
@@ -358,11 +358,12 @@ pub async fn load_bucket_metadata_parse(api: Arc<ECStore>, bucket: &str, parse:
let mut bm = match read_bucket_metadata(api.clone(), bucket).await { let mut bm = match read_bucket_metadata(api.clone(), bucket).await {
Ok(res) => res, Ok(res) => res,
Err(err) => { Err(err) => {
warn!("load_bucket_metadata_parse err {:?}", &err);
if !config::error::is_not_found(&err) { if !config::error::is_not_found(&err) {
return Err(err); return Err(err);
} }
info!("bucketmeta {} not found with err {:?}, start to init ", bucket, &err);
BucketMetadata::new(bucket) BucketMetadata::new(bucket)
} }
}; };
+2 -2
View File
@@ -761,7 +761,7 @@ impl LocalDisk {
Ok(res) => res, Ok(res) => res,
Err(e) => { Err(e) => {
if !DiskError::VolumeNotFound.is(&e) && !is_err_file_not_found(&e) { if !DiskError::VolumeNotFound.is(&e) && !is_err_file_not_found(&e) {
error!("scan list_dir {}, err {:?}", &current, &e); warn!("scan list_dir {}, err {:?}", &current, &e);
} }
if opts.report_notfound && is_err_file_not_found(&e) && current == &opts.base_dir { if opts.report_notfound && is_err_file_not_found(&e) && current == &opts.base_dir {
@@ -1443,7 +1443,7 @@ impl DiskAPI for LocalDisk {
check_path_length(file_path.to_string_lossy().to_string().as_str())?; check_path_length(file_path.to_string_lossy().to_string().as_str())?;
// TODO: writeAllDirect io.copy // TODO: writeAllDirect io.copy
info!("file_path: {:?}", file_path); // info!("file_path: {:?}", file_path);
if let Some(parent) = file_path.parent() { if let Some(parent) = file_path.parent() {
os::make_dir_all(parent, &volume_dir).await?; os::make_dir_all(parent, &volume_dir).await?;
} }
+1
View File
@@ -28,6 +28,7 @@ pub mod store_api;
pub mod store_err; pub mod store_err;
mod store_init; mod store_init;
pub mod store_list_objects; pub mod store_list_objects;
mod store_utils;
pub mod utils; pub mod utils;
pub mod xhttp; pub mod xhttp;
+4 -2
View File
@@ -3957,6 +3957,8 @@ impl StorageAPI for SetDisks {
} }
let (fi, _, _) = self.get_object_fileinfo(bucket, object, opts, false).await?; let (fi, _, _) = self.get_object_fileinfo(bucket, object, opts, false).await?;
// warn!("get object_info fi {:?}", &fi);
let oi = fi.to_object_info(bucket, object, opts.versioned || opts.version_suspended); let oi = fi.to_object_info(bucket, object, opts.versioned || opts.version_suspended);
Ok(oi) Ok(oi)
@@ -4018,14 +4020,14 @@ impl StorageAPI for SetDisks {
let obj_info = fi.to_object_info(bucket, object, opts.versioned || opts.version_suspended); let obj_info = fi.to_object_info(bucket, object, opts.versioned || opts.version_suspended);
if let Some(ref mut metadata) = fi.metadata { if let Some(ref mut metadata) = fi.metadata {
for (k, v) in obj_info.user_defined { for (k, v) in obj_info.user_defined.unwrap_or_default() {
metadata.insert(k, v); metadata.insert(k, v);
} }
fi.metadata = Some(metadata.clone()) fi.metadata = Some(metadata.clone())
} else { } else {
let mut metadata = HashMap::new(); let mut metadata = HashMap::new();
for (k, v) in obj_info.user_defined { for (k, v) in obj_info.user_defined.unwrap_or_default() {
metadata.insert(k, v); metadata.insert(k, v);
} }
+27 -8
View File
@@ -1,4 +1,5 @@
use crate::heal::heal_ops::HealSequence; use crate::heal::heal_ops::HealSequence;
use crate::store_utils::clean_metadata;
use crate::{ use crate::{
disk::DiskStore, disk::DiskStore,
error::{Error, Result}, error::{Error, Result},
@@ -171,6 +172,7 @@ impl FileInfo {
version_id = Some(Uuid::nil()) version_id = Some(Uuid::nil())
} }
// etag
let (content_type, content_encoding, etag) = { let (content_type, content_encoding, etag) = {
if let Some(ref meta) = self.metadata { if let Some(ref meta) = self.metadata {
let content_type = meta.get("content-type").cloned(); let content_type = meta.get("content-type").cloned();
@@ -182,6 +184,7 @@ impl FileInfo {
(None, None, None) (None, None, None)
} }
}; };
// tags
let user_tags = self let user_tags = self
.metadata .metadata
.as_ref() .as_ref()
@@ -196,6 +199,15 @@ impl FileInfo {
let inlined = self.inline_data(); let inlined = self.inline_data();
// TODO:expires
// TODO:ReplicationState
// TODO:TransitionedObject
let metadata = self.metadata.clone().map(|mut v| {
clean_metadata(&mut v);
v
});
ObjectInfo { ObjectInfo {
bucket: bucket.to_string(), bucket: bucket.to_string(),
name, name,
@@ -215,6 +227,7 @@ impl FileInfo {
successor_mod_time: self.successor_mod_time, successor_mod_time: self.successor_mod_time,
etag, etag,
inlined, inlined,
user_defined: metadata,
..Default::default() ..Default::default()
} }
} }
@@ -627,7 +640,7 @@ pub struct ObjectInfo {
// Actual size is the real size of the object uploaded by client. // Actual size is the real size of the object uploaded by client.
pub actual_size: Option<usize>, pub actual_size: Option<usize>,
pub is_dir: bool, pub is_dir: bool,
pub user_defined: HashMap<String, String>, pub user_defined: Option<HashMap<String, String>>,
pub parity_blocks: usize, pub parity_blocks: usize,
pub data_blocks: usize, pub data_blocks: usize,
pub version_id: Option<Uuid>, pub version_id: Option<Uuid>,
@@ -646,8 +659,11 @@ pub struct ObjectInfo {
impl ObjectInfo { impl ObjectInfo {
pub fn is_compressed(&self) -> bool { pub fn is_compressed(&self) -> bool {
self.user_defined if let Some(meta) = &self.user_defined {
.contains_key(&format!("{}compression", RESERVED_METADATA_PREFIX)) meta.contains_key(&format!("{}compression", RESERVED_METADATA_PREFIX))
} else {
false
}
} }
pub fn get_actual_size(&self) -> Result<usize> { pub fn get_actual_size(&self) -> Result<usize> {
@@ -656,13 +672,16 @@ impl ObjectInfo {
} }
if self.is_compressed() { if self.is_compressed() {
if let Some(size_str) = self.user_defined.get(&format!("{}actual-size", RESERVED_METADATA_PREFIX)) { if let Some(meta) = &self.user_defined {
if !size_str.is_empty() { if let Some(size_str) = meta.get(&format!("{}actual-size", RESERVED_METADATA_PREFIX)) {
// Todo: deal with error if !size_str.is_empty() {
let size = size_str.parse::<usize>()?; // Todo: deal with error
return Ok(size); let size = size_str.parse::<usize>()?;
return Ok(size);
}
} }
} }
let mut actual_size = 0; let mut actual_size = 0;
self.parts.iter().for_each(|part| { self.parts.iter().for_each(|part| {
actual_size += part.actual_size; actual_size += part.actual_size;
+2
View File
@@ -245,6 +245,8 @@ impl ECStore {
..Default::default() ..Default::default()
}; };
// warn!("list_objects_generic opts {:?}", &opts);
// use get // use get
if !opts.prefix.is_empty() && opts.limit == 1 && opts.marker.is_none() { if !opts.prefix.is_empty() && opts.limit == 1 && opts.marker.is_none() {
match self match self
+3 -9
View File
@@ -5,7 +5,7 @@ use serde::{Deserialize, Serialize};
use crate::heal_commands::HealResultItem; use crate::heal_commands::HealResultItem;
#[derive(Debug, Clone, Copy, Serialize, Deserialize)] #[derive(Debug, Clone, Copy, Serialize, Deserialize, Default)]
pub struct TraceType(u64); pub struct TraceType(u64);
impl TraceType { impl TraceType {
@@ -34,12 +34,6 @@ impl TraceType {
} }
} }
impl Default for TraceType {
fn default() -> Self {
Self(0)
}
}
impl TraceType { impl TraceType {
pub fn contains(&self, x: &TraceType) -> bool { pub fn contains(&self, x: &TraceType) -> bool {
(self.0 & x.0) == x.0 (self.0 & x.0) == x.0
@@ -54,12 +48,12 @@ impl TraceType {
} }
pub fn merge(&mut self, other: &TraceType) { pub fn merge(&mut self, other: &TraceType) {
self.0 = self.0 | other.0 self.0 |= other.0
} }
pub fn set_if(&mut self, b: bool, other: &TraceType) { pub fn set_if(&mut self, b: bool, other: &TraceType) {
if b { if b {
self.0 = self.0 | other.0 self.0 |= other.0
} }
} }
+7 -2
View File
@@ -52,6 +52,7 @@ use transform_stream::AsyncTryStream;
use uuid::Uuid; use uuid::Uuid;
use crate::storage::error::to_s3_error; use crate::storage::error::to_s3_error;
use crate::storage::options::extract_metadata_from_mime;
macro_rules! try_ { macro_rules! try_ {
($result:expr) => { ($result:expr) => {
@@ -411,7 +412,7 @@ impl S3 for FS {
}; };
let last_modified = info.mod_time.map(Timestamp::from); let last_modified = info.mod_time.map(Timestamp::from);
let metadata = Some(info.user_defined); let metadata = info.user_defined;
let output = HeadObjectOutput { let output = HeadObjectOutput {
content_length: Some(try_!(i64::try_from(info.size))), content_length: Some(try_!(i64::try_from(info.size))),
@@ -642,6 +643,7 @@ impl S3 for FS {
key, key,
content_length, content_length,
tagging, tagging,
metadata,
.. ..
} = input; } = input;
@@ -667,7 +669,10 @@ impl S3 for FS {
return Err(S3Error::with_message(S3ErrorCode::InternalError, "Not init".to_string())); return Err(S3Error::with_message(S3ErrorCode::InternalError, "Not init".to_string()));
}; };
let mut metadata = extract_metadata(&req.headers); let mut metadata = metadata.unwrap_or_default();
extract_metadata_from_mime(&req.headers, &mut metadata);
if let Some(tags) = tagging { if let Some(tags) = tagging {
metadata.insert(xhttp::AMZ_OBJECT_TAGGING.to_owned(), tags); metadata.insert(xhttp::AMZ_OBJECT_TAGGING.to_owned(), tags);
} }
+9 -5
View File
@@ -130,15 +130,19 @@ pub fn extract_metadata(headers: &HeaderMap<HeaderValue>) -> HashMap<String, Str
metadata metadata
} }
fn extract_metadata_from_mime(headers: &HeaderMap<HeaderValue>, metadata: &mut HashMap<String, String>) { pub fn extract_metadata_from_mime(headers: &HeaderMap<HeaderValue>, metadata: &mut HashMap<String, String>) {
for (k, v) in headers.iter() { for (k, v) in headers.iter() {
if k.as_str().starts_with("x-amz-meta-") { if let Some(key) = k.as_str().strip_prefix("x-amz-meta-") {
metadata.insert(k.to_string(), String::from_utf8_lossy(v.as_bytes()).to_string()); if key.is_empty() {
continue;
}
metadata.insert(key.to_owned(), String::from_utf8_lossy(v.as_bytes()).to_string());
continue; continue;
} }
if k.as_str().starts_with("x-rustfs-meta-") { if let Some(key) = k.as_str().strip_prefix("x-rustfs-meta-") {
metadata.insert(k.to_string(), String::from_utf8_lossy(v.as_bytes()).to_string()); metadata.insert(key.to_owned(), String::from_utf8_lossy(v.as_bytes()).to_string());
continue; continue;
} }