ecstore update ec/disk/error

This commit is contained in:
weisd
2025-06-04 14:26:46 +08:00
committed by weisd
parent 7fe0cc74d2
commit 9384b831ec
102 changed files with 18806 additions and 4864 deletions
+94 -110
View File
@@ -5,8 +5,11 @@ use crate::bucket::utils::{check_valid_bucket_name, check_valid_bucket_name_stri
use crate::config::storageclass;
use crate::config::GLOBAL_StorageClass;
use crate::disk::endpoint::{Endpoint, EndpointType};
use crate::disk::{DiskAPI, DiskInfo, DiskInfoOptions, MetaCacheEntry};
use crate::error::clone_err;
use crate::disk::{DiskAPI, DiskInfo, DiskInfoOptions};
use crate::error::{
is_err_bucket_exists, is_err_invalid_upload_id, is_err_object_not_found, is_err_read_quorum, is_err_version_not_found,
to_object_err, StorageError,
};
use crate::global::{
get_global_endpoints, is_dist_erasure, is_erasure_sd, set_global_deployment_id, set_object_layer, DISK_ASSUME_UNKNOWN_SIZE,
DISK_FILL_FRACTION, DISK_MIN_INODES, DISK_RESERVE_FRACTION, GLOBAL_BOOT_TIME, GLOBAL_LOCAL_DISK_MAP,
@@ -21,17 +24,13 @@ use crate::notification_sys::get_global_notification_sys;
use crate::pools::PoolMeta;
use crate::rebalance::RebalanceMeta;
use crate::store_api::{ListMultipartsInfo, ListObjectVersionsInfo, MultipartInfo, ObjectIO};
use crate::store_err::{
is_err_bucket_exists, is_err_decommission_already_running, is_err_invalid_upload_id, is_err_object_not_found,
is_err_read_quorum, is_err_version_not_found, to_object_err, StorageError,
};
use crate::store_init::ec_drives_no_config;
use crate::store_init::{check_disk_fatal_errs, ec_drives_no_config};
use crate::utils::crypto::base64_decode;
use crate::utils::path::{decode_dir_object, encode_dir_object, path_join_buf, SLASH_SEPARATOR};
use crate::utils::xml;
use crate::{
bucket::metadata::BucketMetadata,
disk::{error::DiskError, new_disk, DiskOption, DiskStore, BUCKET_META_PREFIX, RUSTFS_META_BUCKET},
disk::{new_disk, DiskOption, DiskStore, BUCKET_META_PREFIX, RUSTFS_META_BUCKET},
endpoints::EndpointServerPools,
peer::S3PeerSys,
sets::Sets,
@@ -43,7 +42,7 @@ use crate::{
store_init,
};
use common::error::{Error, Result};
use crate::error::{Error, Result};
use common::globals::{GLOBAL_Local_Node_Name, GLOBAL_Rustfs_Host, GLOBAL_Rustfs_Port};
use futures::future::join_all;
use glob::Pattern;
@@ -51,6 +50,7 @@ use http::HeaderMap;
use lazy_static::lazy_static;
use madmin::heal_commands::HealResultItem;
use rand::Rng;
use rustfs_filemeta::MetaCacheEntry;
use s3s::dto::{BucketVersioningStatus, ObjectLockConfiguration, ObjectLockEnabled, VersioningConfiguration};
use std::cmp::Ordering;
use std::process::exit;
@@ -62,8 +62,8 @@ use tokio::select;
use tokio::sync::mpsc::Sender;
use tokio::sync::{broadcast, mpsc, RwLock};
use tokio::time::{interval, sleep};
use tracing::error;
use tracing::{debug, info};
use tracing::{error, warn};
use uuid::Uuid;
const MAX_UPLOADS_LIST: usize = 10000;
@@ -144,7 +144,7 @@ impl ECStore {
)
.await;
DiskError::check_disk_fatal_errs(&errs)?;
check_disk_fatal_errs(&errs)?;
let fm = {
let mut times = 0;
@@ -166,7 +166,7 @@ impl ECStore {
interval *= 2;
}
if times > 10 {
return Err(Error::from_string("can not get formats"));
return Err(Error::other("can not get formats"));
}
info!("retrying get formats after {:?}", interval);
select! {
@@ -185,7 +185,7 @@ impl ECStore {
}
if deployment_id != Some(fm.id) {
return Err(Error::msg("deployment_id not same in one pool"));
return Err(Error::other("deployment_id not same in one pool"));
}
if deployment_id.is_some() && deployment_id.unwrap().is_nil() {
@@ -241,7 +241,7 @@ impl ECStore {
sleep(Duration::from_secs(wait_sec)).await;
if exit_count > 10 {
return Err(Error::msg("ec init faild"));
return Err(Error::other("ec init faild"));
}
exit_count += 1;
@@ -291,7 +291,7 @@ impl ECStore {
if let Some(idx) = endpoints.get_pool_idx(&p.cmd_line) {
pool_indeces.push(idx);
} else {
return Err(Error::msg(format!(
return Err(Error::other(format!(
"unexpected state present for decommission status pool({}) not found",
p.cmd_line
)));
@@ -310,7 +310,7 @@ impl ECStore {
tokio::time::sleep(Duration::from_secs(60 * 3)).await;
if let Err(err) = store.decommission(rx.resubscribe(), pool_indeces.clone()).await {
if is_err_decommission_already_running(&err) {
if err == StorageError::DecommissionAlreadyRunning {
for i in pool_indeces.iter() {
store.do_decommission_in_routine(rx.resubscribe(), *i).await;
}
@@ -341,7 +341,7 @@ impl ECStore {
// define in store_list_objects.rs
// pub async fn list_path(&self, opts: &ListPathOptions, delimiter: &str) -> Result<ListObjectsInfo> {
// // if opts.prefix.ends_with(SLASH_SEPARATOR) {
// // return Err(Error::msg("eof"));
// // return Err(Error::other("eof"));
// // }
// let mut opts = opts.clone();
@@ -614,7 +614,7 @@ impl ECStore {
if let Some(hit_idx) = self.get_available_pool_idx(bucket, object, size).await {
hit_idx
} else {
return Err(Error::new(DiskError::DiskFull));
return Err(Error::DiskFull);
}
}
};
@@ -633,7 +633,8 @@ impl ECStore {
if let Some(idx) = self.get_available_pool_idx(bucket, object, size).await {
idx
} else {
return Err(to_object_err(Error::new(DiskError::DiskFull), vec![bucket, object]));
warn!("get_pool_idx_no_lock: disk full {}/{}", bucket, object);
return Err(Error::DiskFull);
}
}
};
@@ -731,7 +732,7 @@ impl ECStore {
let err = pinfo.err.as_ref().unwrap();
if is_err_read_quorum(err) && !opts.metadata_chg {
if err == &Error::ErasureReadQuorum && !opts.metadata_chg {
return Ok((pinfo.clone(), self.pools_with_object(&ress, opts).await));
}
@@ -739,7 +740,7 @@ impl ECStore {
has_def_pool = true;
if !is_err_object_not_found(err) && !is_err_version_not_found(err) {
return Err(clone_err(err));
return Err(err.clone());
}
if pinfo.object_info.delete_marker && !pinfo.object_info.name.is_empty() {
@@ -751,7 +752,7 @@ impl ECStore {
return Ok((def_pool, Vec::new()));
}
Err(to_object_err(Error::new(DiskError::FileNotFound), vec![bucket, object]))
Err(Error::ObjectNotFound(bucket.to_owned(), object.to_owned()))
}
async fn pools_with_object(&self, pools: &[PoolObjInfo], opts: &ObjectOptions) -> Vec<PoolErr> {
@@ -767,10 +768,10 @@ impl ECStore {
}
if let Some(err) = &pool.err {
if is_err_read_quorum(err) {
if err == &Error::ErasureReadQuorum {
errs.push(PoolErr {
index: Some(pool.index),
err: Some(Error::new(StorageError::InsufficientReadQuorum)),
err: Some(Error::ErasureReadQuorum),
});
}
} else {
@@ -878,7 +879,7 @@ impl ECStore {
}
let _ = task.await;
if let Some(err) = first_err.read().await.as_ref() {
return Err(clone_err(err));
return Err(err.clone());
}
Ok(())
}
@@ -961,13 +962,13 @@ impl ECStore {
let object = decode_dir_object(object);
if opts.version_id.is_none() {
Err(Error::new(StorageError::ObjectNotFound(bucket.to_owned(), object.to_owned())))
Err(StorageError::ObjectNotFound(bucket.to_owned(), object.to_owned()))
} else {
Err(Error::new(StorageError::VersionNotFound(
Err(StorageError::VersionNotFound(
bucket.to_owned(),
object.to_owned(),
opts.version_id.clone().unwrap_or_default(),
)))
))
}
}
@@ -983,9 +984,9 @@ impl ECStore {
for pe in errs.iter() {
if let Some(err) = &pe.err {
if is_err_read_quorum(err) {
if err == &StorageError::ErasureWriteQuorum {
objs.push(None);
derrs.push(Some(Error::new(StorageError::InsufficientWriteQuorum)));
derrs.push(Some(StorageError::ErasureWriteQuorum));
continue;
}
}
@@ -1006,7 +1007,7 @@ impl ECStore {
}
if let Some(e) = &derrs[0] {
return Err(clone_err(e));
return Err(e.clone());
}
Ok(objs[0].as_ref().unwrap().clone())
@@ -1142,7 +1143,7 @@ impl Clone for PoolObjInfo {
Self {
index: self.index,
object_info: self.object_info.clone(),
err: self.err.as_ref().map(clone_err),
err: self.err.clone(),
}
}
}
@@ -1219,11 +1220,11 @@ impl ObjectIO for ECStore {
let idx = self.get_pool_idx(bucket, &object, data.content_length as i64).await?;
if opts.data_movement && idx == opts.src_pool_idx {
return Err(Error::new(StorageError::DataMovementOverwriteErr(
return Err(StorageError::DataMovementOverwriteErr(
bucket.to_owned(),
object.to_owned(),
opts.version_id.clone().unwrap_or_default(),
)));
));
}
self.pools[idx].put_object(bucket, &object, data, opts).await
@@ -1327,7 +1328,7 @@ impl StorageAPI for ECStore {
}
if let Err(err) = self.peer_sys.make_bucket(bucket, opts).await {
if !is_err_bucket_exists(&err) {
if !is_err_bucket_exists(&err.into()) {
let _ = self
.delete_bucket(
bucket,
@@ -1354,7 +1355,7 @@ impl StorageAPI for ECStore {
meta.versioning_config_xml = xml::serialize::<VersioningConfiguration>(&enableVersioningConfig)?;
}
meta.save().await.map_err(|e| to_object_err(e, vec![bucket]))?;
meta.save().await?;
set_bucket_metadata(bucket.to_string(), meta).await?;
@@ -1363,11 +1364,7 @@ impl StorageAPI for ECStore {
#[tracing::instrument(skip(self))]
async fn get_bucket_info(&self, bucket: &str, opts: &BucketOptions) -> Result<BucketInfo> {
let mut info = self
.peer_sys
.get_bucket_info(bucket, opts)
.await
.map_err(|e| to_object_err(e, vec![bucket]))?;
let mut info = self.peer_sys.get_bucket_info(bucket, opts).await?;
if let Ok(sys) = metadata_sys::get(bucket).await {
info.created = Some(sys.created);
@@ -1413,7 +1410,7 @@ impl StorageAPI for ECStore {
self.peer_sys
.delete_bucket(bucket, &opts)
.await
.map_err(|e| to_object_err(e, vec![bucket]))?;
.map_err(|e| to_object_err(e.into(), vec![bucket]))?;
// TODO: replication opts.srdelete_op
@@ -1537,11 +1534,11 @@ impl StorageAPI for ECStore {
.await;
}
Err(Error::new(StorageError::InvalidArgument(
Err(StorageError::InvalidArgument(
src_bucket.to_owned(),
src_object.to_owned(),
"put_object_reader is none".to_owned(),
)))
))
}
#[tracing::instrument(skip(self))]
async fn delete_object(&self, bucket: &str, object: &str, opts: ObjectOptions) -> Result<ObjectInfo> {
@@ -1563,7 +1560,7 @@ impl StorageAPI for ECStore {
.await
.map_err(|e| {
if is_err_read_quorum(&e) {
Error::new(StorageError::InsufficientWriteQuorum)
StorageError::ErasureWriteQuorum
} else {
e
}
@@ -1575,11 +1572,11 @@ impl StorageAPI for ECStore {
}
if opts.data_movement && opts.src_pool_idx == pinfo.index {
return Err(Error::new(StorageError::DataMovementOverwriteErr(
return Err(StorageError::DataMovementOverwriteErr(
bucket.to_owned(),
object.to_owned(),
opts.version_id.unwrap_or_default(),
)));
));
}
if opts.data_movement {
@@ -1608,10 +1605,10 @@ impl StorageAPI for ECStore {
}
if let Some(ver) = opts.version_id {
return Err(Error::new(StorageError::VersionNotFound(bucket.to_owned(), object.to_owned(), ver)));
return Err(StorageError::VersionNotFound(bucket.to_owned(), object.to_owned(), ver));
}
Err(Error::new(StorageError::ObjectNotFound(bucket.to_owned(), object.to_owned())))
Err(StorageError::ObjectNotFound(bucket.to_owned(), object.to_owned()))
}
// TODO: review
#[tracing::instrument(skip(self))]
@@ -1843,11 +1840,11 @@ impl StorageAPI for ECStore {
let idx = self.get_pool_idx(bucket, object, -1).await?;
if opts.data_movement && idx == opts.src_pool_idx {
return Err(Error::new(StorageError::DataMovementOverwriteErr(
return Err(StorageError::DataMovementOverwriteErr(
bucket.to_owned(),
object.to_owned(),
"".to_owned(),
)));
));
}
self.pools[idx].new_multipart_upload(bucket, object, opts).await
@@ -1914,11 +1911,7 @@ impl StorageAPI for ECStore {
}
}
Err(Error::new(StorageError::InvalidUploadID(
bucket.to_owned(),
object.to_owned(),
upload_id.to_owned(),
)))
Err(StorageError::InvalidUploadID(bucket.to_owned(), object.to_owned(), upload_id.to_owned()))
}
#[tracing::instrument(skip(self))]
@@ -1951,11 +1944,7 @@ impl StorageAPI for ECStore {
};
}
Err(Error::new(StorageError::InvalidUploadID(
bucket.to_owned(),
object.to_owned(),
upload_id.to_owned(),
)))
Err(StorageError::InvalidUploadID(bucket.to_owned(), object.to_owned(), upload_id.to_owned()))
}
#[tracing::instrument(skip(self))]
async fn abort_multipart_upload(&self, bucket: &str, object: &str, upload_id: &str, opts: &ObjectOptions) -> Result<()> {
@@ -1989,11 +1978,7 @@ impl StorageAPI for ECStore {
}
}
Err(Error::new(StorageError::InvalidUploadID(
bucket.to_owned(),
object.to_owned(),
upload_id.to_owned(),
)))
Err(StorageError::InvalidUploadID(bucket.to_owned(), object.to_owned(), upload_id.to_owned()))
}
#[tracing::instrument(skip(self))]
@@ -2038,11 +2023,7 @@ impl StorageAPI for ECStore {
}
}
Err(Error::new(StorageError::InvalidUploadID(
bucket.to_owned(),
object.to_owned(),
upload_id.to_owned(),
)))
Err(StorageError::InvalidUploadID(bucket.to_owned(), object.to_owned(), upload_id.to_owned()))
}
#[tracing::instrument(skip(self))]
@@ -2050,7 +2031,7 @@ impl StorageAPI for ECStore {
if pool_idx < self.pools.len() && set_idx < self.pools[pool_idx].disk_set.len() {
self.pools[pool_idx].disk_set[set_idx].get_disks(0, 0).await
} else {
Err(Error::msg(format!("pool idx {}, set idx {}, not found", pool_idx, set_idx)))
Err(Error::other(format!("pool idx {}, set idx {}, not found", pool_idx, set_idx)))
}
}
@@ -2129,8 +2110,8 @@ impl StorageAPI for ECStore {
for pool in self.pools.iter() {
let (mut result, err) = pool.heal_format(dry_run).await?;
if let Some(err) = err {
match err.downcast_ref::<DiskError>() {
Some(DiskError::NoHealRequired) => {
match err {
StorageError::NoHealRequired => {
count_no_heal += 1;
}
_ => {
@@ -2145,7 +2126,7 @@ impl StorageAPI for ECStore {
}
if count_no_heal == self.pools.len() {
info!("heal format success, NoHealRequired");
return Ok((r, Some(Error::new(DiskError::NoHealRequired))));
return Ok((r, Some(StorageError::NoHealRequired)));
}
info!("heal format success result: {:?}", r);
Ok((r, None))
@@ -2153,7 +2134,9 @@ impl StorageAPI for ECStore {
#[tracing::instrument(skip(self))]
async fn heal_bucket(&self, bucket: &str, opts: &HealOpts) -> Result<HealResultItem> {
self.peer_sys.heal_bucket(bucket, opts).await
let res = self.peer_sys.heal_bucket(bucket, opts).await?;
Ok(res)
}
#[tracing::instrument(skip(self))]
async fn heal_object(
@@ -2212,10 +2195,12 @@ impl StorageAPI for ECStore {
// No pool returned a nil error, return the first non 'not found' error
for (index, err) in errs.iter().enumerate() {
match err {
Some(err) => match err.downcast_ref::<DiskError>() {
Some(DiskError::FileNotFound) | Some(DiskError::FileVersionNotFound) => {}
_ => return Ok((ress.remove(index), Some(clone_err(err)))),
},
Some(err) => {
if is_err_object_not_found(&err) || is_err_version_not_found(&err) {
continue;
}
return Ok((ress.remove(index), Some(err.clone())));
}
None => {
return Ok((ress.remove(index), None));
}
@@ -2224,10 +2209,10 @@ impl StorageAPI for ECStore {
// At this stage, all errors are 'not found'
if !version_id.is_empty() {
return Ok((HealResultItem::default(), Some(Error::new(DiskError::FileVersionNotFound))));
return Ok((HealResultItem::default(), Some(Error::FileVersionNotFound)));
}
Ok((HealResultItem::default(), Some(Error::new(DiskError::FileNotFound))))
Ok((HealResultItem::default(), Some(Error::FileNotFound)))
}
#[tracing::instrument(skip(self))]
@@ -2271,7 +2256,9 @@ impl StorageAPI for ECStore {
};
if opts_clone.remove && !opts_clone.dry_run {
let Some(store) = new_object_layer_fn() else { return Err(Error::msg("errServerNotInitialized")) };
let Some(store) = new_object_layer_fn() else {
return Err(Error::other("errServerNotInitialized"));
};
if let Err(err) = store.check_abandoned_parts(&bucket, &entry.name, &opts_clone).await {
info!("unable to check object {}/{} for abandoned data: {}", bucket, entry.name, err.to_string());
@@ -2288,8 +2275,8 @@ impl StorageAPI for ECStore {
)
.await
{
match err.downcast_ref() {
Some(DiskError::FileNotFound) | Some(DiskError::FileVersionNotFound) => {}
match err {
Error::FileNotFound | Error::FileVersionNotFound => {}
_ => {
return Err(err);
}
@@ -2304,8 +2291,8 @@ impl StorageAPI for ECStore {
)
.await
{
match err.downcast_ref() {
Some(DiskError::FileNotFound) | Some(DiskError::FileVersionNotFound) => {}
match err {
Error::FileNotFound | Error::FileVersionNotFound => {}
_ => {
return Err(err);
}
@@ -2354,7 +2341,7 @@ impl StorageAPI for ECStore {
}
}
Err(Error::new(DiskError::DiskNotFound))
Err(Error::DiskNotFound)
}
#[tracing::instrument(skip(self))]
@@ -2373,7 +2360,7 @@ impl StorageAPI for ECStore {
}
if !errs.is_empty() {
return Err(clone_err(&errs[0]));
return Err(errs[0].clone());
}
Ok(())
@@ -2417,11 +2404,11 @@ fn is_valid_object_name(object: &str) -> bool {
fn check_object_name_for_length_and_slash(bucket: &str, object: &str) -> Result<()> {
if object.len() > 1024 {
return Err(Error::new(StorageError::ObjectNameTooLong(bucket.to_owned(), object.to_owned())));
return Err(StorageError::ObjectNameTooLong(bucket.to_owned(), object.to_owned()));
}
if object.starts_with(SLASH_SEPARATOR) {
return Err(Error::new(StorageError::ObjectNamePrefixAsSlash(bucket.to_owned(), object.to_owned())));
return Err(StorageError::ObjectNamePrefixAsSlash(bucket.to_owned(), object.to_owned()));
}
#[cfg(target_os = "windows")]
@@ -2435,7 +2422,7 @@ fn check_object_name_for_length_and_slash(bucket: &str, object: &str) -> Result<
|| object.contains('<')
|| object.contains('>')
{
return Err(Error::new(StorageError::ObjectNameInvalid(bucket.to_owned(), object.to_owned())));
return Err(StorageError::ObjectNameInvalid(bucket.to_owned(), object.to_owned()));
}
}
@@ -2456,19 +2443,19 @@ fn check_del_obj_args(bucket: &str, object: &str) -> Result<()> {
fn check_bucket_and_object_names(bucket: &str, object: &str) -> Result<()> {
if !is_meta_bucketname(bucket) && check_valid_bucket_name_strict(bucket).is_err() {
return Err(Error::new(StorageError::BucketNameInvalid(bucket.to_string())));
return Err(StorageError::BucketNameInvalid(bucket.to_string()));
}
if object.is_empty() {
return Err(Error::new(StorageError::ObjectNameInvalid(bucket.to_string(), object.to_string())));
return Err(StorageError::ObjectNameInvalid(bucket.to_string(), object.to_string()));
}
if !is_valid_object_prefix(object) {
return Err(Error::new(StorageError::ObjectNameInvalid(bucket.to_string(), object.to_string())));
return Err(StorageError::ObjectNameInvalid(bucket.to_string(), object.to_string()));
}
if cfg!(target_os = "windows") && object.contains('\\') {
return Err(Error::new(StorageError::ObjectNameInvalid(bucket.to_string(), object.to_string())));
return Err(StorageError::ObjectNameInvalid(bucket.to_string(), object.to_string()));
}
Ok(())
@@ -2476,11 +2463,11 @@ fn check_bucket_and_object_names(bucket: &str, object: &str) -> Result<()> {
pub fn check_list_objs_args(bucket: &str, prefix: &str, _marker: &Option<String>) -> Result<()> {
if !is_meta_bucketname(bucket) && check_valid_bucket_name_strict(bucket).is_err() {
return Err(Error::new(StorageError::BucketNameInvalid(bucket.to_string())));
return Err(StorageError::BucketNameInvalid(bucket.to_string()));
}
if !is_valid_object_prefix(prefix) {
return Err(Error::new(StorageError::ObjectNameInvalid(bucket.to_string(), prefix.to_string())));
return Err(StorageError::ObjectNameInvalid(bucket.to_string(), prefix.to_string()));
}
Ok(())
@@ -2498,15 +2485,15 @@ fn check_list_multipart_args(
if let Some(upload_id_marker) = upload_id_marker {
if let Some(key_marker) = key_marker {
if key_marker.ends_with('/') {
return Err(Error::new(StorageError::InvalidUploadIDKeyCombination(
return Err(StorageError::InvalidUploadIDKeyCombination(
upload_id_marker.to_string(),
key_marker.to_string(),
)));
));
}
}
if let Err(_e) = base64_decode(upload_id_marker.as_bytes()) {
return Err(Error::new(StorageError::MalformedUploadID(upload_id_marker.to_owned())));
return Err(StorageError::MalformedUploadID(upload_id_marker.to_owned()));
}
}
@@ -2515,13 +2502,13 @@ fn check_list_multipart_args(
fn check_object_args(bucket: &str, object: &str) -> Result<()> {
if !is_meta_bucketname(bucket) && check_valid_bucket_name_strict(bucket).is_err() {
return Err(Error::new(StorageError::BucketNameInvalid(bucket.to_string())));
return Err(StorageError::BucketNameInvalid(bucket.to_string()));
}
check_object_name_for_length_and_slash(bucket, object)?;
if !is_valid_object_name(object) {
return Err(Error::new(StorageError::ObjectNameInvalid(bucket.to_string(), object.to_string())));
return Err(StorageError::ObjectNameInvalid(bucket.to_string(), object.to_string()));
}
Ok(())
@@ -2533,10 +2520,7 @@ fn check_new_multipart_args(bucket: &str, object: &str) -> Result<()> {
fn check_multipart_object_args(bucket: &str, object: &str, upload_id: &str) -> Result<()> {
if let Err(e) = base64_decode(upload_id.as_bytes()) {
return Err(Error::new(StorageError::MalformedUploadID(format!(
"{}/{}-{},err:{}",
bucket, object, upload_id, e
))));
return Err(StorageError::MalformedUploadID(format!("{}/{}-{},err:{}", bucket, object, upload_id, e)));
};
check_object_args(bucket, object)
}
@@ -2560,13 +2544,13 @@ fn check_abort_multipart_args(bucket: &str, object: &str, upload_id: &str) -> Re
#[tracing::instrument(level = "debug")]
fn check_put_object_args(bucket: &str, object: &str) -> Result<()> {
if !is_meta_bucketname(bucket) && check_valid_bucket_name_strict(bucket).is_err() {
return Err(Error::new(StorageError::BucketNameInvalid(bucket.to_string())));
return Err(StorageError::BucketNameInvalid(bucket.to_string()));
}
check_object_name_for_length_and_slash(bucket, object)?;
if object.is_empty() || !is_valid_object_prefix(object) {
return Err(Error::new(StorageError::ObjectNameInvalid(bucket.to_string(), object.to_string())));
return Err(StorageError::ObjectNameInvalid(bucket.to_string(), object.to_string()));
}
Ok(())
@@ -2659,7 +2643,7 @@ pub async fn has_space_for(dis: &[Option<DiskInfo>], size: i64) -> Result<bool>
}
if disks_num < dis.len() / 2 || disks_num == 0 {
return Err(Error::msg(format!(
return Err(Error::other(format!(
"not enough online disks to calculate the available space,need {}, found {}",
(dis.len() / 2) + 1,
disks_num,