1 use { 2 super::*, 3 std::{ffi::CString, mem, os::unix::ffi::OsStrExt, path::Path}, 4 }; 5 6 /// inode & blocs information given by statvfs 7 #[derive(Debug, Clone)] 8 pub struct Stats { 9 pub bsize: u64, 10 pub blocks: u64, 11 pub bavail: u64, 12 pub bfree: u64, 13 } 14 15 impl Stats { from(mount_point: &Path) -> Result<Option<Self>>16 pub fn from(mount_point: &Path) -> Result<Option<Self>> { 17 let c_mount_point = CString::new(mount_point.as_os_str().as_bytes()).unwrap(); 18 unsafe { 19 let mut statvfs = mem::MaybeUninit::<libc::statvfs>::uninit(); 20 let code = libc::statvfs(c_mount_point.as_ptr(), statvfs.as_mut_ptr()); 21 match code { 22 0 => { 23 // good 24 let statvfs = statvfs.assume_init(); 25 Ok(Some(Stats { 26 bsize: statvfs.f_bsize as u64, 27 blocks: statvfs.f_blocks as u64, 28 bavail: statvfs.f_bavail as u64, 29 bfree: statvfs.f_bfree as u64, 30 })) 31 } 32 -1 => { 33 // the filesystem wasn't found, it's a strange one, for example a 34 // docker one 35 Ok(None) 36 } 37 _ => { 38 // unexpected 39 Err(Error::UnexpectedStavfsReturn { 40 code, 41 path: mount_point.to_path_buf(), 42 }) 43 } 44 } 45 } 46 } size(&self) -> u6447 pub fn size(&self) -> u64 { 48 self.bsize * self.blocks 49 } available(&self) -> u6450 pub fn available(&self) -> u64 { 51 self.bsize * self.bavail 52 } used(&self) -> u6453 pub fn used(&self) -> u64 { 54 self.size() - self.available() 55 } use_share(&self) -> f6456 pub fn use_share(&self) -> f64 { 57 if self.size() == 0 { 58 0.0 59 } else { 60 self.used() as f64 / (self.size() as f64) 61 } 62 } 63 } 64