Add support for Tebibytes

Adding support for Tebibytes enables display size of
volumes in Tebibytes and Terabytes when they are
bigger than 2048 GiB (or GB).

Signed-off-by: Kinga Tanska <kinga.tanska@intel.com>
Signed-off-by: Jes Sorensen <jsorensen@fb.com>
This commit is contained in:
Kinga Tanska 2020-01-21 10:38:52 +01:00 committed by Jes Sorensen
parent 4431efebab
commit 42e641abeb
2 changed files with 43 additions and 24 deletions

View File

@ -467,8 +467,8 @@ If this is not specified
size, though if there is a variance among the drives of greater than 1%, a warning is size, though if there is a variance among the drives of greater than 1%, a warning is
issued. issued.
A suffix of 'K', 'M' or 'G' can be given to indicate Kilobytes, Megabytes or A suffix of 'K', 'M', 'G' or 'T' can be given to indicate Kilobytes,
Gigabytes respectively. Megabytes, Gigabytes or Terabytes respectively.
Sometimes a replacement drive can be a little smaller than the Sometimes a replacement drive can be a little smaller than the
original drives though this should be minimised by IDEMA standards. original drives though this should be minimised by IDEMA standards.
@ -532,8 +532,8 @@ problems the array can be made bigger again with no loss with another
.B "\-\-grow \-\-array\-size=" .B "\-\-grow \-\-array\-size="
command. command.
A suffix of 'K', 'M' or 'G' can be given to indicate Kilobytes, Megabytes or A suffix of 'K', 'M', 'G' or 'T' can be given to indicate Kilobytes,
Gigabytes respectively. Megabytes, Gigabytes or Terabytes respectively.
A value of A value of
.B max .B max
restores the apparent size of the array to be whatever the real restores the apparent size of the array to be whatever the real
@ -551,8 +551,8 @@ This is only meaningful for RAID0, RAID4, RAID5, RAID6, and RAID10.
RAID4, RAID5, RAID6, and RAID10 require the chunk size to be a power RAID4, RAID5, RAID6, and RAID10 require the chunk size to be a power
of 2. In any case it must be a multiple of 4KB. of 2. In any case it must be a multiple of 4KB.
A suffix of 'K', 'M' or 'G' can be given to indicate Kilobytes, Megabytes or A suffix of 'K', 'M', 'G' or 'T' can be given to indicate Kilobytes,
Gigabytes respectively. Megabytes, Gigabytes or Terabytes respectively.
.TP .TP
.BR \-\-rounding= .BR \-\-rounding=
@ -767,8 +767,8 @@ When using an
bitmap, the chunksize defaults to 64Meg, or larger if necessary to bitmap, the chunksize defaults to 64Meg, or larger if necessary to
fit the bitmap into the available space. fit the bitmap into the available space.
A suffix of 'K', 'M' or 'G' can be given to indicate Kilobytes, Megabytes or A suffix of 'K', 'M', 'G' or 'T' can be given to indicate Kilobytes,
Gigabytes respectively. Megabytes, Gigabytes or Terabytes respectively.
.TP .TP
.BR \-W ", " \-\-write\-mostly .BR \-W ", " \-\-write\-mostly
@ -857,8 +857,8 @@ an array which was originally created using a different version of
which computed a different offset. which computed a different offset.
Setting the offset explicitly over-rides the default. The value given Setting the offset explicitly over-rides the default. The value given
is in Kilobytes unless a suffix of 'K', 'M' or 'G' is used to explicitly is in Kilobytes unless a suffix of 'K', 'M', 'G' or 'T' is used to explicitly
indicate Kilobytes, Megabytes or Gigabytes respectively. indicate Kilobytes, Megabytes, Gigabytes or Terabytes respectively.
Since Linux 3.4, Since Linux 3.4,
.B \-\-data\-offset .B \-\-data\-offset

47
util.c
View File

@ -389,7 +389,7 @@ int mdadm_version(char *version)
unsigned long long parse_size(char *size) unsigned long long parse_size(char *size)
{ {
/* parse 'size' which should be a number optionally /* parse 'size' which should be a number optionally
* followed by 'K', 'M', or 'G'. * followed by 'K', 'M'. 'G' or 'T'.
* Without a suffix, K is assumed. * Without a suffix, K is assumed.
* Number returned is in sectors (half-K) * Number returned is in sectors (half-K)
* INVALID_SECTORS returned on error. * INVALID_SECTORS returned on error.
@ -411,6 +411,10 @@ unsigned long long parse_size(char *size)
c++; c++;
s *= 1024 * 1024 * 2; s *= 1024 * 1024 * 2;
break; break;
case 'T':
c++;
s *= 1024 * 1024 * 1024 * 2LL;
break;
case 's': /* sectors */ case 's': /* sectors */
c++; c++;
break; break;
@ -893,13 +897,14 @@ char *human_size(long long bytes)
{ {
static char buf[47]; static char buf[47];
/* We convert bytes to either centi-M{ega,ibi}bytes or /* We convert bytes to either centi-M{ega,ibi}bytes,
* centi-G{igi,ibi}bytes, with appropriate rounding, * centi-G{igi,ibi}bytes or centi-T{era,ebi}bytes
* and then print 1/100th of those as a decimal. * with appropriate rounding, and then print
* 1/100th of those as a decimal.
* We allow upto 2048Megabytes before converting to * We allow upto 2048Megabytes before converting to
* gigabytes, as that shows more precision and isn't * gigabytes and 2048Gigabytes before converting to
* terabytes, as that shows more precision and isn't
* too large a number. * too large a number.
* Terabytes are not yet handled.
*/ */
if (bytes < 5000*1024) if (bytes < 5000*1024)
@ -909,11 +914,16 @@ char *human_size(long long bytes)
long cMB = (bytes / ( 1000000LL / 200LL ) +1) /2; long cMB = (bytes / ( 1000000LL / 200LL ) +1) /2;
snprintf(buf, sizeof(buf), " (%ld.%02ld MiB %ld.%02ld MB)", snprintf(buf, sizeof(buf), " (%ld.%02ld MiB %ld.%02ld MB)",
cMiB/100, cMiB % 100, cMB/100, cMB % 100); cMiB/100, cMiB % 100, cMB/100, cMB % 100);
} else { } else if (bytes < 2*1024LL*1024LL*1024LL*1024LL) {
long cGiB = (bytes * 200LL / (1LL<<30) +1) / 2; long cGiB = (bytes * 200LL / (1LL<<30) +1) / 2;
long cGB = (bytes / (1000000000LL/200LL ) +1) /2; long cGB = (bytes / (1000000000LL/200LL ) +1) /2;
snprintf(buf, sizeof(buf), " (%ld.%02ld GiB %ld.%02ld GB)", snprintf(buf, sizeof(buf), " (%ld.%02ld GiB %ld.%02ld GB)",
cGiB/100, cGiB % 100, cGB/100, cGB % 100); cGiB/100, cGiB % 100, cGB/100, cGB % 100);
} else {
long cTiB = (bytes * 200LL / (1LL<<40) + 1) / 2;
long cTB = (bytes / (1000000000000LL / 200LL) + 1) / 2;
snprintf(buf, sizeof(buf), " (%ld.%02ld TiB %ld.%02ld TB)",
cTiB/100, cTiB % 100, cTB/100, cTB % 100);
} }
return buf; return buf;
} }
@ -922,13 +932,14 @@ char *human_size_brief(long long bytes, int prefix)
{ {
static char buf[30]; static char buf[30];
/* We convert bytes to either centi-M{ega,ibi}bytes or /* We convert bytes to either centi-M{ega,ibi}bytes,
* centi-G{igi,ibi}bytes, with appropriate rounding, * centi-G{igi,ibi}bytes or centi-T{era,ebi}bytes
* and then print 1/100th of those as a decimal. * with appropriate rounding, and then print
* 1/100th of those as a decimal.
* We allow upto 2048Megabytes before converting to * We allow upto 2048Megabytes before converting to
* gigabytes, as that shows more precision and isn't * gigabytes and 2048Gigabytes before converting to
* terabytes, as that shows more precision and isn't
* too large a number. * too large a number.
* Terabytes are not yet handled.
* *
* If prefix == IEC, we mean prefixes like kibi,mebi,gibi etc. * If prefix == IEC, we mean prefixes like kibi,mebi,gibi etc.
* If prefix == JEDEC, we mean prefixes like kilo,mega,giga etc. * If prefix == JEDEC, we mean prefixes like kilo,mega,giga etc.
@ -941,10 +952,14 @@ char *human_size_brief(long long bytes, int prefix)
long cMiB = (bytes * 200LL / (1LL<<20) +1) /2; long cMiB = (bytes * 200LL / (1LL<<20) +1) /2;
snprintf(buf, sizeof(buf), "%ld.%02ldMiB", snprintf(buf, sizeof(buf), "%ld.%02ldMiB",
cMiB/100, cMiB % 100); cMiB/100, cMiB % 100);
} else { } else if (bytes < 2*1024LL*1024LL*1024LL*1024LL) {
long cGiB = (bytes * 200LL / (1LL<<30) +1) /2; long cGiB = (bytes * 200LL / (1LL<<30) +1) /2;
snprintf(buf, sizeof(buf), "%ld.%02ldGiB", snprintf(buf, sizeof(buf), "%ld.%02ldGiB",
cGiB/100, cGiB % 100); cGiB/100, cGiB % 100);
} else {
long cTiB = (bytes * 200LL / (1LL<<40) + 1) / 2;
snprintf(buf, sizeof(buf), "%ld.%02ldTiB",
cTiB/100, cTiB % 100);
} }
} }
else if (prefix == JEDEC) { else if (prefix == JEDEC) {
@ -952,10 +967,14 @@ char *human_size_brief(long long bytes, int prefix)
long cMB = (bytes / ( 1000000LL / 200LL ) +1) /2; long cMB = (bytes / ( 1000000LL / 200LL ) +1) /2;
snprintf(buf, sizeof(buf), "%ld.%02ldMB", snprintf(buf, sizeof(buf), "%ld.%02ldMB",
cMB/100, cMB % 100); cMB/100, cMB % 100);
} else { } else if (bytes < 2*1024LL*1024LL*1024LL*1024LL) {
long cGB = (bytes / (1000000000LL/200LL ) +1) /2; long cGB = (bytes / (1000000000LL/200LL ) +1) /2;
snprintf(buf, sizeof(buf), "%ld.%02ldGB", snprintf(buf, sizeof(buf), "%ld.%02ldGB",
cGB/100, cGB % 100); cGB/100, cGB % 100);
} else {
long cTB = (bytes / (1000000000000LL / 200LL) + 1) / 2;
snprintf(buf, sizeof(buf), "%ld.%02ldTB",
cTB/100, cTB % 100);
} }
} }
else else