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 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 ({}) > f_bfree space ({}), fs corruption at ({}). please run 'fsck'", bavail, bfree, p.as_ref().display() ))); } }; let total = match blocks.checked_sub(reserved) { Some(total) => total * bsize, None => { return Err(Error::other(format!( "detected reserved space ({}) > blocks space ({}), fs corruption at ({}). please run 'fsck'", reserved, blocks, p.as_ref().display() ))); } }; let free = bavail * bsize; let used = match total.checked_sub(free) { Some(used) => used, None => { return Err(Error::other(format!( "detected free space ({}) > total drive space ({}), fs corruption at ({}). please run 'fsck'", free, total, p.as_ref().display() ))); } }; 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()) }