add all StorageErr

This commit is contained in:
weisd
2024-09-23 11:46:48 +08:00
parent 2935945585
commit f1004a1324
3 changed files with 111 additions and 26 deletions
+88 -15
View File
@@ -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)
}
}
+1 -1
View File
@@ -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
View File
@@ -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);