Richard W.M. Jones
2017-Dec-12 22:23 UTC
[Libguestfs] [PATCH] df: Handle block sizes smaller than 1024 bytes (RHBZ#1525241).
Thanks: Mykola Ivanets
---
df/output.c | 26 ++++++++++++++++++++------
1 file changed, 20 insertions(+), 6 deletions(-)
diff --git a/df/output.c b/df/output.c
index eed7f384d..18f76b155 100644
--- a/df/output.c
+++ b/df/output.c
@@ -80,6 +80,22 @@ print_title (void)
}
}
+/* scale (n, 4096, 1024) ==> n * 4
+ * scale (n, 512, 1024) ==> n / 2
+ */
+static uintmax_t
+scale (uintmax_t n, uintmax_t from, uintmax_t to)
+{
+ if (from >= to) {
+ uintmax_t multiplier = from / to;
+ return n * multiplier;
+ }
+ else {
+ uintmax_t divisor = to / from;
+ return n / divisor;
+ }
+}
+
void
print_stat (FILE *fp,
const char *name, const char *uuid_param,
@@ -95,7 +111,7 @@ print_stat (FILE *fp,
#define MAX_LEN (LONGEST_HUMAN_READABLE > 128 ? LONGEST_HUMAN_READABLE :
128)
char buf[4][MAX_LEN];
const char *cols[4];
- int64_t factor, v;
+ int64_t v;
float percent;
const int hopts
human_round_to_nearest|human_autoscale|human_base_1024|human_SI;
@@ -109,15 +125,13 @@ print_stat (FILE *fp,
if (!inodes) { /* 1K blocks */
if (!human) {
- factor = stat->bsize / 1024;
-
- v = stat->blocks * factor;
+ v = scale (stat->blocks, stat->bsize, 1024);
snprintf (buf[0], MAX_LEN, "%" PRIi64, v);
cols[0] = buf[0];
- v = (stat->blocks - stat->bfree) * factor;
+ v = scale (stat->blocks - stat->bfree, stat->bsize, 1024);
snprintf (buf[1], MAX_LEN, "%" PRIi64, v);
cols[1] = buf[1];
- v = stat->bavail * factor;
+ v = scale (stat->bavail, stat->bsize, 1024);
snprintf (buf[2], MAX_LEN, "%" PRIi64, v);
cols[2] = buf[2];
} else {
--
2.15.1
Nikolay Ivanets
2017-Dec-13 00:02 UTC
Re: [Libguestfs] [PATCH] df: Handle block sizes smaller than 1024 bytes (RHBZ#1525241).
2017-12-13 0:23 GMT+02:00 Richard W.M. Jones <rjones@redhat.com>:> Thanks: Mykola IvanetsI have applied the patch and tested on latest stable release: 1.36.11 (actually version doesn't matter). The problem gone. The only note I'd like to stress that virt-df and df will have slightly different output for such cases. Here is virt-df: Filesystem 1K-blocks Used Available Use% disk.qcow2:/dev/sda1 99800 0 99799 1% Here is df: Filesystem 1K-blocks Used Available Use% /dev/sda1 99800 1 99800 1% In both cases (used + available != total) block count. But inequality is in a different way. The situation is the same with human-readable option: rounding is done differently. I don't think virt-df must strickly mimic identical output from df. It is more like informative tool: just quick check. If you need precise values - use statvfs. And lastly, I guess that only file systems with block size < 1024 are affected. -- Nikolay Ivanets
Apparently Analagous Threads
- [PATCH 2/2] GCC 7: Allocate sufficient space for sprintf output.
- [PATCH v2 2/2] GCC 7: Allocate sufficient space for sprintf output.
- [PATCH nbdkit v2 2/3] filters: stats: Measure time per operation
- [PATCH nbdkit v2 1/3] filters: stats: Add size in GiB, show rate in MiB/s
- [PATCH nbdkit v2 3/3] filters: stats: Add flush stats