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