// Copyright 2024 RustFS Team // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. use super::{DiskInfo, IOStats}; use nix::sys::{stat::stat, statfs::statfs}; use std::io::Error; use std::path::Path; /// Returns total and free bytes available in a directory, e.g. `/`. pub fn get_info(p: impl AsRef) -> std::io::Result { let path_display = p.as_ref().display(); let stat = statfs(p.as_ref())?; let bsize = stat.block_size() as u64; let bfree = stat.blocks_free(); let bavail = stat.blocks_available(); let blocks = stat.blocks(); let reserved = match bfree.checked_sub(bavail) { Some(reserved) => reserved, None => { return Err(Error::other(format!( "detected f_bavail space ({bavail}) > f_bfree space ({bfree}), fs corruption at ({path_display}). please run 'fsck'", ))); } }; let total = match blocks.checked_sub(reserved) { Some(total) => total * bsize, None => { return Err(Error::other(format!( "detected reserved space ({reserved}) > blocks space ({blocks}), fs corruption at ({path_display}). please run 'fsck'", ))); } }; let free = bavail * bsize; let used = match total.checked_sub(free) { Some(used) => used, None => { return Err(Error::other(format!( "detected free space ({free}) > total drive space ({total}), fs corruption at ({path_display}). please run 'fsck'" ))); } }; Ok(DiskInfo { total, free, used, files: stat.files(), ffree: stat.files_free(), fstype: stat.filesystem_type_name().to_string(), ..Default::default() }) } pub fn same_disk(disk1: &str, disk2: &str) -> std::io::Result { let stat1 = stat(disk1)?; let stat2 = stat(disk2)?; Ok(stat1.st_dev == stat2.st_dev) } pub fn get_drive_stats(_major: u32, _minor: u32) -> std::io::Result { Ok(IOStats::default()) }