Add enum AppendVecError (#31749)

#### Problem
AppendVec currently uses std::io::ErrorKind::Other for its own errors.

#### Summary of Changes
This PR introduces AppendVecError and has AppendVec use it.
This commit is contained in:
Yueh-Hsuan Chiang 2023-05-24 12:18:17 -07:00 committed by GitHub
parent 461342cdd4
commit 6752019a80
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 34 additions and 23 deletions

View File

@ -3,7 +3,7 @@ use {
account_storage::meta::{
StorableAccountsWithHashesAndWriteVersions, StoredAccountInfo, StoredAccountMeta,
},
append_vec::{AppendVec, MatchAccountOwnerError},
append_vec::{AppendVec, AppendVecError, MatchAccountOwnerError},
storable_accounts::StorableAccounts,
tiered_storage::error::TieredStorageError,
},
@ -32,6 +32,9 @@ pub enum AccountsFileError {
#[error("I/O error: {0}")]
Io(#[from] std::io::Error),
#[error("AppendVecError: {0}")]
AppendVecError(#[from] AppendVecError),
#[error("TieredStorageError: {0}")]
TieredStorageError(#[from] TieredStorageError),
}

View File

@ -53,6 +53,22 @@ pub fn aligned_stored_size(data_len: usize) -> usize {
pub const MAXIMUM_APPEND_VEC_FILE_SIZE: u64 = 16 * 1024 * 1024 * 1024; // 16 GiB
#[derive(Error, Debug)]
/// An enum for AppendVec related errors.
pub enum AppendVecError {
#[error("too small file size {0} for AppendVec")]
FileSizeTooSmall(usize),
#[error("too large file size {0} for AppendVec")]
FileSizeTooLarge(usize),
#[error("incorrect layout/length/data in the appendvec at path {}", .0.display())]
IncorrectLayout(PathBuf),
#[error("offset ({0}) is larger than file size ({1})")]
OffsetOutOfBounds(usize, usize),
}
pub struct AppendVecAccountsIter<'append_vec> {
append_vec: &'append_vec AppendVec,
offset: usize,
@ -297,23 +313,20 @@ impl AppendVec {
fn sanitize_len_and_size(current_len: usize, file_size: usize) -> Result<()> {
if file_size == 0 {
Err(AccountsFileError::Io(std::io::Error::new(
std::io::ErrorKind::Other,
format!("too small file size {file_size} for AppendVec"),
)))
Err(AccountsFileError::AppendVecError(
AppendVecError::FileSizeTooSmall(file_size),
))
} else if usize::try_from(MAXIMUM_APPEND_VEC_FILE_SIZE)
.map(|max| file_size > max)
.unwrap_or(true)
{
Err(AccountsFileError::Io(std::io::Error::new(
std::io::ErrorKind::Other,
format!("too large file size {file_size} for AppendVec"),
)))
Err(AccountsFileError::AppendVecError(
AppendVecError::FileSizeTooLarge(file_size),
))
} else if current_len > file_size {
Err(AccountsFileError::Io(std::io::Error::new(
std::io::ErrorKind::Other,
format!("current_len is larger than file size ({file_size})"),
)))
Err(AccountsFileError::AppendVecError(
AppendVecError::OffsetOutOfBounds(current_len, file_size),
))
} else {
Ok(())
}
@ -359,14 +372,9 @@ impl AppendVec {
if !sanitized {
// This info show the failing accountvec file path. It helps debugging
// the appendvec data corrupution issues related to recycling.
let err_msg = format!(
"incorrect layout/length/data in the appendvec at path {}",
path.as_ref().display()
);
return Err(AccountsFileError::Io(std::io::Error::new(
std::io::ErrorKind::Other,
err_msg,
)));
return Err(AccountsFileError::AppendVecError(
AppendVecError::IncorrectLayout(path.as_ref().to_path_buf()),
));
}
Ok((new, num_accounts))
@ -919,7 +927,7 @@ pub mod tests {
}
#[test]
#[should_panic(expected = "too small file size 0 for AppendVec")]
#[should_panic(expected = "AppendVecError(FileSizeTooSmall(0))")]
fn test_append_vec_new_bad_size() {
let path = get_append_vec_path("test_append_vec_new_bad_size");
let _av = AppendVec::new(&path.path, true, 0);
@ -978,7 +986,7 @@ pub mod tests {
const LEN: usize = 1024 * 1024 + 1;
const SIZE: usize = 1024 * 1024;
let result = AppendVec::sanitize_len_and_size(LEN, SIZE);
assert_matches!(result, Err(ref message) if message.to_string().contains("current_len is larger than file size (1048576)"));
assert_matches!(result, Err(ref message) if message.to_string().contains("is larger than file size (1048576)"));
}
#[test]