mirror of
https://github.com/RGBCube/uutils-coreutils
synced 2025-07-27 19:17:43 +00:00
df: switch from u64 to u128 to handle fs with large inodes nr (#6071)
This commit is contained in:
parent
c9922ba3da
commit
32b5591736
1 changed files with 106 additions and 15 deletions
|
@ -58,13 +58,13 @@ pub(crate) struct Row {
|
||||||
bytes_capacity: Option<f64>,
|
bytes_capacity: Option<f64>,
|
||||||
|
|
||||||
/// Total number of inodes in the filesystem.
|
/// Total number of inodes in the filesystem.
|
||||||
inodes: u64,
|
inodes: u128,
|
||||||
|
|
||||||
/// Number of used inodes.
|
/// Number of used inodes.
|
||||||
inodes_used: u64,
|
inodes_used: u128,
|
||||||
|
|
||||||
/// Number of free inodes.
|
/// Number of free inodes.
|
||||||
inodes_free: u64,
|
inodes_free: u128,
|
||||||
|
|
||||||
/// Percentage of inodes that are used, given as a float between 0 and 1.
|
/// Percentage of inodes that are used, given as a float between 0 and 1.
|
||||||
///
|
///
|
||||||
|
@ -178,9 +178,9 @@ impl From<Filesystem> for Row {
|
||||||
} else {
|
} else {
|
||||||
Some(bavail as f64 / ((bused + bavail) as f64))
|
Some(bavail as f64 / ((bused + bavail) as f64))
|
||||||
},
|
},
|
||||||
inodes: files,
|
inodes: files as u128,
|
||||||
inodes_used: fused,
|
inodes_used: fused as u128,
|
||||||
inodes_free: ffree,
|
inodes_free: ffree as u128,
|
||||||
inodes_usage: if files == 0 {
|
inodes_usage: if files == 0 {
|
||||||
None
|
None
|
||||||
} else {
|
} else {
|
||||||
|
@ -235,9 +235,9 @@ impl<'a> RowFormatter<'a> {
|
||||||
/// Get a string giving the scaled version of the input number.
|
/// Get a string giving the scaled version of the input number.
|
||||||
///
|
///
|
||||||
/// The scaling factor is defined in the `options` field.
|
/// The scaling factor is defined in the `options` field.
|
||||||
fn scaled_inodes(&self, size: u64) -> String {
|
fn scaled_inodes(&self, size: u128) -> String {
|
||||||
if let Some(h) = self.options.human_readable {
|
if let Some(h) = self.options.human_readable {
|
||||||
to_magnitude_and_suffix(size.into(), SuffixType::HumanReadable(h))
|
to_magnitude_and_suffix(size, SuffixType::HumanReadable(h))
|
||||||
} else {
|
} else {
|
||||||
size.to_string()
|
size.to_string()
|
||||||
}
|
}
|
||||||
|
@ -395,12 +395,6 @@ impl Table {
|
||||||
let values = fmt.get_values();
|
let values = fmt.get_values();
|
||||||
total += row;
|
total += row;
|
||||||
|
|
||||||
for (i, value) in values.iter().enumerate() {
|
|
||||||
if UnicodeWidthStr::width(value.as_str()) > widths[i] {
|
|
||||||
widths[i] = UnicodeWidthStr::width(value.as_str());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
rows.push(values);
|
rows.push(values);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -410,6 +404,16 @@ impl Table {
|
||||||
rows.push(total_row.get_values());
|
rows.push(total_row.get_values());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// extend the column widths (in chars) for long values in rows
|
||||||
|
// do it here, after total row was added to the list of rows
|
||||||
|
for row in &rows {
|
||||||
|
for (i, value) in row.iter().enumerate() {
|
||||||
|
if UnicodeWidthStr::width(value.as_str()) > widths[i] {
|
||||||
|
widths[i] = UnicodeWidthStr::width(value.as_str());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
rows,
|
rows,
|
||||||
widths,
|
widths,
|
||||||
|
@ -466,9 +470,11 @@ impl fmt::Display for Table {
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
|
|
||||||
|
use std::vec;
|
||||||
|
|
||||||
use crate::blocks::HumanReadable;
|
use crate::blocks::HumanReadable;
|
||||||
use crate::columns::Column;
|
use crate::columns::Column;
|
||||||
use crate::table::{Header, HeaderMode, Row, RowFormatter};
|
use crate::table::{Header, HeaderMode, Row, RowFormatter, Table};
|
||||||
use crate::{BlockSize, Options};
|
use crate::{BlockSize, Options};
|
||||||
|
|
||||||
const COLUMNS_WITH_FS_TYPE: [Column; 7] = [
|
const COLUMNS_WITH_FS_TYPE: [Column; 7] = [
|
||||||
|
@ -848,4 +854,89 @@ mod tests {
|
||||||
|
|
||||||
assert_eq!(row.inodes_used, 0);
|
assert_eq!(row.inodes_used, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_table_column_width_computation_include_total_row() {
|
||||||
|
let d1 = crate::Filesystem {
|
||||||
|
file: None,
|
||||||
|
mount_info: crate::MountInfo {
|
||||||
|
dev_id: "28".to_string(),
|
||||||
|
dev_name: "none".to_string(),
|
||||||
|
fs_type: "9p".to_string(),
|
||||||
|
mount_dir: "/usr/lib/wsl/drivers".to_string(),
|
||||||
|
mount_option: "ro,nosuid,nodev,noatime".to_string(),
|
||||||
|
mount_root: "/".to_string(),
|
||||||
|
remote: false,
|
||||||
|
dummy: false,
|
||||||
|
},
|
||||||
|
usage: crate::table::FsUsage {
|
||||||
|
blocksize: 4096,
|
||||||
|
blocks: 244029695,
|
||||||
|
bfree: 125085030,
|
||||||
|
bavail: 125085030,
|
||||||
|
bavail_top_bit_set: false,
|
||||||
|
files: 99999999999,
|
||||||
|
ffree: 999999,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
let filesystems = vec![d1.clone(), d1];
|
||||||
|
|
||||||
|
let mut options = Options {
|
||||||
|
show_total: true,
|
||||||
|
columns: vec![
|
||||||
|
Column::Source,
|
||||||
|
Column::Itotal,
|
||||||
|
Column::Iused,
|
||||||
|
Column::Iavail,
|
||||||
|
],
|
||||||
|
..Default::default()
|
||||||
|
};
|
||||||
|
|
||||||
|
let table_w_total = Table::new(&options, filesystems.clone());
|
||||||
|
assert_eq!(
|
||||||
|
table_w_total.to_string(),
|
||||||
|
"Filesystem Inodes IUsed IFree\n\
|
||||||
|
none 99999999999 99999000000 999999\n\
|
||||||
|
none 99999999999 99999000000 999999\n\
|
||||||
|
total 199999999998 199998000000 1999998"
|
||||||
|
);
|
||||||
|
|
||||||
|
options.show_total = false;
|
||||||
|
|
||||||
|
let table_w_o_total = Table::new(&options, filesystems);
|
||||||
|
assert_eq!(
|
||||||
|
table_w_o_total.to_string(),
|
||||||
|
"Filesystem Inodes IUsed IFree\n\
|
||||||
|
none 99999999999 99999000000 999999\n\
|
||||||
|
none 99999999999 99999000000 999999"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_row_accumulation_u64_overflow() {
|
||||||
|
let total = u64::MAX as u128;
|
||||||
|
let used1 = 3000u128;
|
||||||
|
let used2 = 50000u128;
|
||||||
|
|
||||||
|
let mut row1 = Row {
|
||||||
|
inodes: total,
|
||||||
|
inodes_used: used1,
|
||||||
|
inodes_free: total - used1,
|
||||||
|
..Default::default()
|
||||||
|
};
|
||||||
|
|
||||||
|
let row2 = Row {
|
||||||
|
inodes: total,
|
||||||
|
inodes_used: used2,
|
||||||
|
inodes_free: total - used2,
|
||||||
|
..Default::default()
|
||||||
|
};
|
||||||
|
|
||||||
|
row1 += row2;
|
||||||
|
|
||||||
|
assert_eq!(row1.inodes, total * 2);
|
||||||
|
assert_eq!(row1.inodes_used, used1 + used2);
|
||||||
|
assert_eq!(row1.inodes_free, total * 2 - used1 - used2);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue