ClementTsang/bottom · error · anyhow::Error

statvfs failed to get the disk usage for disk

Error message

statvfs failed to get the disk usage for disk {path:?}

What it means

Partition::usage on Unix platforms (the generic 'other' implementation) calls statvfs(3) on the mount path to compute free/total space. If statvfs returns non-zero, the call failed and the path plus errno context is reported in this error.

Solutions

  1. Check the partition's mount point still exists before calling usage() (std::path::Path::exists)
  2. Verify the process has read/execute permission on the mount directory
  3. Re-read the mount table to drop stale entries for unmounted filesystems
  4. Handle per-partition failures gracefully instead of aborting the whole disk harvest

Example fix

// before
let usage = partition.usage()?;
// after
let usage = match partition.usage() {
    Ok(u) => Some(u),
    Err(e) => { log::warn!("statvfs failed, skipping: {e}"); None },
};
Defensive patterns

Strategy: validation

Validate before calling

// Check the mount point exists and is accessible before calling usage
use std::os::unix::fs::MetadataExt;
let usable = path.exists() && std::fs::metadata(&path).map(|m| m.dev() != 0).unwrap_or(false);

Try / catch

match partition.usage() {
    Ok(u) => Some(u),
    Err(e) if e.to_string().starts_with("statvfs failed") => {
        log::warn!("unmountable/stale mount: {e}"); None
    },
    Err(e) => return Err(e),
}

Prevention

When it happens

Trigger: Calling usage() on a partition whose mount point no longer exists, is not accessible, or where statvfs fails due to EACCES, ENOENT, ELOOP, or filesystem-specific errors.

Common situations: Mount points that disappeared (unmounted network shares, ejected drives), restricted permissions in containers, or stale mount entries in /proc/mounts.

Understand the failure class

Background: "failed to read file", EACCES, ENOENT and "could not read <path>" errors: when a program can't read a file from disk — this error's family across 49 libraries.

Related errors


AI-assisted analysis of ClementTsang/bottom@b77d317502 (2026-09-07). Data as JSON: /api/errors/dd873aab34af0af8. Report an issue: GitHub.

Appendix: source

Thrown at src/collection/disks/unix/other/partition.rs:45

    #[inline]
    pub fn fs_type(&self) -> &FileSystem {
        &self.fs_type
    }

    /// Returns the usage stats for this partition.
    pub fn usage(&self) -> anyhow::Result<Usage> {
        let path = CString::new(self.mount_point().as_os_str().as_bytes())?;
        let mut vfs = std::mem::MaybeUninit::<libc::statvfs>::uninit();

        // SAFETY: System API call. Arguments should be correct.
        let result = unsafe { libc::statvfs(path.as_ptr(), vfs.as_mut_ptr()) };

        if result == 0 {
            // SAFETY: We check that it succeeded (result is 0), which means vfs
            // should be populated.
            Ok(Usage::new(unsafe { vfs.assume_init() }))
        } else {
            bail!("statvfs failed to get the disk usage for disk {path:?}")
        }
    }

    /// Returns the device name.
    #[inline]
    pub fn get_device_name(&self) -> String {
        self.device.clone()
    }
}

fn partitions_iter() -> anyhow::Result<impl Iterator<Item = Partition>> {
    let mounts = bindings::mounts()?;

    unsafe fn ptr_to_cow<'a>(ptr: *const i8) -> std::borrow::Cow<'a, str> {
        unsafe { CStr::from_ptr(ptr).to_string_lossy() }
    }

    Ok(mounts.into_iter().map(|stat| {

View on GitHub (pinned to b77d317502)