mirror of
https://github.com/rustfs/rustfs.git
synced 2026-07-27 16:48:58 +00:00
add all StorageErr
This commit is contained in:
+88
-15
@@ -1,36 +1,103 @@
|
||||
use crate::error::{Error, Result};
|
||||
use crate::{
|
||||
error::{Error, Result},
|
||||
quorum::CheckErrorFn,
|
||||
};
|
||||
|
||||
// DiskError == StorageErr
|
||||
#[derive(Debug, thiserror::Error)]
|
||||
pub enum DiskError {
|
||||
#[error("maximum versions exceeded, please delete few versions to proceed")]
|
||||
MaxVersionsExceeded,
|
||||
|
||||
#[error("unexpected error")]
|
||||
Unexpected,
|
||||
|
||||
#[error("corrupted format")]
|
||||
CorruptedFormat,
|
||||
|
||||
#[error("corrupted backend")]
|
||||
CorruptedBackend,
|
||||
|
||||
#[error("unformatted disk error")]
|
||||
UnformattedDisk,
|
||||
|
||||
#[error("inconsistent drive found")]
|
||||
InconsistentDisk,
|
||||
|
||||
#[error("drive does not support O_DIRECT")]
|
||||
UnsupportedDisk,
|
||||
|
||||
#[error("drive path full")]
|
||||
DiskFull,
|
||||
|
||||
#[error("disk not a dir")]
|
||||
DiskNotDir,
|
||||
|
||||
#[error("disk not found")]
|
||||
DiskNotFound,
|
||||
|
||||
#[error("drive still did not complete the request")]
|
||||
DiskOngoingReq,
|
||||
|
||||
#[error("drive is part of root drive, will not be used")]
|
||||
DriveIsRoot,
|
||||
|
||||
#[error("remote drive is faulty")]
|
||||
FaultyRemoteDisk,
|
||||
|
||||
#[error("drive is faulty")]
|
||||
FaultyDisk,
|
||||
|
||||
#[error("drive access denied")]
|
||||
DiskAccessDenied,
|
||||
|
||||
#[error("file not found")]
|
||||
FileNotFound,
|
||||
|
||||
#[error("file version not found")]
|
||||
FileVersionNotFound,
|
||||
|
||||
#[error("disk not found")]
|
||||
DiskNotFound,
|
||||
#[error("too many open files, please increase 'ulimit -n'")]
|
||||
TooManyOpenFiles,
|
||||
|
||||
#[error("disk access denied")]
|
||||
FileAccessDenied,
|
||||
|
||||
#[error("InconsistentDisk")]
|
||||
InconsistentDisk,
|
||||
#[error("file name too long")]
|
||||
FileNameTooLong,
|
||||
|
||||
#[error("volume already exists")]
|
||||
VolumeExists,
|
||||
|
||||
#[error("unformatted disk error")]
|
||||
UnformattedDisk,
|
||||
#[error("not of regular file type")]
|
||||
IsNotRegular,
|
||||
|
||||
#[error("unsupport disk")]
|
||||
UnsupportedDisk,
|
||||
|
||||
#[error("disk not a dir")]
|
||||
DiskNotDir,
|
||||
#[error("path not found")]
|
||||
PathNotFound,
|
||||
|
||||
#[error("volume not found")]
|
||||
VolumeNotFound,
|
||||
|
||||
#[error("volume is not empty")]
|
||||
VolumeNotEmpty,
|
||||
|
||||
#[error("volume access denied")]
|
||||
VolumeAccessDenied,
|
||||
|
||||
#[error("disk access denied")]
|
||||
FileAccessDenied,
|
||||
|
||||
#[error("file is corrupted")]
|
||||
FileCorrupt,
|
||||
|
||||
#[error("bit-rot hash algorithm is invalid")]
|
||||
BitrotHashAlgoInvalid,
|
||||
|
||||
#[error("Rename across devices not allowed, please fix your backend configuration")]
|
||||
CrossDeviceLink,
|
||||
|
||||
#[error("less data available than what was requested")]
|
||||
LessData,
|
||||
|
||||
#[error("more data was sent than what was advertised")]
|
||||
MoreData,
|
||||
}
|
||||
|
||||
impl DiskError {
|
||||
@@ -93,3 +160,9 @@ impl PartialEq for DiskError {
|
||||
core::mem::discriminant(self) == core::mem::discriminant(other)
|
||||
}
|
||||
}
|
||||
|
||||
impl CheckErrorFn for DiskError {
|
||||
fn is(&self, e: &Error) -> bool {
|
||||
self.is(e)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -94,7 +94,7 @@ impl Erasure {
|
||||
|
||||
warn!("Erasure encode errs {:?}", errs);
|
||||
|
||||
let err_idx = reduce_write_quorum_errs(&errs, object_ignored_errs().as_slice(), write_quorum)?;
|
||||
let err_idx = reduce_write_quorum_errs(&errs, object_ignored_errs().as_ref(), write_quorum)?;
|
||||
if errs[err_idx].is_some() {
|
||||
let err = errs[err_idx].take().unwrap();
|
||||
return Err(err);
|
||||
|
||||
+22
-10
@@ -1,7 +1,11 @@
|
||||
use crate::{disk::error::DiskError, error::Error};
|
||||
use std::collections::HashMap;
|
||||
use std::{collections::HashMap, fmt::Debug};
|
||||
|
||||
pub type CheckErrorFn = fn(e: &Error) -> bool;
|
||||
// pub type CheckErrorFn = fn(e: &Error) -> bool;
|
||||
|
||||
pub trait CheckErrorFn: Debug + Send + Sync + 'static {
|
||||
fn is(&self, e: &Error) -> bool;
|
||||
}
|
||||
|
||||
#[derive(Debug, thiserror::Error)]
|
||||
enum QuorumError {
|
||||
@@ -15,17 +19,25 @@ pub fn is_file_not_found(e: &Error) -> bool {
|
||||
DiskError::FileNotFound.is(e)
|
||||
}
|
||||
|
||||
pub fn object_ignored_errs() -> Vec<CheckErrorFn> {
|
||||
vec![is_file_not_found]
|
||||
pub fn base_ignored_errs() -> Vec<Box<dyn CheckErrorFn>> {
|
||||
vec![
|
||||
Box::new(DiskError::DiskNotFound),
|
||||
Box::new(DiskError::FaultyDisk),
|
||||
Box::new(DiskError::FaultyRemoteDisk),
|
||||
]
|
||||
}
|
||||
|
||||
pub fn object_ignored_errs() -> Vec<Box<dyn CheckErrorFn>> {
|
||||
vec![Box::new(DiskError::FileNotFound)]
|
||||
}
|
||||
|
||||
// 用于检查错误是否被忽略的函数
|
||||
fn is_err_ignored(err: &Error, ignored_errs: &[CheckErrorFn]) -> bool {
|
||||
ignored_errs.iter().any(|&ignored_err| ignored_err(err))
|
||||
fn is_err_ignored(err: &Error, ignored_errs: &Vec<Box<dyn CheckErrorFn>>) -> bool {
|
||||
ignored_errs.iter().any(|ignored_err| ignored_err.is(err))
|
||||
}
|
||||
|
||||
// 减少错误数量并返回出现次数最多的错误
|
||||
fn reduce_errs(errs: &Vec<Option<Error>>, ignored_errs: &[CheckErrorFn]) -> (usize, Option<usize>) {
|
||||
fn reduce_errs(errs: &Vec<Option<Error>>, ignored_errs: &Vec<Box<dyn CheckErrorFn>>) -> (usize, Option<usize>) {
|
||||
let mut error_counts: HashMap<String, usize> = HashMap::new();
|
||||
let mut error_map: HashMap<String, usize> = HashMap::new(); // 存err位置
|
||||
let nil = "nil".to_string();
|
||||
@@ -69,7 +81,7 @@ fn reduce_errs(errs: &Vec<Option<Error>>, ignored_errs: &[CheckErrorFn]) -> (usi
|
||||
}
|
||||
|
||||
// 根据quorum验证错误数量
|
||||
fn reduce_quorum_errs(errs: &Vec<Option<Error>>, ignored_errs: &[CheckErrorFn], quorum: usize) -> Option<usize> {
|
||||
fn reduce_quorum_errs(errs: &Vec<Option<Error>>, ignored_errs: &Vec<Box<dyn CheckErrorFn>>, quorum: usize) -> Option<usize> {
|
||||
let (max_count, max_err) = reduce_errs(errs, ignored_errs);
|
||||
if max_count >= quorum {
|
||||
max_err
|
||||
@@ -81,7 +93,7 @@ fn reduce_quorum_errs(errs: &Vec<Option<Error>>, ignored_errs: &[CheckErrorFn],
|
||||
// 根据读quorum验证错误数量
|
||||
pub fn reduce_read_quorum_errs(
|
||||
errs: &mut Vec<Option<Error>>,
|
||||
ignored_errs: &[CheckErrorFn],
|
||||
ignored_errs: &Vec<Box<dyn CheckErrorFn>>,
|
||||
read_quorum: usize,
|
||||
) -> Result<usize, Error> {
|
||||
let idx = reduce_quorum_errs(errs, ignored_errs, read_quorum);
|
||||
@@ -95,7 +107,7 @@ pub fn reduce_read_quorum_errs(
|
||||
// 根据写quorum验证错误数量
|
||||
pub fn reduce_write_quorum_errs(
|
||||
errs: &Vec<Option<Error>>,
|
||||
ignored_errs: &[CheckErrorFn],
|
||||
ignored_errs: &Vec<Box<dyn CheckErrorFn>>,
|
||||
write_quorum: usize,
|
||||
) -> Result<usize, Error> {
|
||||
let idx = reduce_quorum_errs(errs, ignored_errs, write_quorum);
|
||||
|
||||
Reference in New Issue
Block a user