mirror of
https://github.com/rustfs/rustfs.git
synced 2026-08-13 00:26:53 +00:00
merge main
This commit is contained in:
@@ -17,7 +17,7 @@ pub enum EndpointType {
|
||||
/// any type of endpoint.
|
||||
#[derive(Debug, PartialEq, Eq, Clone, Hash)]
|
||||
pub struct Endpoint {
|
||||
pub url: url::Url,
|
||||
pub url: Url,
|
||||
pub is_local: bool,
|
||||
|
||||
pub pool_idx: i32,
|
||||
@@ -179,8 +179,8 @@ impl Endpoint {
|
||||
}
|
||||
}
|
||||
|
||||
/// parse a file path into an URL.
|
||||
fn url_parse_from_file_path(value: &str) -> Result<url::Url> {
|
||||
/// parse a file path into a URL.
|
||||
fn url_parse_from_file_path(value: &str) -> Result<Url> {
|
||||
// Only check if the arg is an ip address and ask for scheme since its absent.
|
||||
// localhost, example.com, any FQDN cannot be disambiguated from a regular file path such as
|
||||
// /mnt/export1. So we go ahead and start the rustfs server in FS modes in these cases.
|
||||
@@ -202,7 +202,6 @@ fn url_parse_from_file_path(value: &str) -> Result<url::Url> {
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
@@ -215,10 +214,10 @@ mod test {
|
||||
expected_err: Option<Error>,
|
||||
}
|
||||
|
||||
let u2 = url::Url::parse("https://example.org/path").unwrap();
|
||||
let u4 = url::Url::parse("http://192.168.253.200/path").unwrap();
|
||||
let u6 = url::Url::parse("http://server:/path").unwrap();
|
||||
let root_slash_foo = url::Url::from_file_path("/foo").unwrap();
|
||||
let u2 = Url::parse("https://example.org/path").unwrap();
|
||||
let u4 = Url::parse("http://192.168.253.200/path").unwrap();
|
||||
let u6 = Url::parse("http://server:/path").unwrap();
|
||||
let root_slash_foo = Url::from_file_path("/foo").unwrap();
|
||||
|
||||
let test_cases = [
|
||||
TestCase {
|
||||
|
||||
@@ -301,8 +301,8 @@ pub fn clone_disk_err(e: &DiskError) -> Error {
|
||||
|
||||
pub fn os_err_to_file_err(e: io::Error) -> Error {
|
||||
match e.kind() {
|
||||
io::ErrorKind::NotFound => Error::new(DiskError::FileNotFound),
|
||||
io::ErrorKind::PermissionDenied => Error::new(DiskError::FileAccessDenied),
|
||||
ErrorKind::NotFound => Error::new(DiskError::FileNotFound),
|
||||
ErrorKind::PermissionDenied => Error::new(DiskError::FileAccessDenied),
|
||||
// io::ErrorKind::ConnectionRefused => todo!(),
|
||||
// io::ErrorKind::ConnectionReset => todo!(),
|
||||
// io::ErrorKind::HostUnreachable => todo!(),
|
||||
@@ -350,7 +350,7 @@ pub fn os_err_to_file_err(e: io::Error) -> Error {
|
||||
pub struct FileAccessDeniedWithContext {
|
||||
pub path: PathBuf,
|
||||
#[source]
|
||||
pub source: std::io::Error,
|
||||
pub source: io::Error,
|
||||
}
|
||||
|
||||
impl std::fmt::Display for FileAccessDeniedWithContext {
|
||||
|
||||
@@ -40,7 +40,7 @@ pub struct FormatErasureV3 {
|
||||
pub this: Uuid,
|
||||
|
||||
/// Sets field carries the input disk order generated the first
|
||||
/// time when fresh disks were supplied, it is a two dimensional
|
||||
/// time when fresh disks were supplied, it is a two-dimensional
|
||||
/// array second dimension represents list of disks used per set.
|
||||
pub sets: Vec<Vec<Uuid>>,
|
||||
|
||||
|
||||
+69
-80
@@ -43,7 +43,7 @@ use crate::utils::fs::{
|
||||
};
|
||||
use crate::utils::os::get_info;
|
||||
use crate::utils::path::{
|
||||
self, clean, decode_dir_object, encode_dir_object, has_suffix, path_join, path_join_buf, GLOBAL_DIR_SUFFIX,
|
||||
clean, decode_dir_object, encode_dir_object, has_suffix, path_join, path_join_buf, GLOBAL_DIR_SUFFIX,
|
||||
GLOBAL_DIR_SUFFIX_WITH_SLASH, SLASH_SEPARATOR,
|
||||
};
|
||||
use crate::{
|
||||
@@ -69,7 +69,7 @@ use tokio::fs::{self, File};
|
||||
use tokio::io::{AsyncReadExt, AsyncSeekExt, AsyncWrite, AsyncWriteExt, ErrorKind};
|
||||
use tokio::sync::mpsc::Sender;
|
||||
use tokio::sync::RwLock;
|
||||
use tracing::{error, info, warn};
|
||||
use tracing::{debug, error, info, warn};
|
||||
use uuid::Uuid;
|
||||
|
||||
#[derive(Debug)]
|
||||
@@ -127,7 +127,7 @@ impl LocalDisk {
|
||||
// TODO: 删除 tmp 数据
|
||||
}
|
||||
|
||||
let format_path = Path::new(super::RUSTFS_META_BUCKET)
|
||||
let format_path = Path::new(RUSTFS_META_BUCKET)
|
||||
.join(Path::new(super::FORMAT_CONFIG_FILE))
|
||||
.absolutize_virtually(&root)?
|
||||
.into_owned();
|
||||
@@ -192,7 +192,7 @@ impl LocalDisk {
|
||||
|
||||
let cache = Cache::new(update_fn, Duration::from_secs(1), Opts::default());
|
||||
|
||||
// TODO: DIRECT suport
|
||||
// TODO: DIRECT support
|
||||
// TODD: DiskInfo
|
||||
let mut disk = Self {
|
||||
root: root.clone(),
|
||||
@@ -272,10 +272,10 @@ impl LocalDisk {
|
||||
Ok(md)
|
||||
}
|
||||
async fn make_meta_volumes(&self) -> Result<()> {
|
||||
let buckets = format!("{}/{}", super::RUSTFS_META_BUCKET, super::BUCKET_META_PREFIX);
|
||||
let multipart = format!("{}/{}", super::RUSTFS_META_BUCKET, "multipart");
|
||||
let config = format!("{}/{}", super::RUSTFS_META_BUCKET, "config");
|
||||
let tmp = format!("{}/{}", super::RUSTFS_META_BUCKET, "tmp");
|
||||
let buckets = format!("{}/{}", RUSTFS_META_BUCKET, BUCKET_META_PREFIX);
|
||||
let multipart = format!("{}/{}", RUSTFS_META_BUCKET, "multipart");
|
||||
let config = format!("{}/{}", RUSTFS_META_BUCKET, "config");
|
||||
let tmp = format!("{}/{}", RUSTFS_META_BUCKET, "tmp");
|
||||
let defaults = vec![buckets.as_str(), multipart.as_str(), config.as_str(), tmp.as_str()];
|
||||
|
||||
self.make_volumes(defaults).await
|
||||
@@ -341,7 +341,7 @@ impl LocalDisk {
|
||||
rename(&delete_path, &trash_path).await.map_err(Error::new).err()
|
||||
};
|
||||
|
||||
if immediate_purge || delete_path.to_string_lossy().ends_with(path::SLASH_SEPARATOR) {
|
||||
if immediate_purge || delete_path.to_string_lossy().ends_with(SLASH_SEPARATOR) {
|
||||
warn!("move_to_trash immediate_purge {:?}", &delete_path.to_string_lossy());
|
||||
let trash_path2 = self.get_object_path(super::RUSTFS_META_TMP_DELETED_BUCKET, Uuid::new_v4().to_string().as_str())?;
|
||||
let _ = rename_all(
|
||||
@@ -443,7 +443,7 @@ impl LocalDisk {
|
||||
return Err(Error::new(DiskError::FileNotFound));
|
||||
}
|
||||
|
||||
let meta_path = file_path.as_ref().join(Path::new(super::STORAGE_FORMAT_FILE));
|
||||
let meta_path = file_path.as_ref().join(Path::new(STORAGE_FORMAT_FILE));
|
||||
|
||||
let res = {
|
||||
if read_data {
|
||||
@@ -530,12 +530,12 @@ impl LocalDisk {
|
||||
volume_dir: impl AsRef<Path>,
|
||||
file_path: impl AsRef<Path>,
|
||||
) -> Result<(Vec<u8>, Option<OffsetDateTime>)> {
|
||||
let mut f = match utils::fs::open_file(file_path.as_ref(), utils::fs::O_RDONLY).await {
|
||||
let mut f = match utils::fs::open_file(file_path.as_ref(), O_RDONLY).await {
|
||||
Ok(f) => f,
|
||||
Err(e) => {
|
||||
if os_is_not_exist(&e) {
|
||||
if !skip_access_checks(volume) {
|
||||
if let Err(er) = utils::fs::access(volume_dir.as_ref()).await {
|
||||
if let Err(er) = access(volume_dir.as_ref()).await {
|
||||
if os_is_not_exist(&er) {
|
||||
warn!("read_all_data_with_dmtime os err {:?}", &er);
|
||||
return Err(Error::new(DiskError::VolumeNotFound));
|
||||
@@ -553,7 +553,7 @@ impl LocalDisk {
|
||||
} else if is_sys_err_too_many_files(&e) {
|
||||
return Err(Error::new(DiskError::TooManyOpenFiles));
|
||||
} else if is_sys_err_invalid_arg(&e) {
|
||||
if let Ok(meta) = utils::fs::lstat(file_path.as_ref()).await {
|
||||
if let Ok(meta) = lstat(file_path.as_ref()).await {
|
||||
if meta.is_dir() {
|
||||
return Err(Error::new(DiskError::FileNotFound));
|
||||
}
|
||||
@@ -587,7 +587,7 @@ impl LocalDisk {
|
||||
|
||||
async fn delete_versions_internal(&self, volume: &str, path: &str, fis: &Vec<FileInfo>) -> Result<()> {
|
||||
let volume_dir = self.get_bucket_path(volume)?;
|
||||
let xlpath = self.get_object_path(volume, format!("{}/{}", path, super::STORAGE_FORMAT_FILE).as_str())?;
|
||||
let xlpath = self.get_object_path(volume, format!("{}/{}", path, STORAGE_FORMAT_FILE).as_str())?;
|
||||
|
||||
let data = match self.read_all_data_with_dmtime(volume, volume_dir.as_path(), &xlpath).await {
|
||||
Ok((data, _)) => data,
|
||||
@@ -627,7 +627,7 @@ impl LocalDisk {
|
||||
};
|
||||
|
||||
if let Some(dir) = data_dir {
|
||||
let vid = fi.version_id.unwrap_or(Uuid::nil());
|
||||
let vid = fi.version_id.unwrap_or_default();
|
||||
let _ = fm.data.remove(vec![vid, dir]);
|
||||
|
||||
let dir_path = self.get_object_path(volume, format!("{}/{}", path, dir).as_str())?;
|
||||
@@ -650,14 +650,8 @@ impl LocalDisk {
|
||||
|
||||
let volume_dir = self.get_bucket_path(volume)?;
|
||||
|
||||
self.write_all_private(
|
||||
volume,
|
||||
format!("{}/{}", path, super::STORAGE_FORMAT_FILE).as_str(),
|
||||
&buf,
|
||||
true,
|
||||
volume_dir,
|
||||
)
|
||||
.await?;
|
||||
self.write_all_private(volume, format!("{}/{}", path, STORAGE_FORMAT_FILE).as_str(), &buf, true, volume_dir)
|
||||
.await?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
@@ -672,12 +666,12 @@ impl LocalDisk {
|
||||
|
||||
self.write_all_internal(&tmp_file_path, buf, sync, tmp_volume_dir).await?;
|
||||
|
||||
os::rename_all(tmp_file_path, file_path, volume_dir).await
|
||||
rename_all(tmp_file_path, file_path, volume_dir).await
|
||||
}
|
||||
|
||||
// write_all_public for trail
|
||||
async fn write_all_public(&self, volume: &str, path: &str, data: Vec<u8>) -> Result<()> {
|
||||
if volume == super::RUSTFS_META_BUCKET && path == super::FORMAT_CONFIG_FILE {
|
||||
if volume == RUSTFS_META_BUCKET && path == super::FORMAT_CONFIG_FILE {
|
||||
let mut format_info = self.format_info.write().await;
|
||||
format_info.data.clone_from(&data);
|
||||
}
|
||||
@@ -713,7 +707,7 @@ impl LocalDisk {
|
||||
sync: bool,
|
||||
skip_parent: impl AsRef<Path>,
|
||||
) -> Result<()> {
|
||||
let flags = utils::fs::O_CREATE | utils::fs::O_WRONLY | utils::fs::O_TRUNC;
|
||||
let flags = O_CREATE | O_WRONLY | utils::fs::O_TRUNC;
|
||||
|
||||
let mut f = {
|
||||
if sync {
|
||||
@@ -924,7 +918,7 @@ impl LocalDisk {
|
||||
continue;
|
||||
}
|
||||
|
||||
let name = path::path_join_buf(&[current, entry]);
|
||||
let name = path_join_buf(&[current, entry]);
|
||||
|
||||
if !dir_stack.is_empty() {
|
||||
if let Some(pop) = dir_stack.pop() {
|
||||
@@ -1068,7 +1062,7 @@ fn skip_access_checks(p: impl AsRef<str>) -> bool {
|
||||
super::RUSTFS_META_TMP_DELETED_BUCKET,
|
||||
super::RUSTFS_META_TMP_BUCKET,
|
||||
super::RUSTFS_META_MULTIPART_BUCKET,
|
||||
super::RUSTFS_META_BUCKET,
|
||||
RUSTFS_META_BUCKET,
|
||||
];
|
||||
|
||||
for v in vols.iter() {
|
||||
@@ -1203,7 +1197,7 @@ impl DiskAPI for LocalDisk {
|
||||
#[tracing::instrument(skip(self))]
|
||||
#[must_use]
|
||||
async fn read_all(&self, volume: &str, path: &str) -> Result<Vec<u8>> {
|
||||
if volume == super::RUSTFS_META_BUCKET && path == super::FORMAT_CONFIG_FILE {
|
||||
if volume == RUSTFS_META_BUCKET && path == super::FORMAT_CONFIG_FILE {
|
||||
let format_info = self.format_info.read().await;
|
||||
if !format_info.data.is_empty() {
|
||||
return Ok(format_info.data.clone());
|
||||
@@ -1225,7 +1219,7 @@ impl DiskAPI for LocalDisk {
|
||||
async fn delete(&self, volume: &str, path: &str, opt: DeleteOptions) -> Result<()> {
|
||||
let volume_dir = self.get_bucket_path(volume)?;
|
||||
if !skip_access_checks(volume) {
|
||||
if let Err(e) = utils::fs::access(&volume_dir).await {
|
||||
if let Err(e) = access(&volume_dir).await {
|
||||
return Err(convert_access_error(e, DiskError::VolumeAccessDenied));
|
||||
}
|
||||
}
|
||||
@@ -1243,7 +1237,7 @@ impl DiskAPI for LocalDisk {
|
||||
async fn verify_file(&self, volume: &str, path: &str, fi: &FileInfo) -> Result<CheckPartsResp> {
|
||||
let volume_dir = self.get_bucket_path(volume)?;
|
||||
if !skip_access_checks(volume) {
|
||||
if let Err(e) = utils::fs::access(&volume_dir).await {
|
||||
if let Err(e) = access(&volume_dir).await {
|
||||
return Err(convert_access_error(e, DiskError::VolumeAccessDenied));
|
||||
}
|
||||
}
|
||||
@@ -1259,7 +1253,7 @@ impl DiskAPI for LocalDisk {
|
||||
.join(path)
|
||||
.join(fi.data_dir.map_or("".to_string(), |dir| dir.to_string()))
|
||||
.join(format!("part.{}", part.number));
|
||||
let err = (self
|
||||
let err = self
|
||||
.bitrot_verify(
|
||||
&part_path,
|
||||
erasure.shard_file_size(part.size),
|
||||
@@ -1267,7 +1261,7 @@ impl DiskAPI for LocalDisk {
|
||||
&checksum_info.hash,
|
||||
erasure.shard_size(erasure.block_size),
|
||||
)
|
||||
.await)
|
||||
.await
|
||||
.err();
|
||||
resp.results[i] = conv_part_err_to_int(&err);
|
||||
if resp.results[i] == CHECK_PART_UNKNOWN {
|
||||
@@ -1384,7 +1378,7 @@ impl DiskAPI for LocalDisk {
|
||||
}
|
||||
}
|
||||
|
||||
if let Err(e) = utils::fs::remove_std(&dst_file_path) {
|
||||
if let Err(e) = remove_std(&dst_file_path) {
|
||||
if is_sys_err_not_empty(&e) || is_sys_err_not_dir(&e) {
|
||||
warn!("rename_part remove dst failed {:?} err {:?}", &dst_file_path, e);
|
||||
return Err(Error::new(DiskError::FileAccessDenied));
|
||||
@@ -1396,7 +1390,7 @@ impl DiskAPI for LocalDisk {
|
||||
}
|
||||
}
|
||||
|
||||
if let Err(err) = os::rename_all(&src_file_path, &dst_file_path, &dst_volume_dir).await {
|
||||
if let Err(err) = rename_all(&src_file_path, &dst_file_path, &dst_volume_dir).await {
|
||||
if let Some(e) = err.to_io_err() {
|
||||
if is_sys_err_not_empty(&e) || is_sys_err_not_dir(&e) {
|
||||
warn!("rename_part rename all failed {:?} err {:?}", &dst_file_path, e);
|
||||
@@ -1429,7 +1423,7 @@ impl DiskAPI for LocalDisk {
|
||||
let src_volume_dir = self.get_bucket_path(src_volume)?;
|
||||
let dst_volume_dir = self.get_bucket_path(dst_volume)?;
|
||||
if !skip_access_checks(src_volume) {
|
||||
if let Err(e) = utils::fs::access(&src_volume_dir).await {
|
||||
if let Err(e) = access(&src_volume_dir).await {
|
||||
if os_is_not_exist(&e) {
|
||||
return Err(Error::from(DiskError::VolumeNotFound));
|
||||
} else if is_sys_err_io(&e) {
|
||||
@@ -1440,7 +1434,7 @@ impl DiskAPI for LocalDisk {
|
||||
}
|
||||
}
|
||||
if !skip_access_checks(dst_volume) {
|
||||
if let Err(e) = utils::fs::access(&dst_volume_dir).await {
|
||||
if let Err(e) = access(&dst_volume_dir).await {
|
||||
if os_is_not_exist(&e) {
|
||||
return Err(Error::from(DiskError::VolumeNotFound));
|
||||
} else if is_sys_err_io(&e) {
|
||||
@@ -1484,7 +1478,7 @@ impl DiskAPI for LocalDisk {
|
||||
}
|
||||
}
|
||||
|
||||
if let Err(e) = utils::fs::remove(&dst_file_path).await {
|
||||
if let Err(e) = remove(&dst_file_path).await {
|
||||
if is_sys_err_not_empty(&e) || is_sys_err_not_dir(&e) {
|
||||
return Err(Error::new(DiskError::FileAccessDenied));
|
||||
} else if is_sys_err_io(&e) {
|
||||
@@ -1495,7 +1489,7 @@ impl DiskAPI for LocalDisk {
|
||||
}
|
||||
}
|
||||
|
||||
if let Err(err) = os::rename_all(&src_file_path, &dst_file_path, &dst_volume_dir).await {
|
||||
if let Err(err) = rename_all(&src_file_path, &dst_file_path, &dst_volume_dir).await {
|
||||
if let Some(e) = err.to_io_err() {
|
||||
if is_sys_err_not_empty(&e) || is_sys_err_not_dir(&e) {
|
||||
return Err(Error::new(DiskError::FileAccessDenied));
|
||||
@@ -1521,7 +1515,7 @@ impl DiskAPI for LocalDisk {
|
||||
if !origvolume.is_empty() {
|
||||
let origvolume_dir = self.get_bucket_path(origvolume)?;
|
||||
if !skip_access_checks(origvolume) {
|
||||
if let Err(e) = utils::fs::access(origvolume_dir).await {
|
||||
if let Err(e) = access(origvolume_dir).await {
|
||||
return Err(convert_access_error(e, DiskError::VolumeAccessDenied));
|
||||
}
|
||||
}
|
||||
@@ -1552,7 +1546,7 @@ impl DiskAPI for LocalDisk {
|
||||
|
||||
let volume_dir = self.get_bucket_path(volume)?;
|
||||
if !skip_access_checks(volume) {
|
||||
if let Err(e) = utils::fs::access(&volume_dir).await {
|
||||
if let Err(e) = access(&volume_dir).await {
|
||||
return Err(convert_access_error(e, DiskError::VolumeAccessDenied));
|
||||
}
|
||||
}
|
||||
@@ -1571,7 +1565,7 @@ impl DiskAPI for LocalDisk {
|
||||
// warn!("disk read_file: volume: {}, path: {}", volume, path);
|
||||
let volume_dir = self.get_bucket_path(volume)?;
|
||||
if !skip_access_checks(volume) {
|
||||
if let Err(e) = utils::fs::access(&volume_dir).await {
|
||||
if let Err(e) = access(&volume_dir).await {
|
||||
return Err(convert_access_error(e, DiskError::VolumeAccessDenied));
|
||||
}
|
||||
}
|
||||
@@ -1609,7 +1603,7 @@ impl DiskAPI for LocalDisk {
|
||||
|
||||
let volume_dir = self.get_bucket_path(volume)?;
|
||||
if !skip_access_checks(volume) {
|
||||
if let Err(e) = utils::fs::access(&volume_dir).await {
|
||||
if let Err(e) = access(&volume_dir).await {
|
||||
return Err(convert_access_error(e, DiskError::VolumeAccessDenied));
|
||||
}
|
||||
}
|
||||
@@ -1655,7 +1649,7 @@ impl DiskAPI for LocalDisk {
|
||||
if !origvolume.is_empty() {
|
||||
let origvolume_dir = self.get_bucket_path(origvolume)?;
|
||||
if !skip_access_checks(origvolume) {
|
||||
if let Err(e) = utils::fs::access(origvolume_dir).await {
|
||||
if let Err(e) = access(origvolume_dir).await {
|
||||
return Err(convert_access_error(e, DiskError::VolumeAccessDenied));
|
||||
}
|
||||
}
|
||||
@@ -1668,7 +1662,7 @@ impl DiskAPI for LocalDisk {
|
||||
Ok(res) => res,
|
||||
Err(e) => {
|
||||
if is_err_file_not_found(&e) && !skip_access_checks(volume) {
|
||||
if let Err(e) = utils::fs::access(&volume_dir).await {
|
||||
if let Err(e) = access(&volume_dir).await {
|
||||
return Err(convert_access_error(e, DiskError::VolumeAccessDenied));
|
||||
}
|
||||
}
|
||||
@@ -1750,8 +1744,8 @@ impl DiskAPI for LocalDisk {
|
||||
}
|
||||
|
||||
// xl.meta 路径
|
||||
let src_file_path = src_volume_dir.join(Path::new(format!("{}/{}", &src_path, super::STORAGE_FORMAT_FILE).as_str()));
|
||||
let dst_file_path = dst_volume_dir.join(Path::new(format!("{}/{}", &dst_path, super::STORAGE_FORMAT_FILE).as_str()));
|
||||
let src_file_path = src_volume_dir.join(Path::new(format!("{}/{}", &src_path, STORAGE_FORMAT_FILE).as_str()));
|
||||
let dst_file_path = dst_volume_dir.join(Path::new(format!("{}/{}", &dst_path, STORAGE_FORMAT_FILE).as_str()));
|
||||
|
||||
// data_dir 路径
|
||||
let has_data_dir_path = {
|
||||
@@ -1846,7 +1840,7 @@ impl DiskAPI for LocalDisk {
|
||||
|
||||
let new_dst_buf = xlmeta.marshal_msg()?;
|
||||
|
||||
self.write_all(src_volume, format!("{}/{}", &src_path, super::STORAGE_FORMAT_FILE).as_str(), new_dst_buf)
|
||||
self.write_all(src_volume, format!("{}/{}", &src_path, STORAGE_FORMAT_FILE).as_str(), new_dst_buf)
|
||||
.await
|
||||
.map_err(|err| {
|
||||
if let Some(e) = err.to_io_err() {
|
||||
@@ -1858,7 +1852,7 @@ impl DiskAPI for LocalDisk {
|
||||
if let Some((src_data_path, dst_data_path)) = has_data_dir_path.as_ref() {
|
||||
let no_inline = fi.data.is_none() && fi.size > 0;
|
||||
if no_inline {
|
||||
if let Err(err) = os::rename_all(&src_data_path, &dst_data_path, &skip_parent).await {
|
||||
if let Err(err) = rename_all(&src_data_path, &dst_data_path, &skip_parent).await {
|
||||
let _ = self.delete_file(&dst_volume_dir, dst_data_path, false, false).await;
|
||||
info!(
|
||||
"rename all failed src_data_path: {:?}, dst_data_path: {:?}, err: {:?}",
|
||||
@@ -1881,7 +1875,7 @@ impl DiskAPI for LocalDisk {
|
||||
if let Err(err) = self
|
||||
.write_all_private(
|
||||
dst_volume,
|
||||
format!("{}/{}/{}", &dst_path, &old_data_dir.to_string(), super::STORAGE_FORMAT_FILE).as_str(),
|
||||
format!("{}/{}/{}", &dst_path, &old_data_dir.to_string(), STORAGE_FORMAT_FILE).as_str(),
|
||||
&dst_buf,
|
||||
true,
|
||||
&skip_parent,
|
||||
@@ -1900,7 +1894,7 @@ impl DiskAPI for LocalDisk {
|
||||
}
|
||||
}
|
||||
|
||||
if let Err(err) = os::rename_all(&src_file_path, &dst_file_path, &skip_parent).await {
|
||||
if let Err(err) = rename_all(&src_file_path, &dst_file_path, &skip_parent).await {
|
||||
if let Some((_, dst_data_path)) = has_data_dir_path.as_ref() {
|
||||
let _ = self.delete_file(&dst_volume_dir, dst_data_path, false, false).await;
|
||||
}
|
||||
@@ -1916,7 +1910,7 @@ impl DiskAPI for LocalDisk {
|
||||
|
||||
if let Some(src_file_path_parent) = src_file_path.parent() {
|
||||
if src_volume != super::RUSTFS_META_MULTIPART_BUCKET {
|
||||
let _ = utils::fs::remove_std(src_file_path_parent);
|
||||
let _ = remove_std(src_file_path_parent);
|
||||
} else {
|
||||
let _ = self
|
||||
.delete_file(&dst_volume_dir, &src_file_path_parent.to_path_buf(), true, false)
|
||||
@@ -1951,7 +1945,7 @@ impl DiskAPI for LocalDisk {
|
||||
|
||||
let volume_dir = self.get_bucket_path(volume)?;
|
||||
|
||||
if let Err(e) = utils::fs::access(&volume_dir).await {
|
||||
if let Err(e) = access(&volume_dir).await {
|
||||
if os_is_not_exist(&e) {
|
||||
os::make_dir_all(&volume_dir, self.root.as_path()).await?;
|
||||
return Ok(());
|
||||
@@ -1981,7 +1975,7 @@ impl DiskAPI for LocalDisk {
|
||||
})?;
|
||||
|
||||
for entry in entries {
|
||||
if !utils::path::has_suffix(&entry, SLASH_SEPARATOR) || !Self::is_valid_volname(utils::path::clean(&entry).as_str()) {
|
||||
if !has_suffix(&entry, SLASH_SEPARATOR) || !Self::is_valid_volname(clean(&entry).as_str()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -1997,17 +1991,17 @@ impl DiskAPI for LocalDisk {
|
||||
#[tracing::instrument(skip(self))]
|
||||
async fn stat_volume(&self, volume: &str) -> Result<VolumeInfo> {
|
||||
let volume_dir = self.get_bucket_path(volume)?;
|
||||
let meta = match utils::fs::lstat(&volume_dir).await {
|
||||
let meta = match lstat(&volume_dir).await {
|
||||
Ok(res) => res,
|
||||
Err(e) => {
|
||||
if os_is_not_exist(&e) {
|
||||
return Err(Error::new(DiskError::VolumeNotFound));
|
||||
return if os_is_not_exist(&e) {
|
||||
Err(Error::new(DiskError::VolumeNotFound))
|
||||
} else if os_is_permission(&e) {
|
||||
return Err(Error::new(DiskError::DiskAccessDenied));
|
||||
Err(Error::new(DiskError::DiskAccessDenied))
|
||||
} else if is_sys_err_io(&e) {
|
||||
return Err(Error::new(DiskError::FaultyDisk));
|
||||
Err(Error::new(DiskError::FaultyDisk))
|
||||
} else {
|
||||
return Err(Error::new(e));
|
||||
Err(Error::new(e))
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -2027,7 +2021,7 @@ impl DiskAPI for LocalDisk {
|
||||
async fn delete_paths(&self, volume: &str, paths: &[String]) -> Result<()> {
|
||||
let volume_dir = self.get_bucket_path(volume)?;
|
||||
if !skip_access_checks(volume) {
|
||||
utils::fs::access(&volume_dir)
|
||||
access(&volume_dir)
|
||||
.await
|
||||
.map_err(|e| convert_access_error(e, DiskError::VolumeAccessDenied))?
|
||||
}
|
||||
@@ -2052,7 +2046,7 @@ impl DiskAPI for LocalDisk {
|
||||
check_path_length(file_path.to_string_lossy().as_ref())?;
|
||||
|
||||
let buf = self
|
||||
.read_all(volume, format!("{}/{}", &path, super::STORAGE_FORMAT_FILE).as_str())
|
||||
.read_all(volume, format!("{}/{}", &path, STORAGE_FORMAT_FILE).as_str())
|
||||
.await
|
||||
.map_err(|e| {
|
||||
if is_err_file_not_found(&e) && fi.version_id.is_some() {
|
||||
@@ -2073,12 +2067,7 @@ impl DiskAPI for LocalDisk {
|
||||
let wbuf = xl_meta.marshal_msg()?;
|
||||
|
||||
return self
|
||||
.write_all_meta(
|
||||
volume,
|
||||
format!("{}/{}", path, super::STORAGE_FORMAT_FILE).as_str(),
|
||||
&wbuf,
|
||||
!opts.no_persistence,
|
||||
)
|
||||
.write_all_meta(volume, format!("{}/{}", path, STORAGE_FORMAT_FILE).as_str(), &wbuf, !opts.no_persistence)
|
||||
.await;
|
||||
}
|
||||
|
||||
@@ -2087,7 +2076,7 @@ impl DiskAPI for LocalDisk {
|
||||
|
||||
#[tracing::instrument(skip(self))]
|
||||
async fn write_metadata(&self, _org_volume: &str, volume: &str, path: &str, fi: FileInfo) -> Result<()> {
|
||||
let p = self.get_object_path(volume, format!("{}/{}", path, super::STORAGE_FORMAT_FILE).as_str())?;
|
||||
let p = self.get_object_path(volume, format!("{}/{}", path, STORAGE_FORMAT_FILE).as_str())?;
|
||||
|
||||
let mut meta = FileMeta::new();
|
||||
if !fi.fresh {
|
||||
@@ -2103,10 +2092,10 @@ impl DiskAPI for LocalDisk {
|
||||
|
||||
let fm_data = meta.marshal_msg()?;
|
||||
|
||||
self.write_all(volume, format!("{}/{}", path, super::STORAGE_FORMAT_FILE).as_str(), fm_data)
|
||||
self.write_all(volume, format!("{}/{}", path, STORAGE_FORMAT_FILE).as_str(), fm_data)
|
||||
.await?;
|
||||
|
||||
return Ok(());
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[tracing::instrument(level = "debug", skip(self))]
|
||||
@@ -2182,11 +2171,11 @@ impl DiskAPI for LocalDisk {
|
||||
return self.write_metadata("", volume, path, fi).await;
|
||||
}
|
||||
|
||||
if fi.version_id.is_some() {
|
||||
return Err(Error::new(DiskError::FileVersionNotFound));
|
||||
return if fi.version_id.is_some() {
|
||||
Err(Error::new(DiskError::FileVersionNotFound))
|
||||
} else {
|
||||
return Err(Error::new(DiskError::FileNotFound));
|
||||
}
|
||||
Err(Error::new(DiskError::FileNotFound))
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
@@ -2194,7 +2183,7 @@ impl DiskAPI for LocalDisk {
|
||||
let old_dir = meta.delete_version(&fi)?;
|
||||
|
||||
if let Some(uuid) = old_dir {
|
||||
let vid = fi.version_id.unwrap_or(Uuid::nil());
|
||||
let vid = fi.version_id.unwrap_or_default();
|
||||
let _ = meta.data.remove(vec![vid, uuid])?;
|
||||
|
||||
let old_path = file_path.join(Path::new(uuid.to_string().as_str()));
|
||||
@@ -2357,7 +2346,7 @@ impl DiskAPI for LocalDisk {
|
||||
self.scanning.fetch_add(1, Ordering::SeqCst);
|
||||
defer!(|| { self.scanning.fetch_sub(1, Ordering::SeqCst) });
|
||||
|
||||
// must befor metadata_sys
|
||||
// must before metadata_sys
|
||||
let Some(store) = new_object_layer_fn() else { return Err(Error::msg("errServerNotInitialized")) };
|
||||
|
||||
let mut cache = cache.clone();
|
||||
@@ -2375,7 +2364,7 @@ impl DiskAPI for LocalDisk {
|
||||
}
|
||||
}
|
||||
|
||||
let vcfg = (BucketVersioningSys::get(&cache.info.name).await).ok();
|
||||
let vcfg = BucketVersioningSys::get(&cache.info.name).await.ok();
|
||||
|
||||
let loc = self.get_disk_location();
|
||||
let disks = store.get_disks(loc.pool_idx.unwrap(), loc.disk_idx.unwrap()).await?;
|
||||
@@ -2489,7 +2478,7 @@ impl DiskAPI for LocalDisk {
|
||||
)
|
||||
.await?;
|
||||
data_usage_info.info.last_update = Some(SystemTime::now());
|
||||
info!("ns_scanner completed: {data_usage_info:?}");
|
||||
debug!("ns_scanner completed: {data_usage_info:?}");
|
||||
Ok(data_usage_info)
|
||||
}
|
||||
|
||||
@@ -2546,7 +2535,7 @@ mod test {
|
||||
super::super::RUSTFS_META_TMP_DELETED_BUCKET,
|
||||
super::super::RUSTFS_META_TMP_BUCKET,
|
||||
super::super::RUSTFS_META_MULTIPART_BUCKET,
|
||||
super::super::RUSTFS_META_BUCKET,
|
||||
RUSTFS_META_BUCKET,
|
||||
];
|
||||
|
||||
let paths: Vec<_> = vols.iter().map(|v| Path::new(v).join("test")).collect();
|
||||
|
||||
+191
-191
@@ -57,6 +57,14 @@ impl DiskAPI for Disk {
|
||||
}
|
||||
}
|
||||
|
||||
#[tracing::instrument(skip(self))]
|
||||
async fn is_online(&self) -> bool {
|
||||
match self {
|
||||
Disk::Local(local_disk) => local_disk.is_online().await,
|
||||
Disk::Remote(remote_disk) => remote_disk.is_online().await,
|
||||
}
|
||||
}
|
||||
|
||||
#[tracing::instrument(skip(self))]
|
||||
fn is_local(&self) -> bool {
|
||||
match self {
|
||||
@@ -73,14 +81,6 @@ impl DiskAPI for Disk {
|
||||
}
|
||||
}
|
||||
|
||||
#[tracing::instrument(skip(self))]
|
||||
async fn is_online(&self) -> bool {
|
||||
match self {
|
||||
Disk::Local(local_disk) => local_disk.is_online().await,
|
||||
Disk::Remote(remote_disk) => remote_disk.is_online().await,
|
||||
}
|
||||
}
|
||||
|
||||
#[tracing::instrument(skip(self))]
|
||||
fn endpoint(&self) -> Endpoint {
|
||||
match self {
|
||||
@@ -97,22 +97,6 @@ impl DiskAPI for Disk {
|
||||
}
|
||||
}
|
||||
|
||||
#[tracing::instrument(skip(self))]
|
||||
fn path(&self) -> PathBuf {
|
||||
match self {
|
||||
Disk::Local(local_disk) => local_disk.path(),
|
||||
Disk::Remote(remote_disk) => remote_disk.path(),
|
||||
}
|
||||
}
|
||||
|
||||
#[tracing::instrument(skip(self))]
|
||||
fn get_disk_location(&self) -> DiskLocation {
|
||||
match self {
|
||||
Disk::Local(local_disk) => local_disk.get_disk_location(),
|
||||
Disk::Remote(remote_disk) => remote_disk.get_disk_location(),
|
||||
}
|
||||
}
|
||||
|
||||
#[tracing::instrument(skip(self))]
|
||||
async fn get_disk_id(&self) -> Result<Option<Uuid>> {
|
||||
match self {
|
||||
@@ -130,133 +114,18 @@ impl DiskAPI for Disk {
|
||||
}
|
||||
|
||||
#[tracing::instrument(skip(self))]
|
||||
async fn read_all(&self, volume: &str, path: &str) -> Result<Vec<u8>> {
|
||||
fn path(&self) -> PathBuf {
|
||||
match self {
|
||||
Disk::Local(local_disk) => local_disk.read_all(volume, path).await,
|
||||
Disk::Remote(remote_disk) => remote_disk.read_all(volume, path).await,
|
||||
Disk::Local(local_disk) => local_disk.path(),
|
||||
Disk::Remote(remote_disk) => remote_disk.path(),
|
||||
}
|
||||
}
|
||||
|
||||
#[tracing::instrument(skip(self))]
|
||||
async fn write_all(&self, volume: &str, path: &str, data: Vec<u8>) -> Result<()> {
|
||||
fn get_disk_location(&self) -> DiskLocation {
|
||||
match self {
|
||||
Disk::Local(local_disk) => local_disk.write_all(volume, path, data).await,
|
||||
Disk::Remote(remote_disk) => remote_disk.write_all(volume, path, data).await,
|
||||
}
|
||||
}
|
||||
|
||||
#[tracing::instrument(skip(self))]
|
||||
async fn delete(&self, volume: &str, path: &str, opt: DeleteOptions) -> Result<()> {
|
||||
match self {
|
||||
Disk::Local(local_disk) => local_disk.delete(volume, path, opt).await,
|
||||
Disk::Remote(remote_disk) => remote_disk.delete(volume, path, opt).await,
|
||||
}
|
||||
}
|
||||
|
||||
#[tracing::instrument(skip(self))]
|
||||
async fn verify_file(&self, volume: &str, path: &str, fi: &FileInfo) -> Result<CheckPartsResp> {
|
||||
match self {
|
||||
Disk::Local(local_disk) => local_disk.verify_file(volume, path, fi).await,
|
||||
Disk::Remote(remote_disk) => remote_disk.verify_file(volume, path, fi).await,
|
||||
}
|
||||
}
|
||||
|
||||
#[tracing::instrument(skip(self))]
|
||||
async fn check_parts(&self, volume: &str, path: &str, fi: &FileInfo) -> Result<CheckPartsResp> {
|
||||
match self {
|
||||
Disk::Local(local_disk) => local_disk.check_parts(volume, path, fi).await,
|
||||
Disk::Remote(remote_disk) => remote_disk.check_parts(volume, path, fi).await,
|
||||
}
|
||||
}
|
||||
|
||||
#[tracing::instrument(skip(self))]
|
||||
async fn rename_part(&self, src_volume: &str, src_path: &str, dst_volume: &str, dst_path: &str, meta: Vec<u8>) -> Result<()> {
|
||||
match self {
|
||||
Disk::Local(local_disk) => local_disk.rename_part(src_volume, src_path, dst_volume, dst_path, meta).await,
|
||||
Disk::Remote(remote_disk) => {
|
||||
remote_disk
|
||||
.rename_part(src_volume, src_path, dst_volume, dst_path, meta)
|
||||
.await
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[tracing::instrument(skip(self))]
|
||||
async fn rename_file(&self, src_volume: &str, src_path: &str, dst_volume: &str, dst_path: &str) -> Result<()> {
|
||||
match self {
|
||||
Disk::Local(local_disk) => local_disk.rename_file(src_volume, src_path, dst_volume, dst_path).await,
|
||||
Disk::Remote(remote_disk) => remote_disk.rename_file(src_volume, src_path, dst_volume, dst_path).await,
|
||||
}
|
||||
}
|
||||
|
||||
#[tracing::instrument(skip(self))]
|
||||
async fn create_file(&self, _origvolume: &str, volume: &str, path: &str, _file_size: usize) -> Result<FileWriter> {
|
||||
match self {
|
||||
Disk::Local(local_disk) => local_disk.create_file(_origvolume, volume, path, _file_size).await,
|
||||
Disk::Remote(remote_disk) => remote_disk.create_file(_origvolume, volume, path, _file_size).await,
|
||||
}
|
||||
}
|
||||
|
||||
#[tracing::instrument(skip(self))]
|
||||
async fn append_file(&self, volume: &str, path: &str) -> Result<FileWriter> {
|
||||
match self {
|
||||
Disk::Local(local_disk) => local_disk.append_file(volume, path).await,
|
||||
Disk::Remote(remote_disk) => remote_disk.append_file(volume, path).await,
|
||||
}
|
||||
}
|
||||
|
||||
#[tracing::instrument(skip(self))]
|
||||
async fn read_file(&self, volume: &str, path: &str) -> Result<FileReader> {
|
||||
match self {
|
||||
Disk::Local(local_disk) => local_disk.read_file(volume, path).await,
|
||||
Disk::Remote(remote_disk) => remote_disk.read_file(volume, path).await,
|
||||
}
|
||||
}
|
||||
|
||||
#[tracing::instrument(skip(self))]
|
||||
async fn read_file_stream(&self, volume: &str, path: &str, offset: usize, length: usize) -> Result<FileReader> {
|
||||
match self {
|
||||
Disk::Local(local_disk) => local_disk.read_file_stream(volume, path, offset, length).await,
|
||||
Disk::Remote(remote_disk) => remote_disk.read_file_stream(volume, path, offset, length).await,
|
||||
}
|
||||
}
|
||||
|
||||
#[tracing::instrument(skip(self))]
|
||||
async fn list_dir(&self, _origvolume: &str, volume: &str, _dir_path: &str, _count: i32) -> Result<Vec<String>> {
|
||||
match self {
|
||||
Disk::Local(local_disk) => local_disk.list_dir(_origvolume, volume, _dir_path, _count).await,
|
||||
Disk::Remote(remote_disk) => remote_disk.list_dir(_origvolume, volume, _dir_path, _count).await,
|
||||
}
|
||||
}
|
||||
|
||||
#[tracing::instrument(skip(self, wr))]
|
||||
async fn walk_dir<W: AsyncWrite + Unpin + Send>(&self, opts: WalkDirOptions, wr: &mut W) -> Result<()> {
|
||||
match self {
|
||||
Disk::Local(local_disk) => local_disk.walk_dir(opts, wr).await,
|
||||
Disk::Remote(remote_disk) => remote_disk.walk_dir(opts, wr).await,
|
||||
}
|
||||
}
|
||||
|
||||
#[tracing::instrument(skip(self))]
|
||||
async fn rename_data(
|
||||
&self,
|
||||
src_volume: &str,
|
||||
src_path: &str,
|
||||
fi: FileInfo,
|
||||
dst_volume: &str,
|
||||
dst_path: &str,
|
||||
) -> Result<RenameDataResp> {
|
||||
match self {
|
||||
Disk::Local(local_disk) => local_disk.rename_data(src_volume, src_path, fi, dst_volume, dst_path).await,
|
||||
Disk::Remote(remote_disk) => remote_disk.rename_data(src_volume, src_path, fi, dst_volume, dst_path).await,
|
||||
}
|
||||
}
|
||||
|
||||
#[tracing::instrument(skip(self))]
|
||||
async fn make_volumes(&self, volumes: Vec<&str>) -> Result<()> {
|
||||
match self {
|
||||
Disk::Local(local_disk) => local_disk.make_volumes(volumes).await,
|
||||
Disk::Remote(remote_disk) => remote_disk.make_volumes(volumes).await,
|
||||
Disk::Local(local_disk) => local_disk.get_disk_location(),
|
||||
Disk::Remote(remote_disk) => remote_disk.get_disk_location(),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -268,6 +137,14 @@ impl DiskAPI for Disk {
|
||||
}
|
||||
}
|
||||
|
||||
#[tracing::instrument(skip(self))]
|
||||
async fn make_volumes(&self, volumes: Vec<&str>) -> Result<()> {
|
||||
match self {
|
||||
Disk::Local(local_disk) => local_disk.make_volumes(volumes).await,
|
||||
Disk::Remote(remote_disk) => remote_disk.make_volumes(volumes).await,
|
||||
}
|
||||
}
|
||||
|
||||
#[tracing::instrument(skip(self))]
|
||||
async fn list_volumes(&self) -> Result<Vec<VolumeInfo>> {
|
||||
match self {
|
||||
@@ -285,49 +162,18 @@ impl DiskAPI for Disk {
|
||||
}
|
||||
|
||||
#[tracing::instrument(skip(self))]
|
||||
async fn delete_paths(&self, volume: &str, paths: &[String]) -> Result<()> {
|
||||
async fn delete_volume(&self, volume: &str) -> Result<()> {
|
||||
match self {
|
||||
Disk::Local(local_disk) => local_disk.delete_paths(volume, paths).await,
|
||||
Disk::Remote(remote_disk) => remote_disk.delete_paths(volume, paths).await,
|
||||
Disk::Local(local_disk) => local_disk.delete_volume(volume).await,
|
||||
Disk::Remote(remote_disk) => remote_disk.delete_volume(volume).await,
|
||||
}
|
||||
}
|
||||
|
||||
#[tracing::instrument(skip(self))]
|
||||
async fn update_metadata(&self, volume: &str, path: &str, fi: FileInfo, opts: &UpdateMetadataOpts) -> Result<()> {
|
||||
#[tracing::instrument(skip(self, wr))]
|
||||
async fn walk_dir<W: AsyncWrite + Unpin + Send>(&self, opts: WalkDirOptions, wr: &mut W) -> Result<()> {
|
||||
match self {
|
||||
Disk::Local(local_disk) => local_disk.update_metadata(volume, path, fi, opts).await,
|
||||
Disk::Remote(remote_disk) => remote_disk.update_metadata(volume, path, fi, opts).await,
|
||||
}
|
||||
}
|
||||
|
||||
#[tracing::instrument(skip(self))]
|
||||
async fn write_metadata(&self, _org_volume: &str, volume: &str, path: &str, fi: FileInfo) -> Result<()> {
|
||||
match self {
|
||||
Disk::Local(local_disk) => local_disk.write_metadata(_org_volume, volume, path, fi).await,
|
||||
Disk::Remote(remote_disk) => remote_disk.write_metadata(_org_volume, volume, path, fi).await,
|
||||
}
|
||||
}
|
||||
|
||||
#[tracing::instrument(level = "debug", skip(self))]
|
||||
async fn read_version(
|
||||
&self,
|
||||
_org_volume: &str,
|
||||
volume: &str,
|
||||
path: &str,
|
||||
version_id: &str,
|
||||
opts: &ReadOptions,
|
||||
) -> Result<FileInfo> {
|
||||
match self {
|
||||
Disk::Local(local_disk) => local_disk.read_version(_org_volume, volume, path, version_id, opts).await,
|
||||
Disk::Remote(remote_disk) => remote_disk.read_version(_org_volume, volume, path, version_id, opts).await,
|
||||
}
|
||||
}
|
||||
|
||||
#[tracing::instrument(skip(self))]
|
||||
async fn read_xl(&self, volume: &str, path: &str, read_data: bool) -> Result<RawFileInfo> {
|
||||
match self {
|
||||
Disk::Local(local_disk) => local_disk.read_xl(volume, path, read_data).await,
|
||||
Disk::Remote(remote_disk) => remote_disk.read_xl(volume, path, read_data).await,
|
||||
Disk::Local(local_disk) => local_disk.walk_dir(opts, wr).await,
|
||||
Disk::Remote(remote_disk) => remote_disk.walk_dir(opts, wr).await,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -359,6 +205,152 @@ impl DiskAPI for Disk {
|
||||
}
|
||||
}
|
||||
|
||||
#[tracing::instrument(skip(self))]
|
||||
async fn delete_paths(&self, volume: &str, paths: &[String]) -> Result<()> {
|
||||
match self {
|
||||
Disk::Local(local_disk) => local_disk.delete_paths(volume, paths).await,
|
||||
Disk::Remote(remote_disk) => remote_disk.delete_paths(volume, paths).await,
|
||||
}
|
||||
}
|
||||
|
||||
#[tracing::instrument(skip(self))]
|
||||
async fn write_metadata(&self, _org_volume: &str, volume: &str, path: &str, fi: FileInfo) -> Result<()> {
|
||||
match self {
|
||||
Disk::Local(local_disk) => local_disk.write_metadata(_org_volume, volume, path, fi).await,
|
||||
Disk::Remote(remote_disk) => remote_disk.write_metadata(_org_volume, volume, path, fi).await,
|
||||
}
|
||||
}
|
||||
|
||||
#[tracing::instrument(skip(self))]
|
||||
async fn update_metadata(&self, volume: &str, path: &str, fi: FileInfo, opts: &UpdateMetadataOpts) -> Result<()> {
|
||||
match self {
|
||||
Disk::Local(local_disk) => local_disk.update_metadata(volume, path, fi, opts).await,
|
||||
Disk::Remote(remote_disk) => remote_disk.update_metadata(volume, path, fi, opts).await,
|
||||
}
|
||||
}
|
||||
|
||||
#[tracing::instrument(level = "debug", skip(self))]
|
||||
async fn read_version(
|
||||
&self,
|
||||
_org_volume: &str,
|
||||
volume: &str,
|
||||
path: &str,
|
||||
version_id: &str,
|
||||
opts: &ReadOptions,
|
||||
) -> Result<FileInfo> {
|
||||
match self {
|
||||
Disk::Local(local_disk) => local_disk.read_version(_org_volume, volume, path, version_id, opts).await,
|
||||
Disk::Remote(remote_disk) => remote_disk.read_version(_org_volume, volume, path, version_id, opts).await,
|
||||
}
|
||||
}
|
||||
|
||||
#[tracing::instrument(skip(self))]
|
||||
async fn read_xl(&self, volume: &str, path: &str, read_data: bool) -> Result<RawFileInfo> {
|
||||
match self {
|
||||
Disk::Local(local_disk) => local_disk.read_xl(volume, path, read_data).await,
|
||||
Disk::Remote(remote_disk) => remote_disk.read_xl(volume, path, read_data).await,
|
||||
}
|
||||
}
|
||||
|
||||
#[tracing::instrument(skip(self, fi))]
|
||||
async fn rename_data(
|
||||
&self,
|
||||
src_volume: &str,
|
||||
src_path: &str,
|
||||
fi: FileInfo,
|
||||
dst_volume: &str,
|
||||
dst_path: &str,
|
||||
) -> Result<RenameDataResp> {
|
||||
match self {
|
||||
Disk::Local(local_disk) => local_disk.rename_data(src_volume, src_path, fi, dst_volume, dst_path).await,
|
||||
Disk::Remote(remote_disk) => remote_disk.rename_data(src_volume, src_path, fi, dst_volume, dst_path).await,
|
||||
}
|
||||
}
|
||||
|
||||
#[tracing::instrument(skip(self))]
|
||||
async fn list_dir(&self, _origvolume: &str, volume: &str, _dir_path: &str, _count: i32) -> Result<Vec<String>> {
|
||||
match self {
|
||||
Disk::Local(local_disk) => local_disk.list_dir(_origvolume, volume, _dir_path, _count).await,
|
||||
Disk::Remote(remote_disk) => remote_disk.list_dir(_origvolume, volume, _dir_path, _count).await,
|
||||
}
|
||||
}
|
||||
|
||||
#[tracing::instrument(skip(self))]
|
||||
async fn read_file(&self, volume: &str, path: &str) -> Result<FileReader> {
|
||||
match self {
|
||||
Disk::Local(local_disk) => local_disk.read_file(volume, path).await,
|
||||
Disk::Remote(remote_disk) => remote_disk.read_file(volume, path).await,
|
||||
}
|
||||
}
|
||||
|
||||
#[tracing::instrument(skip(self))]
|
||||
async fn read_file_stream(&self, volume: &str, path: &str, offset: usize, length: usize) -> Result<FileReader> {
|
||||
match self {
|
||||
Disk::Local(local_disk) => local_disk.read_file_stream(volume, path, offset, length).await,
|
||||
Disk::Remote(remote_disk) => remote_disk.read_file_stream(volume, path, offset, length).await,
|
||||
}
|
||||
}
|
||||
|
||||
#[tracing::instrument(skip(self))]
|
||||
async fn append_file(&self, volume: &str, path: &str) -> Result<FileWriter> {
|
||||
match self {
|
||||
Disk::Local(local_disk) => local_disk.append_file(volume, path).await,
|
||||
Disk::Remote(remote_disk) => remote_disk.append_file(volume, path).await,
|
||||
}
|
||||
}
|
||||
|
||||
#[tracing::instrument(skip(self))]
|
||||
async fn create_file(&self, _origvolume: &str, volume: &str, path: &str, _file_size: usize) -> Result<FileWriter> {
|
||||
match self {
|
||||
Disk::Local(local_disk) => local_disk.create_file(_origvolume, volume, path, _file_size).await,
|
||||
Disk::Remote(remote_disk) => remote_disk.create_file(_origvolume, volume, path, _file_size).await,
|
||||
}
|
||||
}
|
||||
|
||||
#[tracing::instrument(skip(self))]
|
||||
async fn rename_file(&self, src_volume: &str, src_path: &str, dst_volume: &str, dst_path: &str) -> Result<()> {
|
||||
match self {
|
||||
Disk::Local(local_disk) => local_disk.rename_file(src_volume, src_path, dst_volume, dst_path).await,
|
||||
Disk::Remote(remote_disk) => remote_disk.rename_file(src_volume, src_path, dst_volume, dst_path).await,
|
||||
}
|
||||
}
|
||||
|
||||
#[tracing::instrument(skip(self))]
|
||||
async fn rename_part(&self, src_volume: &str, src_path: &str, dst_volume: &str, dst_path: &str, meta: Vec<u8>) -> Result<()> {
|
||||
match self {
|
||||
Disk::Local(local_disk) => local_disk.rename_part(src_volume, src_path, dst_volume, dst_path, meta).await,
|
||||
Disk::Remote(remote_disk) => {
|
||||
remote_disk
|
||||
.rename_part(src_volume, src_path, dst_volume, dst_path, meta)
|
||||
.await
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[tracing::instrument(skip(self))]
|
||||
async fn delete(&self, volume: &str, path: &str, opt: DeleteOptions) -> Result<()> {
|
||||
match self {
|
||||
Disk::Local(local_disk) => local_disk.delete(volume, path, opt).await,
|
||||
Disk::Remote(remote_disk) => remote_disk.delete(volume, path, opt).await,
|
||||
}
|
||||
}
|
||||
|
||||
#[tracing::instrument(skip(self))]
|
||||
async fn verify_file(&self, volume: &str, path: &str, fi: &FileInfo) -> Result<CheckPartsResp> {
|
||||
match self {
|
||||
Disk::Local(local_disk) => local_disk.verify_file(volume, path, fi).await,
|
||||
Disk::Remote(remote_disk) => remote_disk.verify_file(volume, path, fi).await,
|
||||
}
|
||||
}
|
||||
|
||||
#[tracing::instrument(skip(self))]
|
||||
async fn check_parts(&self, volume: &str, path: &str, fi: &FileInfo) -> Result<CheckPartsResp> {
|
||||
match self {
|
||||
Disk::Local(local_disk) => local_disk.check_parts(volume, path, fi).await,
|
||||
Disk::Remote(remote_disk) => remote_disk.check_parts(volume, path, fi).await,
|
||||
}
|
||||
}
|
||||
|
||||
#[tracing::instrument(skip(self))]
|
||||
async fn read_multiple(&self, req: ReadMultipleReq) -> Result<Vec<ReadMultipleResp>> {
|
||||
match self {
|
||||
@@ -368,10 +360,18 @@ impl DiskAPI for Disk {
|
||||
}
|
||||
|
||||
#[tracing::instrument(skip(self))]
|
||||
async fn delete_volume(&self, volume: &str) -> Result<()> {
|
||||
async fn write_all(&self, volume: &str, path: &str, data: Vec<u8>) -> Result<()> {
|
||||
match self {
|
||||
Disk::Local(local_disk) => local_disk.delete_volume(volume).await,
|
||||
Disk::Remote(remote_disk) => remote_disk.delete_volume(volume).await,
|
||||
Disk::Local(local_disk) => local_disk.write_all(volume, path, data).await,
|
||||
Disk::Remote(remote_disk) => remote_disk.write_all(volume, path, data).await,
|
||||
}
|
||||
}
|
||||
|
||||
#[tracing::instrument(skip(self))]
|
||||
async fn read_all(&self, volume: &str, path: &str) -> Result<Vec<u8>> {
|
||||
match self {
|
||||
Disk::Local(local_disk) => local_disk.read_all(volume, path).await,
|
||||
Disk::Remote(remote_disk) => remote_disk.read_all(volume, path).await,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -406,12 +406,12 @@ impl DiskAPI for Disk {
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn new_disk(ep: &endpoint::Endpoint, opt: &DiskOption) -> Result<DiskStore> {
|
||||
pub async fn new_disk(ep: &Endpoint, opt: &DiskOption) -> Result<DiskStore> {
|
||||
if ep.is_local {
|
||||
let s = local::LocalDisk::new(ep, opt.cleanup).await?;
|
||||
let s = LocalDisk::new(ep, opt.cleanup).await?;
|
||||
Ok(Arc::new(Disk::Local(Box::new(s))))
|
||||
} else {
|
||||
let remote_disk = remote::RemoteDisk::new(ep, opt).await?;
|
||||
let remote_disk = RemoteDisk::new(ep, opt).await?;
|
||||
Ok(Arc::new(Disk::Remote(Box::new(remote_disk))))
|
||||
}
|
||||
}
|
||||
@@ -601,7 +601,7 @@ impl FileInfoVersions {
|
||||
return None;
|
||||
}
|
||||
|
||||
let vid = Uuid::parse_str(v).unwrap_or(Uuid::nil());
|
||||
let vid = Uuid::parse_str(v).unwrap_or_default();
|
||||
|
||||
self.versions.iter().position(|v| v.version_id == Some(vid))
|
||||
}
|
||||
@@ -763,7 +763,7 @@ impl MetaCacheEntry {
|
||||
|
||||
let fi = fm.into_fileinfo(bucket, self.name.as_str(), "", false, false)?;
|
||||
|
||||
return Ok(fi);
|
||||
Ok(fi)
|
||||
}
|
||||
|
||||
pub fn file_info_versions(&self, bucket: &str) -> Result<FileInfoVersions> {
|
||||
|
||||
@@ -199,7 +199,7 @@ pub async fn os_mkdir_all(dir_path: impl AsRef<Path>, base_dir: impl AsRef<Path>
|
||||
}
|
||||
|
||||
if let Some(parent) = dir_path.as_ref().parent() {
|
||||
// 不支持递归,直接create_dir_all了
|
||||
// 不支持递归,直接 create_dir_all 了
|
||||
if let Err(e) = utils::fs::make_dir_all(&parent).await {
|
||||
if os_is_exist(&e) {
|
||||
return Ok(());
|
||||
|
||||
+580
-580
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user