Subject: kern/32205: Use standard units for memory/media sizes
To: None <kern-bug-people@netbsd.org, gnats-admin@netbsd.org,>
From: Christian Biere <christianbiere@gmx.de>
List: netbsd-bugs
Date: 12/01/2005 02:16:00
>Number:         32205
>Category:       kern
>Synopsis:       Use standard units for memory/media sizes
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    kern-bug-people
>State:          open
>Class:          change-request
>Submitter-Id:   net
>Arrival-Date:   Thu Dec 01 02:16:00 +0000 2005
>Originator:     Christian Biere
>Release:        NetBSD 3.99.13
>Environment:
System: NetBSD cyclonus 3.99.13 NetBSD 3.99.13 (STARSCREAM) #5: Thu Dec 1 02:47:07 CET 2005 bin@cyclonus:/o/NetBSD/obj/sys/arch/i386/compile/STARSCREAM i386
Architecture: i386
Machine: i386
>Description:
The kernel boot messages use the infamous non-standard units to
display memory and media sizes, so that for example a 120 GB
disk is falsely reported as 111 GB disk. 111 GiB would be correct
but such binary units are only commonly used for chip-based
memory.

>How-To-Repeat:
$ dmesg

>Fix:

The following patch replaces format_bytes(9) with humanize_number(9) and
a divisor of 1000 for disk-based devices. Further, humanize_number(9)
is modified so that a divisor of 1024 used by format_bytes(9) gains
KiB, MiB, GiB etc. instead of kB, MB, GB etc. otherwise.

Index: dev/ld.c
===================================================================
RCS file: /cvsroot/src/sys/dev/ld.c,v
retrieving revision 1.38
diff -u -p -r1.38 ld.c
--- dev/ld.c	15 Oct 2005 17:29:11 -0000	1.38
+++ dev/ld.c	1 Dec 2005 01:54:00 -0000
@@ -140,8 +140,8 @@ ldattach(struct ld_softc *sc)
 			sc->sc_ncylinders = (int)ncyl;
 	}
 
-	format_bytes(tbuf, sizeof(tbuf), sc->sc_secperunit *
-	    sc->sc_secsize);
+	humanize_number(tbuf, sizeof(tbuf), sc->sc_secperunit *
+	    sc->sc_secsize, "B", 1000);
 	aprint_normal("%s: %s, %d cyl, %d head, %d sec, %d bytes/sect x %"PRIu64" sectors\n",
 	    sc->sc_dv.dv_xname, tbuf, sc->sc_ncylinders, sc->sc_nheads,
 	    sc->sc_nsectors, sc->sc_secsize, sc->sc_secperunit);
Index: dev/ata/wd.c
===================================================================
RCS file: /cvsroot/src/sys/dev/ata/wd.c,v
retrieving revision 1.313
diff -u -p -r1.313 wd.c
--- dev/ata/wd.c	1 Nov 2005 20:44:04 -0000	1.313
+++ dev/ata/wd.c	1 Dec 2005 01:54:03 -0000
@@ -377,7 +377,7 @@ wdattach(struct device *parent, struct d
 		    wd->sc_params.atap_heads *
 		    wd->sc_params.atap_sectors;
 	}
-	format_bytes(pbuf, sizeof(pbuf), wd->sc_capacity * DEV_BSIZE);
+	humanize_number(pbuf, sizeof(pbuf), wd->sc_capacity * DEV_BSIZE, "B", 1000);
 	aprint_normal("%s: %s, %d cyl, %d head, %d sec, "
 	    "%d bytes/sect x %llu sectors\n",
 	    self->dv_xname, pbuf,
Index: dev/mca/ed_mca.c
===================================================================
RCS file: /cvsroot/src/sys/dev/mca/ed_mca.c,v
retrieving revision 1.30
diff -u -p -r1.30 ed_mca.c
--- dev/mca/ed_mca.c	15 Oct 2005 17:29:25 -0000	1.30
+++ dev/mca/ed_mca.c	1 Dec 2005 01:54:05 -0000
@@ -163,8 +163,8 @@ ed_mca_attach(parent, self, aux)
 		return;
 	}
 
-	format_bytes(pbuf, sizeof(pbuf),
-		(u_int64_t) ed->sc_capacity * DEV_BSIZE);
+	humanize_number(pbuf, sizeof(pbuf),
+		(u_int64_t) ed->sc_capacity * DEV_BSIZE, "B", 1000);
 	printf(": %s, %u cyl, %u head, %u sec, 512 bytes/sect x %u sectors\n",
 		pbuf,
 		ed->cyl, ed->heads, ed->sectors,
Index: dev/scsipi/sd.c
===================================================================
RCS file: /cvsroot/src/sys/dev/scsipi/sd.c,v
retrieving revision 1.241
diff -u -p -r1.241 sd.c
--- dev/scsipi/sd.c	15 Oct 2005 17:29:25 -0000	1.241
+++ dev/scsipi/sd.c	1 Dec 2005 01:54:11 -0000
@@ -274,8 +274,8 @@ sdattach(struct device *parent, struct d
 	aprint_normal("%s: ", sd->sc_dev.dv_xname);
 	switch (result) {
 	case SDGP_RESULT_OK:
-		format_bytes(pbuf, sizeof(pbuf),
-		    (u_int64_t)dp->disksize * dp->blksize);
+		humanize_number(pbuf, sizeof(pbuf),
+		    (u_int64_t)dp->disksize * dp->blksize, "B", 1000);
 	        aprint_normal(
 		"%s, %ld cyl, %ld head, %ld sec, %ld bytes/sect x %llu sectors",
 		    pbuf, dp->cyls, dp->heads, dp->sectors, dp->blksize,
Index: kern/kern_subr.c
===================================================================
RCS file: /cvsroot/src/sys/kern/kern_subr.c,v
retrieving revision 1.119
diff -u -p -r1.119 kern_subr.c
--- kern/kern_subr.c	28 Aug 2005 20:58:14 -0000	1.119
+++ kern/kern_subr.c	1 Dec 2005 01:54:15 -0000
@@ -1229,13 +1229,13 @@ parsedisk(char *str, int len, int defpar
  * plus a possible `x' + suffix extension) fits into len bytes (including
  * the terminating NUL).
  * Returns the number of bytes stored in buf, or -1 if there was a problem.
- * E.g, given a len of 9 and a suffix of `B':
+ * E.g, given a len of 10, a suffix of `B' and 1024 as divisor:
  *	bytes		result
  *	-----		------
  *	99999		`99999 B'
- *	100000		`97 kB'
- *	66715648	`65152 kB'
- *	252215296	`240 MB'
+ *	100000		`97 KiB'
+ *	66715648	`65152 KiB'
+ *	252215296	`240 MiB'
  */
 int
 humanize_number(char *buf, size_t len, uint64_t bytes, const char *suffix,
@@ -1271,8 +1271,9 @@ humanize_number(char *buf, size_t len, u
 	for (i = 0; bytes >= umax && prefixes[i + 1]; i++)
 		bytes /= divisor;
 
-	r = snprintf(buf, len, "%qu%s%c%s", (unsigned long long)bytes,
-	    i == 0 ? "" : " ", prefixes[i], suffix);
+	r = snprintf(buf, len, "%qu%s%c%s%s", (unsigned long long)bytes,
+	    i == 0 ? "" : " ", prefixes[i],
+	    divisor == 1024 && i > 0 ? "i" : "", suffix);
 
 	return (r);
 }
Index: humanize_number.9
===================================================================
RCS file: /cvsroot/src/share/man/man9/humanize_number.9,v
retrieving revision 1.6
diff -u -p -r1.6 humanize_number.9
--- humanize_number.9	4 Oct 2004 19:12:52 -0000	1.6
+++ humanize_number.9	1 Dec 2005 01:04:55 -0000
@@ -85,12 +85,19 @@ SI designator prefixes.
 The prefixes are:
 .Bl -column "Prefix" "Description" "Multiplier" -offset indent
 .It Sy "Prefix" Ta Sy "Description" Ta Sy "Multiplier"
-.It k	kilo	1024
-.It M	mega	1048576
-.It G	giga	1073741824
-.It T	tera	1099511627776
-.It P	peta	1125899906842624
-.It E	exa	1152921504606846976
+.It k	kilo	1000
+.It M	mega	1000000
+.It G	giga	1000000000
+.It T	tera	1000000000000
+.It P	peta	1000000000000000
+.It E	exa	1000000000000000000
+.It Ki	kibi	1024
+.It Mi	mebi	1048576
+.It Gi	gibi	1073741824
+.It Ti	tebi	1099511627776
+.It Pi	pebi	1125899906842624
+.It Ei	exbi	1152921504606846976
+.El
 .El
 .Pp
 .Fa len