Skip to content

Commit

Permalink
freebsd impl
Browse files Browse the repository at this point in the history
  • Loading branch information
dlowe committed Nov 25, 2024
1 parent a400670 commit 621e11b
Show file tree
Hide file tree
Showing 2 changed files with 54 additions and 25 deletions.
78 changes: 53 additions & 25 deletions src/unix/freebsd/disk.rs
Original file line number Diff line number Diff line change
Expand Up @@ -75,8 +75,8 @@ impl DiskInner {
self.is_read_only
}

pub(crate) fn refresh_specifics(&mut self, _refreshes: DiskRefreshKind) -> bool {
refresh_disk(self)
pub(crate) fn refresh_specifics(&mut self, refresh_kind: DiskRefreshKind) -> bool {
refresh_disk(self, refresh_kind)
}

pub(crate) fn usage(&self) -> DiskUsage {
Expand All @@ -96,8 +96,8 @@ impl crate::DisksInner {
}
}

pub(crate) fn refresh_list_specifics(&mut self, _refreshes: DiskRefreshKind) {
unsafe { get_all_list(&mut self.disks, true) }
pub(crate) fn refresh_list_specifics(&mut self, refresh_kind: DiskRefreshKind) {
unsafe { get_all_list(&mut self.disks, true, refresh_kind) }
}

pub(crate) fn list(&self) -> &[Disk] {
Expand All @@ -108,8 +108,8 @@ impl crate::DisksInner {
&mut self.disks
}

pub(crate) fn refresh_specifics(&mut self, _refreshes: DiskRefreshKind) {
unsafe { get_all_list(&mut self.disks, false); }
pub(crate) fn refresh_specifics(&mut self, refresh_kind: DiskRefreshKind) {
unsafe { get_all_list(&mut self.disks, false, refresh_kind); }
}
}

Expand Down Expand Up @@ -166,19 +166,38 @@ impl GetValues for DiskInner {
}
}

fn refresh_disk(disk: &mut DiskInner) -> bool {
fn refresh_disk(disk: &mut DiskInner, refresh_kind: DiskRefreshKind) -> bool {
let (total_space, available_space) = if refresh_kind.details() {
unsafe {
let mut vfs: libc::statvfs = std::mem::zeroed();
if libc::statvfs(disk.c_mount_point.as_ptr() as *const _, &mut vfs as *mut _) < 0 {
return false;
}
let block_size: u64 = vfs.f_frsize as _;

disk.total_space = vfs.f_blocks.saturating_mul(block_size);
disk.available_space = vfs.f_favail.saturating_mul(block_size);
refresh_disk_io(&mut [disk]);
true
(
vfs.f_blocks.saturating_mul(block_size),
vfs.f_favail.saturating_mul(block_size),
)
}
} else {
Default::default()
};

disk.total_space = total_space;
disk.available_space = available_space;

if refresh_kind.io_usage() {
unsafe {
refresh_disk_io(&mut [disk]);
}
} else {
disk.update_old();
*disk.get_read() = Default::default();
*disk.get_written() = Default::default();
}

true
}

unsafe fn initialize_geom() -> Result<(), ()> {
Expand Down Expand Up @@ -281,7 +300,7 @@ fn get_disks_mapping() -> HashMap<String, String> {
disk_mapping
}

pub unsafe fn get_all_list(container: &mut Vec<Disk>, add_new_disks: bool) {
pub unsafe fn get_all_list(container: &mut Vec<Disk>, add_new_disks: bool, refresh_kind: DiskRefreshKind) {
let mut fs_infos: *mut libc::statfs = null_mut();

let count = libc::getmntinfo(&mut fs_infos, libc::MNT_WAIT);
Expand Down Expand Up @@ -339,15 +358,21 @@ pub unsafe fn get_all_list(container: &mut Vec<Disk>, add_new_disks: bool) {
OsString::from(mount_point)
};

if libc::statvfs(fs_info.f_mntonname.as_ptr(), &mut vfs) != 0 {
continue;
}

let f_frsize: u64 = vfs.f_frsize as _;

let is_read_only = (vfs.f_flag & libc::ST_RDONLY) != 0;
let total_space = vfs.f_blocks.saturating_mul(f_frsize);
let available_space = vfs.f_favail.saturating_mul(f_frsize);
let (is_read_only, total_space, available_space) = if refresh_kind.details() {
if libc::statvfs(fs_info.f_mntonname.as_ptr(), &mut vfs) != 0 {
Default::default()
} else {
let f_frsize: u64 = vfs.f_frsize as _;

(
((vfs.f_flag & libc::ST_RDONLY) != 0),
vfs.f_blocks.saturating_mul(f_frsize),
vfs.f_favail.saturating_mul(f_frsize),
)
}
} else {
Default::default()
};

if let Some(disk) = container.iter_mut().find(|d| d.inner.name == name) {
disk.inner.updated = true;
Expand All @@ -357,17 +382,20 @@ pub unsafe fn get_all_list(container: &mut Vec<Disk>, add_new_disks: bool) {
let dev_mount_point = c_buf_to_utf8_str(&fs_info.f_mntfromname).unwrap_or("");

// USB keys and CDs are removable.
let is_removable =
[b"USB", b"usb"].iter().any(|b| *b == &fs_type[..]) || fs_type.starts_with(b"/dev/cd");
let is_removable = if refresh_kind.details() {
[b"USB", b"usb"].iter().any(|b| *b == &fs_type[..]) || fs_type.starts_with(b"/dev/cd")
} else {
Default::default()
};

container.push(Disk {
inner: DiskInner {
name,
c_mount_point: fs_info.f_mntonname.to_vec(),
mount_point: PathBuf::from(mount_point),
dev_id: disk_mapping.get(dev_mount_point).map(ToString::to_string),
total_space: vfs.f_blocks.saturating_mul(f_frsize),
available_space: vfs.f_favail.saturating_mul(f_frsize),
total_space,
available_space,
file_system: OsString::from_vec(fs_type),
is_removable,
is_read_only,
Expand Down
1 change: 1 addition & 0 deletions tests/disk.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ fn test_disk_refresh_kind() {
let assertions = |disks: &Disks| {
for disk in disks.list().iter() {
if refreshes.kind() {
#[cfg(not(target_os = "freebsd"))]
assert_ne!(
disk.kind(),
DiskKind::Unknown(-1),
Expand Down

0 comments on commit 621e11b

Please sign in to comment.