Repository: GuillaumeGomez/sysinfo
Pull request #1404 (2024-11-29 22:29:46)

Improve disk list refresh and rename `DiskRefreshKind::details` into `DiskRefreshKind::storage`


Patch:
diff --git a/benches/basic.rs b/benches/basic.rs
index 2853b1b..6b050fc 100644
--- a/benches/basic.rs
+++ b/benches/basic.rs
@@ -86,7 +86,7 @@ fn bench_refresh_disks_list(b: &mut test::Bencher) {
     let mut disks = sysinfo::Disks::new_with_refreshed_list();
 
     b.iter(move || {
-        disks.refresh_list();
+        disks.refresh_list(false);
     });
 }
 
diff --git a/examples/simple.rs b/examples/simple.rs
index efd003f..cd10074 100644
--- a/examples/simple.rs
+++ b/examples/simple.rs
@@ -158,7 +158,7 @@ fn interpret_input(
         "help" => print_help(),
         "refresh_disks" => {
             writeln!(&mut io::stdout(), "Refreshing disk list...");
-            disks.refresh_list();
+            disks.refresh_list(true);
             writeln!(&mut io::stdout(), "Done.");
         }
         "refresh_users" => {
diff --git a/src/c_interface.rs b/src/c_interface.rs
index c1d007f..ecdee17 100644
--- a/src/c_interface.rs
+++ b/src/c_interface.rs
@@ -156,7 +156,7 @@ pub extern "C" fn sysinfo_disks_refresh_list(disks: CDisks) {
         let mut disks: Box<Disks> = Box::from_raw(disks as *mut Disks);
         {
             let disks: &mut Disks = disks.borrow_mut();
-            disks.refresh_list();
+            disks.refresh_list(true);
         }
         let _ = Box::into_raw(disks);
     }
diff --git a/src/common/disk.rs b/src/common/disk.rs
index 90d2f30..cf570e3 100644
--- a/src/common/disk.rs
+++ b/src/common/disk.rs
@@ -249,7 +249,7 @@ impl Disks {
     /// use sysinfo::Disks;
     ///
     /// let mut disks = Disks::new();
-    /// disks.refresh_list();
+    /// disks.refresh_list(false);
     /// for disk in disks.list() {
     ///     println!("{disk:?}");
     /// }
@@ -290,7 +290,7 @@ impl Disks {
     /// ```
     pub fn new_with_refreshed_list_specifics(refreshes: DiskRefreshKind) -> Self {
         let mut disks = Self::new();
-        disks.refresh_list_specifics(refreshes);
+        disks.refresh_list_specifics(false, refreshes);
         disks
     }
 
@@ -357,10 +357,10 @@ impl Disks {
     /// use sysinfo::Disks;
     ///
     /// let mut disks = Disks::new();
-    /// disks.refresh_list();
+    /// disks.refresh_list(true);
     /// ```
-    pub fn refresh_list(&mut self) {
-        self.refresh_list_specifics(DiskRefreshKind::everything());
+    pub fn refresh_list(&mut self, remove_not_listed_disks: bool) {
+        self.refresh_list_specifics(remove_not_listed_disks, DiskRefreshKind::everything());
     }
 
     /// The disk list will be emptied then completely recomputed according to the given
@@ -380,10 +380,15 @@ impl Disks {
     /// use sysinfo::{Disks, DiskRefreshKind};
     ///
     /// let mut disks = Disks::new();
-    /// disks.refresh_list_specifics(DiskRefreshKind::new());
+    /// disks.refresh_list_specifics(true, DiskRefreshKind::new());
     /// ```
-    pub fn refresh_list_specifics(&mut self, refreshes: DiskRefreshKind) {
-        self.inner.refresh_list_specifics(refreshes);
+    pub fn refresh_list_specifics(
+        &mut self,
+        remove_not_listed_disks: bool,
+        refreshes: DiskRefreshKind,
+    ) {
+        self.inner
+            .refresh_list_specifics(remove_not_listed_disks, refreshes);
     }
 }
 
@@ -435,19 +440,23 @@ impl fmt::Display for DiskKind {
 
 /// Used to determine what you want to refresh specifically on the [`Disk`] type.
 ///
+/// * `kind` is about refreshing the [`Disk::kind`] information.
+/// * `storage` is about refreshing the [`Disk::available_space`] and [`Disk::total_space`] information.
+/// * `io_usage` is about refreshing the [`Disk::usage`] information.
+///
 /// ```no_run
 /// use sysinfo::{Disks, DiskRefreshKind};
 ///
 /// let mut disks = Disks::new_with_refreshed_list_specifics(DiskRefreshKind::everything());
 ///
 /// for disk in disks.list() {
-///     assert_eq!(disk.total_space(), 0);
+///     assert!(disk.total_space() != 0);
 /// }
 /// ```
 #[derive(Clone, Copy, Debug, Default)]
 pub struct DiskRefreshKind {
     kind: bool,
-    details: bool,
+    storage: bool,
     io_usage: bool,
 }
 
@@ -460,7 +469,7 @@ impl DiskRefreshKind {
     /// let r = DiskRefreshKind::new();
     ///
     /// assert_eq!(r.kind(), false);
-    /// assert_eq!(r.details(), false);
+    /// assert_eq!(r.storage(), false);
     /// assert_eq!(r.io_usage(), false);
     /// ```
     pub fn new() -> Self {
@@ -475,18 +484,18 @@ impl DiskRefreshKind {
     /// let r = DiskRefreshKind::everything();
     ///
     /// assert_eq!(r.kind(), true);
-    /// assert_eq!(r.details(), true);
+    /// assert_eq!(r.storage(), true);
     /// assert_eq!(r.io_usage(), true);
     /// ```
     pub fn everything() -> Self {
         Self {
             kind: true,
-            details: true,
+            storage: true,
             io_usage: true,
         }
     }
 
     impl_get_set!(DiskRefreshKind, kind, with_kind, without_kind);
-    impl_get_set!(DiskRefreshKind, details, with_details, without_details,);
+    impl_get_set!(DiskRefreshKind, storage, with_storage, without_storage);
     impl_get_set!(DiskRefreshKind, io_usage, with_io_usage, without_io_usage);
 }
diff --git a/src/unix/apple/disk.rs b/src/unix/apple/disk.rs
index 712f9f0..812f363 100644
--- a/src/unix/apple/disk.rs
+++ b/src/unix/apple/disk.rs
@@ -37,6 +37,7 @@ pub(crate) struct DiskInner {
     pub(crate) old_read_bytes: u64,
     pub(crate) written_bytes: u64,
     pub(crate) read_bytes: u64,
+    updated: bool,
 }
 
 impl DiskInner {
@@ -73,46 +74,10 @@ impl DiskInner {
     }
 
     pub(crate) fn refresh_specifics(&mut self, refresh_kind: DiskRefreshKind) -> bool {
-        if refresh_kind.kind() && self.type_ == DiskKind::Unknown(-1) {
-            #[cfg(target_os = "macos")]
-            {
-                match self
-                    .bsd_name
-                    .as_ref()
-                    .and_then(|name| crate::sys::inner::disk::get_disk_type(name))
-                {
-                    Some(type_) => self.type_ = type_,
-                    None => {
-                        sysinfo_debug!("Failed to retrieve `DiskKind`");
-                    }
-                }
-            }
-            #[cfg(not(target_os = "macos"))]
-            {
-                self.type_ = DiskKind::SSD;
-            }
-        }
-
-        if refresh_kind.io_usage() {
-            #[cfg(target_os = "macos")]
-            match self
-                .bsd_name
-                .as_ref()
-                .and_then(|name| crate::sys::inner::disk::get_disk_io(name))
-            {
-                Some((read_bytes, written_bytes)) => {
-                    self.old_read_bytes = self.read_bytes;
-                    self.old_written_bytes = self.written_bytes;
-                    self.read_bytes = read_bytes;
-                    self.written_bytes = written_bytes;
-                }
-                None => {
-                    sysinfo_debug!("Failed to update disk i/o stats");
-                }
-            }
-        }
+        self.refresh_kind(refresh_kind);
+        self.refresh_io(refresh_kind);
 
-        if refresh_kind.details() {
+        if refresh_kind.storage() {
             unsafe {
                 if let Some(requested_properties) = build_requested_properties(&[
                     ffi::kCFURLVolumeTotalCapacityKey,
@@ -158,6 +123,52 @@ impl DiskInner {
             total_written_bytes: self.written_bytes,
         }
     }
+
+    fn refresh_kind(&mut self, refresh_kind: DiskRefreshKind) {
+        if refresh_kind.kind() && self.type_ == DiskKind::Unknown(-1) {
+            #[cfg(target_os = "macos")]
+            {
+                match self
+                    .bsd_name
+                    .as_ref()
+                    .and_then(|name| crate::sys::inner::disk::get_disk_type(name))
+                {
+                    Some(type_) => self.type_ = type_,
+                    None => {
+                        sysinfo_debug!("Failed to retrieve `DiskKind`");
+                    }
+                }
+            }
+            #[cfg(not(target_os = "macos"))]
+            {
+                self.type_ = DiskKind::SSD;
+            }
+        }
+    }
+
+    #[cfg(target_os = "macos")]
+    fn refresh_io(&mut self, refresh_kind: DiskRefreshKind) {
+        if refresh_kind.io_usage() {
+            match self
+                .bsd_name
+                .as_ref()
+                .and_then(|name| crate::sys::inner::disk::get_disk_io(name))
+            {
+                Some((read_bytes, written_bytes)) => {
+                    self.old_read_bytes = self.read_bytes;
+                    self.old_written_bytes = self.written_bytes;
+                    self.read_bytes = read_bytes;
+                    self.written_bytes = written_bytes;
+                }
+                None => {
+                    sysinfo_debug!("Failed to update disk i/o stats");
+                }
+            }
+        }
+    }
+
+    #[cfg(not(target_os = "macos"))]
+    fn refresh_io(&mut self, _refresh_kind: DiskRefreshKind) {}
 }
 
 impl crate::DisksInner {
@@ -167,12 +178,16 @@ impl crate::DisksInner {
         }
     }
 
-    pub(crate) fn refresh_list_specifics(&mut self, refresh_kind: DiskRefreshKind) {
+    pub(crate) fn refresh_list_specifics(
+        &mut self,
+        remove_not_listed_disks: bool,
+        refresh_kind: DiskRefreshKind,
+    ) {
         unsafe {
             // SAFETY: We don't keep any Objective-C objects around because we
             // don't make any direct Objective-C calls in this code.
             with_autorelease(|| {
-                get_list(&mut self.disks, refresh_kind);
+                get_list(&mut self.disks, remove_not_listed_disks, refresh_kind);
             })
         }
     }
@@ -192,9 +207,11 @@ impl crate::DisksInner {
     }
 }
 
-unsafe fn get_list(container: &mut Vec<Disk>, refresh_kind: DiskRefreshKind) {
-    container.clear();
-
+unsafe fn get_list(
+    container: &mut Vec<Disk>,
+    remove_not_listed_disks: bool,
+    refresh_kind: DiskRefreshKind,
+) {
     let raw_disks = {
         let count = libc::getfsstat(ptr::null_mut(), 0, libc::MNT_NOWAIT);
         if count < 1 {
@@ -213,18 +230,26 @@ unsafe fn get_list(container: &mut Vec<Disk>, refresh_kind: DiskRefreshKind) {
         disks
     };
 
+    // Currently we query maximum 9 properties.
+    let mut properties = Vec::with_capacity(9);
+    // "mandatory" information
+    properties.push(ffi::kCFURLVolumeNameKey);
+    properties.push(ffi::kCFURLVolumeIsBrowsableKey);
+    properties.push(ffi::kCFURLVolumeIsLocalKey);
+
+    // is_removable
+    properties.push(ffi::kCFURLVolumeIsEjectableKey);
+    properties.push(ffi::kCFURLVolumeIsRemovableKey);
+    properties.push(ffi::kCFURLVolumeIsInternalKey);
+
+    if refresh_kind.storage() {
+        properties.push(ffi::kCFURLVolumeTotalCapacityKey);
+        properties.push(ffi::kCFURLVolumeAvailableCapacityForImportantUsageKey);
+        properties.push(ffi::kCFURLVolumeAvailableCapacityKey);
+    }
+
     // Create a list of properties about the disk that we want to fetch.
-    let requested_properties = match build_requested_properties(&[
-        ffi::kCFURLVolumeIsEjectableKey,
-        ffi::kCFURLVolumeIsRemovableKey,
-        ffi::kCFURLVolumeIsInternalKey,
-        ffi::kCFURLVolumeTotalCapacityKey,
-        ffi::kCFURLVolumeAvailableCapacityForImportantUsageKey,
-        ffi::kCFURLVolumeAvailableCapacityKey,
-        ffi::kCFURLVolumeNameKey,
-        ffi::kCFURLVolumeIsBrowsableKey,
-        ffi::kCFURLVolumeIsLocalKey,
-    ]) {
+    let requested_properties = match build_requested_properties(&properties) {
         Some(properties) => properties,
         None => {
             sysinfo_debug!("failed to create volume key list");
@@ -290,10 +315,34 @@ unsafe fn get_list(container: &mut Vec<Disk>, refresh_kind: DiskRefreshKind) {
             CStr::from_ptr(c_disk.f_mntonname.as_ptr()).to_bytes(),
         ));
 
-        if let Some(disk) = new_disk(mount_point, volume_url, c_disk, &prop_dict, refresh_kind) {
+        let disk = container
+            .iter_mut()
+            .find(|d| d.inner.mount_point == mount_point);
+        if let Some(disk) = new_disk(
+            disk,
+            mount_point,
+            volume_url,
+            c_disk,
+            &prop_dict,
+            refresh_kind,
+        ) {
             container.push(disk);
         }
     }
+
+    if remove_not_listed_disks {
+        container.retain_mut(|disk| {
+            if !disk.inner.updated {
+                return false;
+            }
+            disk.inner.updated = false;
+            true
+        });
+    } else {
+        for c in container.iter_mut() {
+            c.inner.updated = false;
+        }
+    }
 }
 
 type RetainedCFArray = CFReleaser<core_foundation_sys::array::__CFArray>;
@@ -431,46 +480,37 @@ pub(super) unsafe fn get_int_value(dict: CFDictionaryRef, key: DictKey) -> Optio
 }
 
 unsafe fn new_disk(
+    disk: Option<&mut Disk>,
     mount_point: PathBuf,
     volume_url: RetainedCFURL,
     c_disk: libc::statfs,
     disk_props: &RetainedCFDictionary,
     refresh_kind: DiskRefreshKind,
 ) -> Option<Disk> {
-    let bsd_name = get_bsd_name(&c_disk);
-
-    // IOKit is not available on any but the most recent (16+) iOS and iPadOS versions.
-    // Due to this, we can't query the medium type and disk i/o stats. All iOS devices use flash-based storage
-    // so we just assume the disk type is an SSD and set disk i/o stats to 0 until Rust has a way to conditionally link to
-    // IOKit in more recent deployment versions.
-
-    let type_ = if refresh_kind.kind() {
-        #[cfg(target_os = "macos")]
-        {
-            bsd_name
-                .as_ref()
-                .and_then(|name| crate::sys::inner::disk::get_disk_type(name))
-                .unwrap_or(DiskKind::Unknown(-1))
-        }
-        #[cfg(not(target_os = "macos"))]
-        DiskKind::SSD
+    let (total_space, available_space) = if refresh_kind.storage() {
+        (
+            get_int_value(
+                disk_props.inner(),
+                DictKey::Extern(ffi::kCFURLVolumeTotalCapacityKey),
+            ),
+            get_available_volume_space(disk_props),
+        )
     } else {
-        DiskKind::Unknown(-1)
+        (None, None)
     };
 
-    let (read_bytes, written_bytes) = if refresh_kind.io_usage() {
-        #[cfg(target_os = "macos")]
-        {
-            bsd_name
-                .as_ref()
-                .and_then(|name| crate::sys::inner::disk::get_disk_io(name))
-                .unwrap_or_default()
+    if let Some(disk) = disk {
+        let disk = &mut disk.inner;
+        if let Some(total_space) = total_space {
+            disk.total_space = total_space;
         }
-        #[cfg(not(target_os = "macos"))]
-        (0, 0)
-    } else {
-        (0, 0)
-    };
+        if let Some(available_space) = available_space {
+            disk.available_space = available_space;
+        }
+        disk.refresh_io(refresh_kind);
+        disk.updated = true;
+        return None;
+    }
 
     // Note: Since we requested these properties from the system, we don't expect
     // these property retrievals to fail.
@@ -481,51 +521,6 @@ unsafe fn new_disk(
     )
     .map(OsString::from)?;
 
-    let is_removable = if refresh_kind.details() {
-        let ejectable = get_bool_value(
-            disk_props.inner(),
-            DictKey::Extern(ffi::kCFURLVolumeIsEjectableKey),
-        )
-        .unwrap_or_default();
-
-        let removable = get_bool_value(
-            disk_props.inner(),
-            DictKey::Extern(ffi::kCFURLVolumeIsRemovableKey),
-        )
-        .unwrap_or_default();
-
-        let is_removable = ejectable || removable;
-
-        if is_removable {
-            is_removable
-        } else {
-            // If neither `ejectable` or `removable` return `true`, fallback to checking
-            // if the disk is attached to the internal system.
-            let internal = get_bool_value(
-                disk_props.inner(),
-                DictKey::Extern(ffi::kCFURLVolumeIsInternalKey),
-            )
-            .unwrap_or_default();
-
-            !internal
-        }
-    } else {
-        false
-    };
-
-    let (total_space, available_space) = if refresh_kind.details() {
-        (
-            get_int_value(
-                disk_props.inner(),
-                DictKey::Extern(ffi::kCFURLVolumeTotalCapacityKey),
-            )
-            .unwrap_or(0),
-            get_available_volume_space(disk_props).unwrap_or(0),
-        )
-    } else {
-        (0, 0)
-    };
-
     let file_system = {
         let len = c_disk
             .f_fstypename
@@ -540,26 +535,63 @@ unsafe fn new_disk(
         )
     };
 
-    let is_read_only = refresh_kind.details() && (c_disk.f_flags & libc::MNT_RDONLY as u32) != 0;
+    let bsd_name = get_bsd_name(&c_disk);
 
-    Some(Disk {
-        inner: DiskInner {
-            type_,
-            name,
-            bsd_name,
-            file_system,
-            mount_point,
-            volume_url,
-            total_space,
-            available_space,
-            is_removable,
-            is_read_only,
-            read_bytes,
-            written_bytes,
-            old_read_bytes: 0,
-            old_written_bytes: 0,
-        },
-    })
+    // IOKit is not available on any but the most recent (16+) iOS and iPadOS versions.
+    // Due to this, we can't query the medium type and disk i/o stats. All iOS devices use flash-based storage
+    // so we just assume the disk type is an SSD and set disk i/o stats to 0 until Rust has a way to conditionally link to
+    // IOKit in more recent deployment versions.
+
+    let ejectable = get_bool_value(
+        disk_props.inner(),
+        DictKey::Extern(ffi::kCFURLVolumeIsEjectableKey),
+    )
+    .unwrap_or(false);
+
+    let removable = get_bool_value(
+        disk_props.inner(),
+        DictKey::Extern(ffi::kCFURLVolumeIsRemovableKey),
+    )
+    .unwrap_or(false);
+
+    let is_removable = if ejectable || removable {
+        true
+    } else {
+        // If neither `ejectable` or `removable` return `true`, fallback to checking
+        // if the disk is attached to the internal system.
+        let internal = get_bool_value(
+            disk_props.inner(),
+            DictKey::Extern(ffi::kCFURLVolumeIsInternalKey),
+        )
+        .unwrap_or_default();
+
+        !internal
+    };
+
+    let is_read_only = (c_disk.f_flags & libc::MNT_RDONLY as u32) != 0;
+
+    let mut disk = DiskInner {
+        type_: DiskKind::Unknown(-1),
+        name,
+        bsd_name,
+        file_system,
+        mount_point,
+        volume_url,
+        total_space: total_space.unwrap_or(0),
+        available_space: available_space.unwrap_or(0),
+        is_removable,
+        is_read_only,
+        read_bytes: 0,
+        written_bytes: 0,
+        old_read_bytes: 0,
+        old_written_bytes: 0,
+        updated: true,
+    };
+
+    disk.refresh_kind(refresh_kind);
+    disk.refresh_io(refresh_kind);
+
+    Some(Disk { inner: disk })
 }
 
 /// Calls the provided closure in the context of a new autorelease pool that is drained
@@ -599,7 +631,7 @@ fn get_bsd_name(disk: &libc::statfs) -> Option<Vec<u8>> {
     // Removes `/dev/` from the value.
     unsafe {
         CStr::from_ptr(disk.f_mntfromname.as_ptr())
-            .to_bytes()
+            .to_bytes_with_nul()
             .strip_prefix(b"/dev/")
             .map(|slice| slice.to_vec())
             .or_else(|| {
diff --git a/src/unix/freebsd/disk.rs b/src/unix/freebsd/disk.rs
index 6958b9b..0804344 100644
--- a/src/unix/freebsd/disk.rs
+++ b/src/unix/freebsd/disk.rs
@@ -38,6 +38,7 @@ pub(crate) struct DiskInner {
 
 impl DiskInner {
     pub(crate) fn kind(&self) -> DiskKind {
+        // Currently don't know how to retrieve this information on FreeBSD.
         DiskKind::Unknown(-1)
     }
 
@@ -90,8 +91,12 @@ impl crate::DisksInner {
         }
     }
 
-    pub(crate) fn refresh_list_specifics(&mut self, refresh_kind: DiskRefreshKind) {
-        unsafe { get_all_list(&mut self.disks, true, refresh_kind) }
+    pub(crate) fn refresh_list_specifics(
+        &mut self,
+        remove_not_listed_disks: bool,
+        refresh_kind: DiskRefreshKind,
+    ) {
+        unsafe { get_all_list(&mut self.disks, true, remove_not_listed_disks, refresh_kind) }
     }
 
     pub(crate) fn list(&self) -> &[Disk] {
@@ -104,7 +109,7 @@ impl crate::DisksInner {
 
     pub(crate) fn refresh_specifics(&mut self, refresh_kind: DiskRefreshKind) {
         unsafe {
-            get_all_list(&mut self.disks, false, refresh_kind);
+            get_all_list(&mut self.disks, false, false, refresh_kind);
         }
     }
 }
@@ -162,11 +167,11 @@ impl GetValues for DiskInner {
     }
 }
 
-/// Returns `(total_space, available_space)`.
+/// Returns `(total_space, available_space, is_read_only)`.
 unsafe fn get_statvfs(
     c_mount_point: &[libc::c_char],
     vfs: &mut libc::statvfs,
-) -> Option<(u64, u64)> {
+) -> Option<(u64, u64, bool)> {
     if libc::statvfs(c_mount_point.as_ptr() as *const _, vfs as *mut _) < 0 {
         sysinfo_debug!("statvfs failed");
         None
@@ -175,18 +180,21 @@ unsafe fn get_statvfs(
         Some((
             vfs.f_blocks.saturating_mul(block_size),
             vfs.f_favail.saturating_mul(block_size),
+            (vfs.f_flag & libc::ST_RDONLY) != 0,
         ))
     }
 }
 
 fn refresh_disk(disk: &mut DiskInner, refresh_kind: DiskRefreshKind) -> bool {
-    if refresh_kind.details() {
+    if refresh_kind.storage() {
         unsafe {
             let mut vfs: libc::statvfs = std::mem::zeroed();
-            if let Some((total_space, available_space)) = get_statvfs(&disk.c_mount_point, &mut vfs)
+            if let Some((total_space, available_space, is_read_only)) =
+                get_statvfs(&disk.c_mount_point, &mut vfs)
             {
                 disk.total_space = total_space;
                 disk.available_space = available_space;
+                disk.is_read_only = is_read_only;
             }
         }
     }
@@ -315,6 +323,7 @@ fn get_disks_mapping() -> HashMap<String, String> {
 pub unsafe fn get_all_list(
     container: &mut Vec<Disk>,
     add_new_disks: bool,
+    remove_not_listed_disks: bool,
     refresh_kind: DiskRefreshKind,
 ) {
     let mut fs_infos: *mut libc::statfs = null_mut();
@@ -326,7 +335,6 @@ pub unsafe fn get_all_list(
     }
     let disk_mapping = get_disks_mapping();
 
-    let mut vfs: libc::statvfs = std::mem::zeroed();
     let fs_infos: &[libc::statfs] = std::slice::from_raw_parts(fs_infos as _, count as _);
 
     for fs_info in fs_infos {
@@ -374,59 +382,44 @@ pub unsafe fn get_all_list(
             OsString::from(mount_point)
         };
 
-        let (is_read_only, total_space, available_space) = if refresh_kind.details() {
-            if let Some((total_space, available_space)) =
-                get_statvfs(&fs_info.f_mntonname, &mut vfs)
-            {
-                (
-                    ((vfs.f_flag & libc::ST_RDONLY) != 0),
-                    available_space,
-                    total_space,
-                )
-            } else {
-                (false, 0, 0)
-            }
-        } else {
-            (false, 0, 0)
-        };
-
         if let Some(disk) = container.iter_mut().find(|d| d.inner.name == name) {
+            // I/O usage is updated for all disks at once at the end.
+            refresh_disk(&mut disk.inner, refresh_kind.without_io_usage());
             disk.inner.updated = true;
-            disk.inner.total_space = total_space;
-            disk.inner.available_space = available_space;
         } else if add_new_disks {
             let dev_mount_point = c_buf_to_utf8_str(&fs_info.f_mntfromname).unwrap_or("");
 
             // USB keys and CDs are removable.
-            let is_removable = if refresh_kind.details() {
+            let is_removable = if refresh_kind.storage() {
                 [b"USB", b"usb"].iter().any(|b| *b == &fs_type[..])
                     || fs_type.starts_with(b"/dev/cd")
             } else {
                 false
             };
 
-            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,
-                    available_space,
-                    file_system: OsString::from_vec(fs_type),
-                    is_removable,
-                    is_read_only,
-                    read_bytes: 0,
-                    old_read_bytes: 0,
-                    written_bytes: 0,
-                    old_written_bytes: 0,
-                    updated: true,
-                },
-            });
+            let mut disk = 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: 0,
+                available_space: 0,
+                file_system: OsString::from_vec(fs_type),
+                is_removable,
+                is_read_only: false,
+                read_bytes: 0,
+                old_read_bytes: 0,
+                written_bytes: 0,
+                old_written_bytes: 0,
+                updated: true,
+            };
+            // I/O usage is updated for all disks at once at the end.
+            refresh_disk(&mut disk, refresh_kind.without_io_usage());
+            container.push(Disk { inner: disk });
         }
     }
 
-    if add_new_disks {
+    if remove_not_listed_disks {
         container.retain_mut(|disk| {
             if !disk.inner.updated {
                 return false;
diff --git a/src/unix/linux/disk.rs b/src/unix/linux/disk.rs
index 83c2c7d..2dfb227 100644
--- a/src/unix/linux/disk.rs
+++ b/src/unix/linux/disk.rs
@@ -7,7 +7,7 @@ use libc::statvfs;
 use std::collections::HashMap;
 use std::ffi::{OsStr, OsString};
 use std::fs;
-use std::mem;
+use std::mem::MaybeUninit;
 use std::os::unix::ffi::OsStrExt;
 use std::path::{Path, PathBuf};
 use std::str::FromStr;
@@ -48,6 +48,7 @@ pub(crate) struct DiskInner {
     old_read_bytes: u64,
     written_bytes: u64,
     read_bytes: u64,
+    updated: bool,
 }
 
 impl DiskInner {
@@ -84,18 +85,15 @@ impl DiskInner {
     }
 
     pub(crate) fn refresh_specifics(&mut self, refresh_kind: DiskRefreshKind) -> bool {
-        self.efficient_refresh(refresh_kind, &disk_stats(&refresh_kind))
+        self.efficient_refresh(refresh_kind, &disk_stats(&refresh_kind), false)
     }
 
     fn efficient_refresh(
         &mut self,
         refresh_kind: DiskRefreshKind,
         procfs_disk_stats: &HashMap<String, DiskStat>,
+        first: bool,
     ) -> bool {
-        if refresh_kind.kind() && self.type_ == DiskKind::Unknown(-1) {
-            self.type_ = find_type_for_device_name(&self.device_name);
-        }
-
         if refresh_kind.io_usage() {
             if self.actual_device_name.is_none() {
                 self.actual_device_name = Some(get_actual_device_name(&self.device_name));
@@ -114,13 +112,19 @@ impl DiskInner {
             }
         }
 
-        if refresh_kind.details() {
+        if refresh_kind.kind() && self.type_ == DiskKind::Unknown(-1) {
+            self.type_ = find_type_for_device_name(&self.device_name);
+        }
+
+        if refresh_kind.storage() {
             if let Some((total_space, available_space, is_read_only)) =
                 unsafe { load_statvfs_values(&self.mount_point) }
             {
                 self.total_space = total_space;
                 self.available_space = available_space;
-                self.is_read_only = is_read_only;
+                if first {
+                    self.is_read_only = is_read_only;
+                }
             }
         }
 
@@ -144,9 +148,14 @@ impl crate::DisksInner {
         }
     }
 
-    pub(crate) fn refresh_list_specifics(&mut self, refresh_kind: DiskRefreshKind) {
+    pub(crate) fn refresh_list_specifics(
+        &mut self,
+        remove_not_listed_disks: bool,
+        refresh_kind: DiskRefreshKind,
+    ) {
         get_all_list(
             &mut self.disks,
+            remove_not_listed_disks,
             &get_all_utf8_data("/proc/mounts", 16_385).unwrap_or_default(),
             refresh_kind,
         )
@@ -156,7 +165,7 @@ impl crate::DisksInner {
         let procfs_disk_stats = disk_stats(&refresh_kind);
         for disk in self.list_mut() {
             disk.inner
-                .efficient_refresh(refresh_kind, &procfs_disk_stats);
+                .efficient_refresh(refresh_kind, &procfs_disk_stats, false);
         }
     }
 
@@ -190,8 +199,14 @@ fn get_actual_device_name(device: &OsStr) -> String {
 
 unsafe fn load_statvfs_values(mount_point: &Path) -> Option<(u64, u64, bool)> {
     let mount_point_cpath = to_cpath(mount_point);
-    let mut stat: statvfs = mem::zeroed();
-    if retry_eintr!(statvfs(mount_point_cpath.as_ptr() as *const _, &mut stat)) == 0 {
+    let mut stat: MaybeUninit<statvfs> = MaybeUninit::uninit();
+    if retry_eintr!(statvfs(
+        mount_point_cpath.as_ptr() as *const _,
+        stat.as_mut_ptr()
+    )) == 0
+    {
+        let stat = stat.assume_init();
+
         let bsize = cast!(stat.f_bsize);
         let blocks = cast!(stat.f_blocks);
         let bavail = cast!(stat.f_bavail);
@@ -216,56 +231,31 @@ fn new_disk(
     procfs_disk_stats: &HashMap<String, DiskStat>,
     refresh_kind: DiskRefreshKind,
 ) -> Disk {
-    let type_ = if refresh_kind.kind() {
-        find_type_for_device_name(device_name)
-    } else {
-        DiskKind::Unknown(-1)
-    };
-
-    let (total_space, available_space, is_read_only) = if refresh_kind.details() {
-        unsafe { load_statvfs_values(mount_point).unwrap_or((0, 0, false)) }
-    } else {
-        (0, 0, false)
-    };
+    let is_removable = removable_entries
+        .iter()
+        .any(|e| e.as_os_str() == device_name);
 
-    let is_removable = refresh_kind.details()
-        && removable_entries
-            .iter()
-            .any(|e| e.as_os_str() == device_name);
-
-    let (actual_device_name, read_bytes, written_bytes) = if refresh_kind.io_usage() {
-        let actual_device_name = get_actual_device_name(device_name);
-        let (read_bytes, written_bytes) = procfs_disk_stats
-            .get(&actual_device_name)
-            .map(|stat| {
-                (
-                    stat.sectors_read * SECTOR_SIZE,
-                    stat.sectors_written * SECTOR_SIZE,
-                )
-            })
-            .unwrap_or_default();
-        (Some(actual_device_name), read_bytes, written_bytes)
-    } else {
-        (None, 0, 0)
-    };
-
-    Disk {
+    let mut disk = Disk {
         inner: DiskInner {
-            type_,
+            type_: DiskKind::Unknown(-1),
             device_name: device_name.to_owned(),
-            actual_device_name,
+            actual_device_name: None,
             file_system: file_system.to_owned(),
             mount_point: mount_point.to_owned(),
-            total_space,
-            available_space,
+            total_space: 0,
+            available_space: 0,
             is_removable,
-            is_read_only,
+            is_read_only: false,
             old_read_bytes: 0,
             old_written_bytes: 0,
-            read_bytes,
-            written_bytes,
+            read_bytes: 0,
+            written_bytes: 0,
+            updated: true,
         },
-    }
+    };
+    disk.inner
+        .efficient_refresh(refresh_kind, procfs_disk_stats, true);
+    disk
 }
 
 #[allow(clippy::manual_range_contains)]
@@ -339,8 +329,12 @@ fn find_type_for_device_name(device_name: &OsStr) -> DiskKind {
     }
 }
 
-fn get_all_list(container: &mut Vec<Disk>, content: &str, refresh_kind: DiskRefreshKind) {
-    container.clear();
+fn get_all_list(
+    container: &mut Vec<Disk>,
+    remove_not_listed_disks: bool,
+    content: &str,
+    refresh_kind: DiskRefreshKind,
+) {
     // The goal of this array is to list all removable devices (the ones whose name starts with
     // "usb-").
     let removable_entries = match fs::read_dir("/dev/disk/by-id/") {
@@ -362,7 +356,7 @@ fn get_all_list(container: &mut Vec<Disk>, content: &str, refresh_kind: DiskRefr
 
     let procfs_disk_stats = disk_stats(&refresh_kind);
 
-    for disk in content
+    for (fs_spec, fs_file, fs_vfstype) in content
         .lines()
         .map(|line| {
             let line = line.trim_start();
@@ -407,18 +401,39 @@ fn get_all_list(container: &mut Vec<Disk>, content: &str, refresh_kind: DiskRefr
                (fs_file.starts_with("/run") && !fs_file.starts_with("/run/media")) ||
                fs_spec.starts_with("sunrpc"))
         })
-        .map(|(fs_spec, fs_file, fs_vfstype)| {
-            new_disk(
-                fs_spec.as_ref(),
-                Path::new(&fs_file),
-                fs_vfstype.as_ref(),
-                &removable_entries,
-                &procfs_disk_stats,
-                refresh_kind,
-            )
-        })
     {
-        container.push(disk);
+        let mount_point = Path::new(&fs_file);
+        if let Some(disk) = container
+            .iter_mut()
+            .find(|d| d.inner.mount_point == mount_point)
+        {
+            disk.inner
+                .efficient_refresh(refresh_kind, &procfs_disk_stats, false);
+            disk.inner.updated = true;
+            continue;
+        }
+        container.push(new_disk(
+            fs_spec.as_ref(),
+            mount_point,
+            fs_vfstype.as_ref(),
+            &removable_entries,
+            &procfs_disk_stats,
+            refresh_kind,
+        ));
+    }
+
+    if remove_not_listed_disks {
+        container.retain_mut(|disk| {
+            if !disk.inner.updated {
+                return false;
+            }
+            disk.inner.updated = false;
+            true
+        });
+    } else {
+        for c in container.iter_mut() {
+            c.inner.updated = false;
+        }
     }
 }
 
diff --git a/src/unknown/disk.rs b/src/unknown/disk.rs
index 7a4b97d..99bc6a6 100644
--- a/src/unknown/disk.rs
+++ b/src/unknown/disk.rs
@@ -65,7 +65,11 @@ impl DisksInner {
         self.disks
     }
 
-    pub(crate) fn refresh_list_specifics(&mut self, _refreshes: DiskRefreshKind) {
+    pub(crate) fn refresh_list_specifics(
+        &mut self,
+        _remove_not_listed_disks: bool,
+        _refreshes: DiskRefreshKind,
+    ) {
         // Does nothing.
     }
 
diff --git a/src/windows/disk.rs b/src/windows/disk.rs
index 13a74b4..46e6606 100644
--- a/src/windows/disk.rs
+++ b/src/windows/disk.rs
@@ -132,6 +132,7 @@ pub(crate) struct DiskInner {
     old_read_bytes: u64,
     written_bytes: u64,
     read_bytes: u64,
+    updated: bool,
 }
 
 impl DiskInner {
@@ -168,22 +169,30 @@ impl DiskInner {
     }
 
     pub(crate) fn refresh_specifics(&mut self, refreshes: DiskRefreshKind) -> bool {
-        if refreshes.kind() && self.type_ == DiskKind::Unknown(-1) {
-            self.type_ = unsafe { get_disk_kind(&self.device_path, None) };
-        }
-
-        if refreshes.io_usage() {
-            if let Some((read_bytes, written_bytes)) = get_disk_io(&self.device_path, None) {
-                self.old_read_bytes = self.read_bytes;
-                self.old_written_bytes = self.written_bytes;
-                self.read_bytes = read_bytes;
-                self.written_bytes = written_bytes;
-            } else {
-                sysinfo_debug!("Failed to update disk i/o stats");
+        if refreshes.kind() || refreshes.io_usage() {
+            unsafe {
+                if let Some(handle) =
+                    HandleWrapper::new_from_file(&self.device_path, Default::default())
+                {
+                    if refreshes.kind() && self.type_ == DiskKind::Unknown(-1) {
+                        self.type_ = get_disk_kind(&handle);
+                    }
+
+                    if refreshes.io_usage() {
+                        if let Some((read_bytes, written_bytes)) = get_disk_io(handle) {
+                            self.old_read_bytes = self.read_bytes;
+                            self.old_written_bytes = self.written_bytes;
+                            self.read_bytes = read_bytes;
+                            self.written_bytes = written_bytes;
+                        } else {
+                            sysinfo_debug!("Failed to update disk i/o stats");
+                        }
+                    }
+                }
             }
         }
 
-        if refreshes.details() {
+        if refreshes.storage() {
             if let Some((total_space, available_space)) =
                 unsafe { get_drive_size(&self.mount_point) }
             {
@@ -191,7 +200,7 @@ impl DiskInner {
                 self.available_space = available_space;
             }
         }
-        false
+        true
     }
 
     pub(crate) fn usage(&self) -> DiskUsage {
@@ -223,9 +232,13 @@ impl DisksInner {
         self.disks
     }
 
-    pub(crate) fn refresh_list_specifics(&mut self, refreshes: DiskRefreshKind) {
+    pub(crate) fn refresh_list_specifics(
+        &mut self,
+        remove_not_listed_disks: bool,
+        refreshes: DiskRefreshKind,
+    ) {
         unsafe {
-            self.disks = get_list(refreshes);
+            get_list(&mut self.disks, remove_not_listed_disks, refreshes);
         }
     }
 
@@ -262,97 +275,97 @@ unsafe fn get_drive_size(mount_point: &[u16]) -> Option<(u64, u64)> {
     }
 }
 
-pub(crate) unsafe fn get_list(refreshes: DiskRefreshKind) -> Vec<Disk> {
-    #[cfg(feature = "multithread")]
-    use rayon::iter::ParallelIterator;
+pub(crate) unsafe fn get_list(
+    disks: &mut Vec<Disk>,
+    remove_not_listed_disks: bool,
+    refreshes: DiskRefreshKind,
+) {
+    for volume_name in get_volume_guid_paths() {
+        let mount_paths = get_volume_path_names_for_volume_name(&volume_name[..]);
+        if mount_paths.is_empty() {
+            continue;
+        }
 
-    crate::utils::into_iter(get_volume_guid_paths())
-        .flat_map(|volume_name| {
-            let raw_volume_name = PCWSTR::from_raw(volume_name.as_ptr());
-            let drive_type = GetDriveTypeW(raw_volume_name);
+        let raw_volume_name = PCWSTR::from_raw(volume_name.as_ptr());
+        let drive_type = GetDriveTypeW(raw_volume_name);
 
-            let is_removable = refreshes.details() && drive_type == DRIVE_REMOVABLE;
+        if drive_type != DRIVE_FIXED && drive_type != DRIVE_REMOVABLE {
+            continue;
+        }
 
-            if drive_type != DRIVE_FIXED && drive_type != DRIVE_REMOVABLE {
-                return Vec::new();
-            }
-            let mut name = [0u16; MAX_PATH as usize + 1];
-            let mut file_system = [0u16; 32];
-            let mut flags = 0;
-            let volume_info_res = GetVolumeInformationW(
-                raw_volume_name,
-                Some(&mut name),
-                None,
-                None,
-                Some(&mut flags),
-                Some(&mut file_system),
-            )
-            .is_ok();
-            if !volume_info_res {
-                sysinfo_debug!(
-                    "Error: GetVolumeInformationW = {:?}",
-                    Error::from_win32().code()
-                );
-                return Vec::new();
-            }
-            let is_read_only = refreshes.details() && (flags & FILE_READ_ONLY_VOLUME) != 0;
+        let is_removable = drive_type == DRIVE_REMOVABLE;
 
-            let mount_paths = get_volume_path_names_for_volume_name(&volume_name[..]);
-            if mount_paths.is_empty() {
-                return Vec::new();
+        let mut name = [0u16; MAX_PATH as usize + 1];
+        let mut file_system = [0u16; 32];
+        let mut flags = 0;
+        let volume_info_res = GetVolumeInformationW(
+            raw_volume_name,
+            Some(&mut name),
+            None,
+            None,
+            Some(&mut flags),
+            Some(&mut file_system),
+        )
+        .is_ok();
+        if !volume_info_res {
+            sysinfo_debug!(
+                "Error: GetVolumeInformationW = {:?}",
+                Error::from_win32().code()
+            );
+            continue;
+        }
+        let is_read_only = (flags & FILE_READ_ONLY_VOLUME) != 0;
+
+        // The device path is the volume name without the trailing backslash.
+        let device_path = volume_name[..(volume_name.len() - 2)]
+            .iter()
+            .copied()
+            .chain([0])
+            .collect::<Vec<_>>();
+
+        let name = os_string_from_zero_terminated(&name);
+        let file_system = os_string_from_zero_terminated(&file_system);
+        for mount_path in mount_paths {
+            if let Some(disk) = disks.iter_mut().find(|d| d.inner.mount_point == mount_path) {
+                disk.refresh_specifics(refreshes);
+                disk.inner.updated = true;
+                continue;
             }
-
-            // The device path is the volume name without the trailing backslash.
-            let device_path = volume_name[..(volume_name.len() - 2)]
-                .iter()
-                .copied()
-                .chain([0])
-                .collect::<Vec<_>>();
-            let handle = HandleWrapper::new_from_file(&device_path[..], Default::default());
-
-            let (total_space, available_space) = if refreshes.details() {
-                get_drive_size(&mount_paths[0][..]).unwrap_or_default()
-            } else {
-                (0, 0)
-            };
-
-            let type_ = if refreshes.kind() {
-                get_disk_kind(&device_path, handle.as_ref())
-            } else {
-                DiskKind::Unknown(-1)
-            };
-
-            let (read_bytes, written_bytes) = if refreshes.io_usage() {
-                get_disk_io(&device_path, handle).unwrap_or_default()
-            } else {
-                (0, 0)
+            let mut disk = DiskInner {
+                type_: DiskKind::Unknown(-1),
+                name: name.clone(),
+                file_system: file_system.clone(),
+                s_mount_point: OsString::from_wide(&mount_path[..mount_path.len() - 1]),
+                mount_point: mount_path,
+                total_space: 0,
+                available_space: 0,
+                is_removable,
+                is_read_only,
+                device_path: device_path.clone(),
+                old_read_bytes: 0,
+                old_written_bytes: 0,
+                read_bytes: 0,
+                written_bytes: 0,
+                updated: true,
             };
+            disk.refresh_specifics(refreshes);
+            disks.push(Disk { inner: disk });
+        }
+    }
 
-            let name = os_string_from_zero_terminated(&name);
-            let file_system = os_string_from_zero_terminated(&file_system);
-            mount_paths
-                .into_iter()
-                .map(move |mount_path| Disk {
-                    inner: DiskInner {
-                        type_,
-                        name: name.clone(),
-                        file_system: file_system.clone(),
-                        s_mount_point: OsString::from_wide(&mount_path[..mount_path.len() - 1]),
-                        mount_point: mount_path,
-                        total_space,
-                        available_space,
-                        is_removable,
-                        is_read_only,
-                        device_path: device_path.clone(),
-                        old_read_bytes: 0,
-                        old_written_bytes: 0,
-                        read_bytes,
-                        written_bytes,
-                    },
-                })
-                .collect::<Vec<_>>()
-        })
-        .collect::<Vec<_>>()
+    if remove_not_listed_disks {
+        disks.retain_mut(|disk| {
+            if !disk.inner.updated {
+                return false;
+            }
+            disk.inner.updated = false;
+            true
+        });
+    } else {
+        for c in disks.iter_mut() {
+            c.inner.updated = false;
+        }
+    }
 }
 
 fn os_string_from_zero_terminated(name: &[u16]) -> OsString {
@@ -360,27 +373,7 @@ fn os_string_from_zero_terminated(name: &[u16]) -> OsString {
     OsString::from_wide(&name[..len])
 }
 
-unsafe fn get_disk_kind(device_path: &[u16], borrowed_handle: Option<&HandleWrapper>) -> DiskKind {
-    let handle_data;
-    let borrowed_handle = if borrowed_handle.is_none() {
-        handle_data = HandleWrapper::new_from_file(device_path, Default::default());
-        handle_data.as_ref()
-    } else {
-        borrowed_handle
-    };
-    let Some(handle) = borrowed_handle else {
-        sysinfo_debug!("Coudn't get a Handle to retrieve `DiskKind`");
-        return DiskKind::Unknown(-1);
-    };
-
-    if handle.is_invalid() {
-        sysinfo_debug!(
-            "Expected handle to {:?} to be valid",
-            String::from_utf16_lossy(device_path)
-        );
-        return DiskKind::Unknown(-1);
-    }
-
+unsafe fn get_disk_kind(handle: &HandleWrapper) -> DiskKind {
     let spq_trim = STORAGE_PROPERTY_QUERY {
         PropertyId: StorageDeviceSeekPenaltyProperty,
         QueryType: PropertyStandardQuery,
@@ -415,19 +408,9 @@ unsafe fn get_disk_kind(device_path: &[u16], borrowed_handle: Option<&HandleWrap
     }
 }
 
-/// Returns a tuple consisting of the total number of bytes read and written by the volume with the specified device path
-fn get_disk_io(device_path: &[u16], handle: Option<HandleWrapper>) -> Option<(u64, u64)> {
-    let handle =
-        handle.or(unsafe { HandleWrapper::new_from_file(device_path, Default::default()) })?;
-
-    if handle.is_invalid() {
-        sysinfo_debug!(
-            "Expected handle to {:?} to be valid",
-            String::from_utf16_lossy(device_path)
-        );
-        return None;
-    }
-
+/// Returns a tuple consisting of the total number of bytes read and written by the volume with the
+/// specified device path
+fn get_disk_io(handle: HandleWrapper) -> Option<(u64, u64)> {
     let mut disk_perf = DISK_PERFORMANCE::default();
     let mut bytes_returned = 0;
 
diff --git a/src/windows/utils.rs b/src/windows/utils.rs
index e286fbf..762df1e 100644
--- a/src/windows/utils.rs
+++ b/src/windows/utils.rs
@@ -59,7 +59,15 @@ cfg_if! {
                     HANDLE::default(),
                 )
                 .ok()?;
-                Some(Self(handle))
+                if handle.is_invalid() {
+                    sysinfo_debug!(
+                        "Expected handle to {:?} to be valid",
+                        String::from_utf16_lossy(drive_name)
+                    );
+                    None
+                } else {
+                    Some(Self(handle))
+                }
             }
         }
 


Test patch:
diff --git a/tests/disk.rs b/tests/disk.rs
index 2fbab2b..0ec0f75 100644
--- a/tests/disk.rs
+++ b/tests/disk.rs
@@ -21,7 +21,7 @@ fn test_disks() {
 
     let mut disks = sysinfo::Disks::new();
     assert!(disks.list().is_empty());
-    disks.refresh_list();
+    disks.refresh_list(false);
     assert!(!disks.list().is_empty());
 }
 
@@ -39,8 +39,8 @@ fn test_disk_refresh_kind() {
     for fs in [
         DiskRefreshKind::with_kind,
         DiskRefreshKind::without_kind,
-        DiskRefreshKind::with_details,
-        DiskRefreshKind::without_details,
+        DiskRefreshKind::with_storage,
+        DiskRefreshKind::without_storage,
         DiskRefreshKind::with_io_usage,
         DiskRefreshKind::without_io_usage,
     ]
@@ -72,7 +72,7 @@ fn test_disk_refresh_kind() {
                 );
             }
 
-            if refreshes.details() {
+            if refreshes.storage() {
                 // These would ideally assert that *all* are refreshed, but we settle for a weaker
                 // assertion because failures can't be distinguished from "not refreshed" values.
                 assert!(
@@ -102,18 +102,6 @@ fn test_disk_refresh_kind() {
                         .all(|disk| disk.total_space() == Default::default()),
                     "{name}: disk.total_space should not be refreshed"
                 );
-                assert!(
-                    disks
-                        .iter()
-                        .all(|disk| disk.is_read_only() == <bool as Default>::default()),
-                    "{name}: disk.is_read_only should not be refreshed"
-                );
-                assert!(
-                    disks
-                        .iter()
-                        .all(|disk| disk.is_removable() == <bool as Default>::default()),
-                    "{name}: disk.is_removable should not be refreshed"
-                );
             }
 
             if refreshes.io_usage() {