lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <20080902203914.4ddf3735.akpm@linux-foundation.org>
Date:	Tue, 2 Sep 2008 20:39:14 -0700
From:	Andrew Morton <akpm@...ux-foundation.org>
To:	James Bottomley <James.Bottomley@...senPartnership.com>
Cc:	Matthew Wilcox <matthew@....cx>, Simon Arlott <simon@...e.lp0.eu>,
	Linux Kernel Mailing List <linux-kernel@...r.kernel.org>,
	linux-scsi <linux-scsi@...r.kernel.org>
Subject: Re: [PATCH 1/2] lib: add generic helper to print sizes rounded to
 the correct SI range

On Sun, 31 Aug 2008 10:13:54 -0500 James Bottomley <James.Bottomley@...senPartnership.com> wrote:

> This patch adds the ability to print sizes in either units of 10^3 (SI)
> or 2^10 (Binary) units.  It rounds up to three significant figures and
> can be used for either memory or storage capacities.
> 
> Oh, and I'm fully aware that 64 bits is only 16EiB ... the Zetta and
> Yotta units are added for future proofing against the day we have 128
> bit computers ...
> 

As Matthew said - a new %p thingy might be appropriate.

> 
> ---
>  include/linux/string_helpers.h |   10 ++++++
>  lib/Makefile                   |    3 +-
>  lib/string_helpers.c           |   62 ++++++++++++++++++++++++++++++++++++++++
>  3 files changed, 74 insertions(+), 1 deletions(-)
>  create mode 100644 include/linux/string_helpers.h
>  create mode 100644 lib/string_helpers.c
> 
> diff --git a/include/linux/string_helpers.h b/include/linux/string_helpers.h
> new file mode 100644
> index 0000000..6b827fb
> --- /dev/null
> +++ b/include/linux/string_helpers.h
> @@ -0,0 +1,10 @@
> +#include <linux/types.h>
> +
> +enum string_size_units {
> +	STRING_UNITS_10,
> +	STRING_UNITS_2,
> +};

Could do with some comments.

> +int string_get_size(u64 size, enum string_size_units units,
> +		    char *buf, int len);
> +
> diff --git a/lib/Makefile b/lib/Makefile
> index 3b1f94b..44001af 100644
> --- a/lib/Makefile
> +++ b/lib/Makefile
> @@ -19,7 +19,8 @@ lib-$(CONFIG_SMP) += cpumask.o
>  lib-y	+= kobject.o kref.o klist.o
>  
>  obj-y += bcd.o div64.o sort.o parser.o halfmd4.o debug_locks.o random32.o \
> -	 bust_spinlocks.o hexdump.o kasprintf.o bitmap.o scatterlist.o
> +	 bust_spinlocks.o hexdump.o kasprintf.o bitmap.o scatterlist.o \
> +	 string_helpers.o
>  
>  ifeq ($(CONFIG_DEBUG_KOBJECT),y)
>  CFLAGS_kobject.o += -DDEBUG
> diff --git a/lib/string_helpers.c b/lib/string_helpers.c
> new file mode 100644
> index 0000000..3675eaa
> --- /dev/null
> +++ b/lib/string_helpers.c
> @@ -0,0 +1,62 @@
> +/*
> + * Helpers for formatting and printing strings
> + *
> + * Copyright 31 August 2008 James Bottomley
> + */
> +#include <linux/kernel.h>
> +#include <linux/math64.h>
> +#include <linux/module.h>
> +#include <linux/string_helpers.h>
> +
> +/**
> + * string_get_size - get the size in the specified units
> + * @size:	The size to be converted
> + * @units:	units to use (powers of 1000 or 1024)
> + * @buf:	buffer to format to
> + * @len:	length of buffer
> + *
> + * This function returns a string formatted to 3 significant figures
> + * giving the size in the required units.  Returns 0 on success or
> + * error on failure.  @buf is always zero terminated.
> + *
> + */
> +int string_get_size(u64 size, const enum string_size_units units,
> +		    char *buf, int len)
> +{
> +	const char *units_10[] = { "B", "KB", "MB", "GB", "TB", "PB",
> +				   "EB", "ZB", "YB", NULL};
> +	const char *units_2[] = {"B", "Kib", "MiB", "GiB", "TiB", "PiB",
> +				 "EiB", "ZiB", "YiB", NULL };
> +	const char **units_str[] = {
> +		[STRING_UNITS_10] =  units_10,
> +		[STRING_UNITS_2] = units_2,
> +	};
> +	const int divisor[] = {
> +		[STRING_UNITS_10] = 1000,
> +		[STRING_UNITS_2] = 1024,
> +	};

Formally these should be static, but I expect the compiler will work it out.


> +	int i,j;
> +	u64 remainder = 0, sf_cap;
> +	char tmp[8];
> +
> +	tmp[0] = '\0';
> +
> +	for (i = 0; size > divisor[units] && units_str[units][i]; i++)
> +		remainder = do_div(size, divisor[units]);
> +
> +	sf_cap = size;
> +	for (j = 0; sf_cap*10 < 1000; j++)
> +		sf_cap *= 10;
> +
> +	if (j) {
> +		remainder *= 1000;
> +		do_div(remainder, divisor[units]);
> +		snprintf(tmp, sizeof(tmp), ".%03lld", remainder);
> +		tmp[j+1] = '\0';
> +	}
> +
> +	snprintf(buf, len, "%lld%s%s", size, tmp, units_str[units][i]);

Can't print a u64 - we don't know what type it has.  It must be cast to
something, usually unsigned long long.

> +	return 0;
> +}
> +EXPORT_SYMBOL(string_get_size);

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ