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
Seemingly Similar 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