mirror of
https://github.com/RGBCube/uutils-coreutils
synced 2025-07-29 12:07:46 +00:00
df: fix calculation of Use% column
Change formula from: "Used/Size * 100" to "Used/(Used + Avail) * 100". This formula also works if "Used" and "Avail" do not add up to "Size", which is the case if there are reserved disk blocks.
This commit is contained in:
parent
d6fd701511
commit
e152ebaead
2 changed files with 15 additions and 20 deletions
|
@ -149,24 +149,28 @@ impl From<Filesystem> for Row {
|
||||||
ffree,
|
ffree,
|
||||||
..
|
..
|
||||||
} = fs.usage;
|
} = fs.usage;
|
||||||
|
let bused = blocks - bfree;
|
||||||
Self {
|
Self {
|
||||||
file: fs.file,
|
file: fs.file,
|
||||||
fs_device: dev_name,
|
fs_device: dev_name,
|
||||||
fs_type,
|
fs_type,
|
||||||
fs_mount: mount_dir,
|
fs_mount: mount_dir,
|
||||||
bytes: blocksize * blocks,
|
bytes: blocksize * blocks,
|
||||||
bytes_used: blocksize * (blocks - bfree),
|
bytes_used: blocksize * bused,
|
||||||
bytes_avail: blocksize * bavail,
|
bytes_avail: blocksize * bavail,
|
||||||
bytes_usage: if blocks == 0 {
|
bytes_usage: if blocks == 0 {
|
||||||
None
|
None
|
||||||
} else {
|
} else {
|
||||||
Some(((blocks - bfree) as f64) / blocks as f64)
|
// We use "(bused + bavail)" instead of "blocks" because on some filesystems (e.g.
|
||||||
|
// ext4) "blocks" also includes reserved blocks we ignore for the usage calculation.
|
||||||
|
// https://www.gnu.org/software/coreutils/faq/coreutils-faq.html#df-Size-and-Used-and-Available-do-not-add-up
|
||||||
|
Some((bused as f64) / (bused + bavail) as f64)
|
||||||
},
|
},
|
||||||
#[cfg(target_os = "macos")]
|
#[cfg(target_os = "macos")]
|
||||||
bytes_capacity: if bavail == 0 {
|
bytes_capacity: if bavail == 0 {
|
||||||
None
|
None
|
||||||
} else {
|
} else {
|
||||||
Some(bavail as f64 / ((blocks - bfree + bavail) as f64))
|
Some(bavail as f64 / ((bused + bavail) as f64))
|
||||||
},
|
},
|
||||||
inodes: files,
|
inodes: files,
|
||||||
inodes_used: files - ffree,
|
inodes_used: files - ffree,
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
// spell-checker:ignore udev
|
// spell-checker:ignore udev pcent
|
||||||
use crate::common::util::*;
|
use crate::common::util::*;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -139,33 +139,24 @@ fn test_total() {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_use_percentage() {
|
fn test_use_percentage() {
|
||||||
// Example output:
|
let output = new_ucmd!()
|
||||||
//
|
.args(&["--output=used,avail,pcent"])
|
||||||
// Filesystem 1K-blocks Used Available Use% Mounted on
|
.succeeds()
|
||||||
// udev 3858016 0 3858016 0% /dev
|
.stdout_move_str();
|
||||||
// ...
|
|
||||||
// /dev/loop14 63488 63488 0 100% /snap/core20/1361
|
|
||||||
let output = new_ucmd!().succeeds().stdout_move_str();
|
|
||||||
|
|
||||||
// Skip the header line.
|
// Skip the header line.
|
||||||
let lines: Vec<&str> = output.lines().skip(1).collect();
|
let lines: Vec<&str> = output.lines().skip(1).collect();
|
||||||
|
|
||||||
for line in lines {
|
for line in lines {
|
||||||
let mut iter = line.split_whitespace();
|
let mut iter = line.split_whitespace();
|
||||||
iter.next();
|
|
||||||
let reported_size = iter.next().unwrap().parse::<f64>().unwrap();
|
|
||||||
let reported_used = iter.next().unwrap().parse::<f64>().unwrap();
|
let reported_used = iter.next().unwrap().parse::<f64>().unwrap();
|
||||||
// Skip "Available" column
|
let reported_avail = iter.next().unwrap().parse::<f64>().unwrap();
|
||||||
iter.next();
|
|
||||||
if cfg!(target_os = "macos") {
|
|
||||||
// Skip "Capacity" column
|
|
||||||
iter.next();
|
|
||||||
}
|
|
||||||
let reported_percentage = iter.next().unwrap();
|
let reported_percentage = iter.next().unwrap();
|
||||||
let reported_percentage = reported_percentage[..reported_percentage.len() - 1]
|
let reported_percentage = reported_percentage[..reported_percentage.len() - 1]
|
||||||
.parse::<u8>()
|
.parse::<u8>()
|
||||||
.unwrap();
|
.unwrap();
|
||||||
let computed_percentage = (100.0 * (reported_used / reported_size)).ceil() as u8;
|
let computed_percentage =
|
||||||
|
(100.0 * (reported_used / (reported_used + reported_avail))).ceil() as u8;
|
||||||
|
|
||||||
assert_eq!(computed_percentage, reported_percentage);
|
assert_eq!(computed_percentage, reported_percentage);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue