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


Attachment: signature.asc
Description: PGP signature

Reply via email to