From: NeilBrown <neilb@suse.de>
To: Michael Tokarev <mjt@tls.msk.ru>
Cc: 763917@bugs.debian.org, linux-raid@vger.kernel.org
Subject: Re: Bug#763917: mdadm: rounding errors in human_size()
Date: Thu, 18 Dec 2014 17:00:59 +1100 [thread overview]
Message-ID: <20141218170059.5be02ac2@notabene.brown> (raw)
In-Reply-To: <548188B0.6000309@msgid.tls.msk.ru>
[-- Attachment #1: Type: text/plain, Size: 3411 bytes --]
On Fri, 05 Dec 2014 13:28:00 +0300 Michael Tokarev <mjt@tls.msk.ru> wrote:
> Neil, will you take the patch in this bugreport for the next version?
>
> http://bugs.debian.org/763917.
>
> Thanks,
>
> /mjt
>
> On Fri, 3 Oct 2014 20:24:54 +0200 Jan Echternach <jan@goneko.de> wrote:
> > Package: mdadm
> > Version: 3.3.2-1
> > Severity: minor
> > Tags: patch
> >
> >
> > While setting up a new system, I noticed an incorrect value in the output
> > of mdadm --examine:
> >
> > Avail Dev Size : 2095080 (1023.16 MiB 1072.68 MB)
> >
> > The 1023.16 MiB were quite irritating because the underlying partition has
> > a size of exactly 1023 MiB.
> >
> > The number of sectors seems plausible: 2095080 sectors * 512 bytes/sector
> > are 1022.988 MiB or 1072.681 MB. I looked into the code and found an
> > inaccuracy in human_size() and human_size_brief(). The formula used for
> > the MiB value is essentially
> >
> > long cMiB = (bytes / ( (1LL<<20) / 200LL ) +1) /2;
> >
> > but (1LL<<20) / 200LL is not an integer. It's rounded down and cMiB becomes
> > too large. The quick fix would have been multiplying by 200 before dividing
> > by 1<<20, but that might cause integer overflows in the GiB case.
Given that we are doing 64bit arithmetic, we would need about 56bits of
bytes for there to be a rounding problem. That's 64 petabytes.
I decide to just do the simple transformation. If we get arrays close to
petabytes I would want to make other changes, like reporting the number of
terabytes for larger arrays.
Thanks,
NeilBrown
> >
> > The following patch uses a more complicated formula that computes the
> > fractional portion separately from the integer portion. It also changes some
> > longs to long longs to eliminate a different cause of integer overflows.
> >
> >
> > --- mdadm-3.3.2/util.c 2014-10-03 19:06:51.000000000 +0200
> > +++ mdadm-3.3.2/util.c 2014-10-03 19:08:06.000000000 +0200
> > @@ -671,15 +671,17 @@
> > if (bytes < 5000*1024)
> > buf[0] = 0;
> > else if (bytes < 2*1024LL*1024LL*1024LL) {
> > - long cMiB = (bytes / ( (1LL<<20) / 200LL ) +1) /2;
> > + long cMiB = bytes / (1LL<<20) * 100
> > + + ((bytes % (1LL<<20)) * 200 / (1LL<<20) +1) /2;
> > long cMB = (bytes / ( 1000000LL / 200LL ) +1) /2;
> > snprintf(buf, sizeof(buf), " (%ld.%02ld MiB %ld.%02ld MB)",
> > cMiB/100 , cMiB % 100,
> > cMB/100, cMB % 100);
> > } else {
> > - long cGiB = (bytes / ( (1LL<<30) / 200LL ) +1) /2;
> > - long cGB = (bytes / (1000000000LL/200LL ) +1) /2;
> > - snprintf(buf, sizeof(buf), " (%ld.%02ld GiB %ld.%02ld GB)",
> > + long long cGiB = bytes / (1LL<<30) * 100
> > + + ((bytes % (1LL<<30)) * 200 / (1LL<<30) +1) /2;
> > + long long cGB = (bytes / (1000000000LL/200LL ) +1) /2;
> > + snprintf(buf, sizeof(buf), " (%lld.%02lld GiB %lld.%02lld GB)",
> > cGiB/100 , cGiB % 100,
> > cGB/100, cGB % 100);
> > }
> > @@ -706,12 +708,14 @@
> > buf[0] = 0;
> > else if (prefix == IEC) {
> > if (bytes < 2*1024LL*1024LL*1024LL) {
> > - long cMiB = (bytes / ( (1LL<<20) / 200LL ) +1) /2;
> > + long cMiB = bytes / (1LL<<20) * 100
>
> _______________________________________________
> pkg-mdadm-devel mailing list
> pkg-mdadm-devel@lists.alioth.debian.org
> http://lists.alioth.debian.org/cgi-bin/mailman/listinfo/pkg-mdadm-devel
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 811 bytes --]
prev parent reply other threads:[~2014-12-18 6:00 UTC|newest]
Thread overview: 2+ messages / expand[flat|nested] mbox.gz Atom feed top
[not found] <20141003182454.GA9120@goneko.de>
2014-12-05 10:28 ` Bug#763917: mdadm: rounding errors in human_size() Michael Tokarev
2014-12-18 6:00 ` NeilBrown [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20141218170059.5be02ac2@notabene.brown \
--to=neilb@suse.de \
--cc=763917@bugs.debian.org \
--cc=linux-raid@vger.kernel.org \
--cc=mjt@tls.msk.ru \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.