ClementTsang/bottom · error

statvfs had an issue getting info from

Error message

statvfs had an issue getting info from {path:?}

What it means

Raised in the public `usage()` of a Linux disk partition when the `libc::statvfs` call returns non-zero, meaning the kernel refused to return filesystem statistics for the given mount-point path. The library has already validated the path as a CString, so the failure comes from statvfs itself — typically the path does not exist or is inaccessible (errno EACCES, ENOENT, etc.).

Solutions

  1. Retry `usage()` — if the mount was being unmounted concurrently, re-enumerate partitions first
  2. Check the mount point still exists and is accessible (`ls`/`stat` it) and that the process has permission to traverse it
  3. Check `errno`/`last_os_error()` right after the failure for the precise reason (ENOENT vs EACCES)
  4. Skip the affected partition if it is transient (e.g. automounted media)

Example fix

// before
let usage = partition.usage()?;
// after
let usage = match partition.usage() {
    Ok(u) => u,
    Err(e) if e.to_string().starts_with("statvfs had an issue") => {
        eprintln!("partition vanished, skipping: {e}");
        continue;
    },
    Err(e) => return Err(e),
};
Defensive patterns

Strategy: retry

Validate before calling

// Verify the mount point is accessible before calling statvfs-backed usage()
let mp = partition.mount_point();
if !mp.exists() {
    eprintln!("mount point {mp:?} is gone; skipping");
} else {
    let usage = partition.usage()?;
}

Try / catch

match partition.usage() {
    Ok(u) => handle(u),
    Err(e) if e.to_string().contains("statvfs had an issue") => {
        eprintln!("transient statvfs failure, re-enumerating mounts: {e}");
        // re-enumerate partitions and retry once
    }
    Err(e) => return Err(e),
}

Prevention

When it happens

Trigger: `usage()` called on a mount point that was unmounted between enumeration and the statvfs call; a path the process lacks search permission for; statvfs failing for any OS reason (result != 0).

Common situations: Race with `umount` while iterating mounted filesystems; restricted environments (containers, sandboxed processes) where the mount point is not visible; autofs mount points that fail on access.

Understand the failure class

Background: "File not found" and ENOENT errors: why libraries can't find a file that should exist — this error's family across 50 libraries.

Related errors


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

Appendix: source

Thrown at src/collection/disks/unix/linux/partition.rs:100

            .to_str()
            .ok_or_else(|| io::Error::from(io::ErrorKind::InvalidInput))
            .and_then(|string| {
                CString::new(string).map_err(|_| io::Error::from(io::ErrorKind::InvalidInput))
            })
            .map_err(|e| anyhow::anyhow!("invalid path: {e:?}"))?;

        let mut vfs = mem::MaybeUninit::<libc::statvfs>::uninit();

        // SAFETY: libc call, `path` is a valid C string and buf is a valid
        // pointer to write to.
        let result = unsafe { libc::statvfs(path.as_ptr(), vfs.as_mut_ptr()) };

        if result == 0 {
            // SAFETY: If result is 0, it succeeded, and vfs should be non-null.
            let vfs = unsafe { vfs.assume_init() };
            Ok(Usage::new(vfs))
        } else {
            Err(anyhow::anyhow!(
                "statvfs had an issue getting info from {path:?}"
            ))
        }
    }
}

fn fix_mount_point(s: &str) -> String {
    const ESCAPED_BACKSLASH: &str = "\\134";
    const ESCAPED_SPACE: &str = "\\040";
    const ESCAPED_TAB: &str = "\\011";
    const ESCAPED_NEWLINE: &str = "\\012";

    s.replace(ESCAPED_BACKSLASH, "\\")
        .replace(ESCAPED_SPACE, " ")
        .replace(ESCAPED_TAB, "\t")
        .replace(ESCAPED_NEWLINE, "\n")
}

View on GitHub (pinned to b77d317502)