mirror of
https://github.com/rustfs/rustfs.git
synced 2026-08-11 07:36:53 +00:00
@@ -1,10 +1,12 @@
|
||||
use super::error::{is_sys_err_io, is_sys_err_not_empty, is_sys_err_too_many_files, os_is_not_exist, os_is_permission};
|
||||
use super::os::is_root_disk;
|
||||
use super::{endpoint::Endpoint, error::DiskError, format::FormatV3};
|
||||
use super::{
|
||||
os, DeleteOptions, DiskAPI, DiskInfo, DiskInfoOptions, DiskLocation, DiskMetrics, FileInfoVersions, FileReader, FileWriter,
|
||||
MetaCacheEntry, ReadMultipleReq, ReadMultipleResp, ReadOptions, RenameDataResp, UpdateMetadataOpts, VolumeInfo,
|
||||
WalkDirOptions,
|
||||
Info, MetaCacheEntry, ReadMultipleReq, ReadMultipleResp, ReadOptions, RenameDataResp, UpdateMetadataOpts, VolumeInfo,
|
||||
WalkDirOptions, BUCKET_META_PREFIX, RUSTFS_META_BUCKET,
|
||||
};
|
||||
use crate::cache_value::cache::Cache;
|
||||
use crate::disk::error::{
|
||||
convert_access_error, is_sys_err_handle_invalid, is_sys_err_invalid_arg, is_sys_err_is_dir, is_sys_err_not_dir,
|
||||
map_err_not_exists, os_err_to_file_err,
|
||||
@@ -12,14 +14,19 @@ use crate::disk::error::{
|
||||
use crate::disk::os::check_path_length;
|
||||
use crate::disk::{LocalFileReader, LocalFileWriter, STORAGE_FORMAT_FILE};
|
||||
use crate::error::{Error, Result};
|
||||
use crate::utils::fs::{lstat, O_APPEND, O_CREATE, O_RDONLY, O_WRONLY};
|
||||
use crate::global::{GLOBAL_IsErasureSD, GLOBAL_RootDiskThreshold};
|
||||
use crate::heal::heal_commands::HealingTracker;
|
||||
use crate::heal::heal_ops::HEALING_TRACKER_FILENAME;
|
||||
use crate::utils::fs::{lstat, read_file, O_APPEND, O_CREATE, O_RDONLY, O_WRONLY};
|
||||
use crate::utils::path::{clean, has_suffix, SLASH_SEPARATOR};
|
||||
use crate::utils::stat_linux::get_info;
|
||||
use crate::{
|
||||
file_meta::FileMeta,
|
||||
store_api::{FileInfo, RawFileInfo},
|
||||
utils,
|
||||
};
|
||||
use path_absolutize::Absolutize;
|
||||
use std::fmt::Debug;
|
||||
use std::{
|
||||
fs::Metadata,
|
||||
path::{Path, PathBuf},
|
||||
@@ -49,18 +56,29 @@ impl FormatInfo {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct LocalDisk {
|
||||
pub root: PathBuf,
|
||||
pub format_path: PathBuf,
|
||||
pub format_info: RwLock<FormatInfo>,
|
||||
pub endpoint: Endpoint,
|
||||
disk_info_cache: Cache<DiskInfo>,
|
||||
// pub id: Mutex<Option<Uuid>>,
|
||||
// pub format_data: Mutex<Vec<u8>>,
|
||||
// pub format_file_info: Mutex<Option<Metadata>>,
|
||||
// pub format_last_check: Mutex<Option<OffsetDateTime>>,
|
||||
}
|
||||
|
||||
impl Debug for LocalDisk {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
f.debug_struct("LocalDisk")
|
||||
.field("root", &self.root)
|
||||
.field("format_path", &self.format_path)
|
||||
.field("format_info", &self.format_info)
|
||||
.field("endpoint", &self.endpoint)
|
||||
.finish()
|
||||
}
|
||||
}
|
||||
|
||||
impl LocalDisk {
|
||||
pub async fn new(ep: &Endpoint, cleanup: bool) -> Result<Self> {
|
||||
let root = fs::canonicalize(ep.url.path()).await?;
|
||||
@@ -101,6 +119,33 @@ impl LocalDisk {
|
||||
last_check: format_last_check,
|
||||
};
|
||||
|
||||
let derive_path = root.to_string_lossy().to_string();
|
||||
let disk_id = id.map_or("".to_string(), |id| id.to_string());
|
||||
let update_fn = || async move {
|
||||
if let Ok((info, root)) = get_disk_info(&derive_path).await {
|
||||
let mut disk_info = DiskInfo {
|
||||
total: info.total,
|
||||
free: info.free,
|
||||
used: info.used,
|
||||
used_inodes: info.files - info.ffree,
|
||||
free_inodes: info.ffree,
|
||||
major: info.major,
|
||||
minor: info.minor,
|
||||
fs_type: info.fstype,
|
||||
root_disk: root,
|
||||
id: disk_id,
|
||||
..Default::default()
|
||||
};
|
||||
if root {
|
||||
return Err(Error::new(DiskError::DriveIsRoot));
|
||||
}
|
||||
|
||||
// disk_info.healing =
|
||||
} else {
|
||||
return Ok(DiskInfo::default());
|
||||
}
|
||||
};
|
||||
|
||||
// TODO: DIRECT suport
|
||||
// TODD: DiskInfo
|
||||
let disk = Self {
|
||||
@@ -1612,6 +1657,27 @@ impl DiskAPI for LocalDisk {
|
||||
}
|
||||
}
|
||||
|
||||
async fn get_disk_info(drive_path: &str) -> Result<(Info, bool)> {
|
||||
check_path_length(drive_path)?;
|
||||
|
||||
let disk_info = get_info(drive_path, false)?;
|
||||
let root_drive = if !*GLOBAL_IsErasureSD.read().await {
|
||||
let root_disk_threshold = *GLOBAL_RootDiskThreshold.read().await;
|
||||
if root_disk_threshold > 0 {
|
||||
disk_info.total <= root_disk_threshold
|
||||
} else {
|
||||
match is_root_disk(drive_path, SLASH_SEPARATOR) {
|
||||
Ok(result) => result,
|
||||
Err(_) => false,
|
||||
}
|
||||
}
|
||||
} else {
|
||||
false
|
||||
};
|
||||
|
||||
Ok((disk_info, root_drive))
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
|
||||
|
||||
+18
-6
@@ -14,10 +14,7 @@ pub const FORMAT_CONFIG_FILE: &str = "format.json";
|
||||
const STORAGE_FORMAT_FILE: &str = "xl.meta";
|
||||
|
||||
use crate::{
|
||||
erasure::{ReadAt, Write},
|
||||
error::{Error, Result},
|
||||
file_meta::FileMeta,
|
||||
store_api::{FileInfo, RawFileInfo},
|
||||
erasure::{ReadAt, Write}, error::{Error, Result}, file_meta::FileMeta, heal::heal_commands::HealingTracker, store_api::{FileInfo, RawFileInfo}
|
||||
};
|
||||
|
||||
use endpoint::Endpoint;
|
||||
@@ -167,8 +164,8 @@ pub struct DiskInfo {
|
||||
pub used: u64,
|
||||
pub used_inodes: u64,
|
||||
pub free_inodes: u64,
|
||||
pub major: u32,
|
||||
pub minor: u32,
|
||||
pub major: u64,
|
||||
pub minor: u64,
|
||||
pub nr_requests: u64,
|
||||
pub fs_type: String,
|
||||
pub root_disk: bool,
|
||||
@@ -192,6 +189,21 @@ pub struct DiskMetrics {
|
||||
total_deletes: u64,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Default)]
|
||||
pub struct Info {
|
||||
pub total: u64,
|
||||
pub free: u64,
|
||||
pub used: u64,
|
||||
pub files: u64,
|
||||
pub ffree: u64,
|
||||
pub fstype: String,
|
||||
pub major: u64,
|
||||
pub minor: u64,
|
||||
pub name: String,
|
||||
pub rotational: bool,
|
||||
pub nrrequests: u64,
|
||||
}
|
||||
|
||||
#[derive(Debug, Default, Clone, Serialize, Deserialize)]
|
||||
pub struct FileInfoVersions {
|
||||
// Name of the volume.
|
||||
|
||||
@@ -8,7 +8,7 @@ use tokio::fs;
|
||||
use crate::{
|
||||
disk::error::{is_sys_err_not_dir, is_sys_err_path_not_found, os_is_not_exist},
|
||||
error::{Error, Result},
|
||||
utils,
|
||||
utils::{self, stat_linux::same_disk},
|
||||
};
|
||||
|
||||
use super::error::{os_err_to_file_err, os_is_exist, DiskError};
|
||||
@@ -51,6 +51,14 @@ pub fn check_path_length(path_name: &str) -> Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn is_root_disk(disk_path: &str, root_disk: &str) -> Result<bool> {
|
||||
if cfg!(target_os = "windows") {
|
||||
return Ok(false);
|
||||
}
|
||||
|
||||
same_disk(disk_path, root_disk)
|
||||
}
|
||||
|
||||
pub async fn make_dir_all(path: impl AsRef<Path>, base_dir: impl AsRef<Path>) -> Result<()> {
|
||||
check_path_length(path.as_ref().to_string_lossy().to_string().as_str())?;
|
||||
|
||||
|
||||
@@ -20,9 +20,7 @@ use super::{
|
||||
RenameDataResp, UpdateMetadataOpts, VolumeInfo, WalkDirOptions,
|
||||
};
|
||||
use crate::{
|
||||
disk::error::DiskError,
|
||||
error::{Error, Result},
|
||||
store_api::{FileInfo, RawFileInfo},
|
||||
disk::error::DiskError, error::{Error, Result}, heal::heal_commands::HealingTracker, store_api::{FileInfo, RawFileInfo}
|
||||
};
|
||||
use protos::proto_gen::node_service::RenamePartRequst;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user