Hi! Ran into this /again/ in my CI environment; I've validated, again, that this patch applies to current git, and that it applies the rounding correctly.
Best,
On Mon, Aug 29, 2022 at 01:51:14PM +0200, наб wrote:
> Subject: [PATCH] Correctly (per POSIX) round up df usage percentage
>
> Quoth POSIX Issue 7:
> <percentage used>
> The percentage of the normally available space that is currently
> allocated to all files on the file system. This shall be calculated
> using the fraction:
> <space used>/(<space used> + <space free>)
> expressed as a percentage. This percentage may be greater than 100
> if <space free> is less than zero. The percentage value shall be
> expressed as a positive integer, with any fractional result causing
> it to be rounded to the next highest integer.
>
> Nominally this only applies to -P and -Pk behaviour (the last hunk),
> but for consistency it may be best to apply that everywhere
> ---
> bin/df/df.c | 23 ++++++++++++-----------
> 1 file changed, 12 insertions(+), 11 deletions(-)
>
> diff --git a/bin/df/df.c b/bin/df/df.c
> index fd51f906f89..1f235dadeb4 100644
> --- a/bin/df/df.c
> +++ b/bin/df/df.c
> @@ -51,6 +51,7 @@ int bread(int, off_t, void *, int);
> static void bsdprint(struct statfs *, long, int);
> char *getmntpt(char *);
> static void maketypelist(char *);
> +static int percent(u_int64_t, u_int64_t);
> static void posixprint(struct statfs *, long, int);
> static void prthuman(struct statfs *sfsp, unsigned long long);
> static void prthumanval(long long);
> @@ -323,13 +324,12 @@ prtstat(struct statfs *sfsp, int maxwidth, int
> headerlen, int blocksize)
> fsbtoblk(sfsp->f_blocks, sfsp->f_bsize, blocksize),
> fsbtoblk(used, sfsp->f_bsize, blocksize),
> fsbtoblk(sfsp->f_bavail, sfsp->f_bsize, blocksize));
> - (void)printf(" %5.0f%%",
> - availblks == 0 ? 100.0 : (double)used / (double)availblks * 100.0);
> + (void)printf(" %5d%%", percent(used, availblks));
> if (iflag) {
> inodes = sfsp->f_files;
> used = inodes - sfsp->f_ffree;
> - (void)printf(" %7llu %7llu %5.0f%% ", used, sfsp->f_ffree,
> - inodes == 0 ? 100.0 : (double)used / (double)inodes * 100.0);
> + (void)printf(" %7llu %7llu %5d%% ", used, sfsp->f_ffree,
> + percent(used, inodes));
> } else
> (void)printf(" ");
> (void)printf(" %s\n", sfsp->f_mntonname);
> @@ -372,6 +372,12 @@ bsdprint(struct statfs *mntbuf, long mntsize, int
> maxwidth)
> return;
> }
>
> +static int
> +percent(u_int64_t used, u_int64_t avail)
> +{
> + return avail ? (100 * used + (avail - 1)) / avail : 100;
> +}
> +
> /*
> * Print in format defined by POSIX 1002.2, invoke with -P option.
> */
> @@ -383,7 +389,6 @@ posixprint(struct statfs *mntbuf, long mntsize, int
> maxwidth)
> char *blockstr;
> struct statfs *sfsp;
> long long used, avail;
> - double percentused;
>
> if (kflag) {
> blocksize = 1024;
> @@ -401,18 +406,14 @@ posixprint(struct statfs *mntbuf, long mntsize, int
> maxwidth)
> sfsp = &mntbuf[i];
> used = sfsp->f_blocks - sfsp->f_bfree;
> avail = sfsp->f_bavail + used;
> - if (avail == 0)
> - percentused = 100.0;
> - else
> - percentused = (double)used / (double)avail * 100.0;
>
> - (void) printf ("%-*.*s %*lld %10lld %11lld %5.0f%% %s\n",
> + (void) printf ("%-*.*s %*lld %10lld %11lld %5d%% %s\n",
> maxwidth, maxwidth, sfsp->f_mntfromname,
> (int)strlen(blockstr),
> fsbtoblk(sfsp->f_blocks, sfsp->f_bsize, blocksize),
> fsbtoblk(used, sfsp->f_bsize, blocksize),
> fsbtoblk(sfsp->f_bavail, sfsp->f_bsize, blocksize),
> - percentused, sfsp->f_mntonname);
> + percent(used, avail), sfsp->f_mntonname);
> }
> }
>
> --
> 2.30.2
signature.asc
Description: PGP signature
