]> git.ipfire.org Git - people/pmueller/ipfire-2.x.git/blob - src/patches/suse-2.6.27.25/patches.fixes/scsi-lib-string_get_size-don-t-hang-on-zero-no-decimals-on-exact.patch
Updated xen patches taken from suse.
[people/pmueller/ipfire-2.x.git] / src / patches / suse-2.6.27.25 / patches.fixes / scsi-lib-string_get_size-don-t-hang-on-zero-no-decimals-on-exact.patch
1 From a8659597bf744b0f8d2560e2a734b5c941569e0e Mon Sep 17 00:00:00 2001
2 From: H. Peter Anvin <hpa@zytor.com>
3 Date: Tue, 14 Oct 2008 11:34:21 -0700
4 Subject: SCSI lib: string_get_size(): don't hang on zero; no decimals on exact
5 Patch-mainline: 2.6.28
6 References: bnc#500429
7
8 From: H. Peter Anvin <hpa@zytor.com>
9
10 commit a8659597bf744b0f8d2560e2a734b5c941569e0e upstream.
11
12 We would hang forever when passing a zero to string_get_size().
13 Furthermore, string_get_size() would produce decimals on a value small
14 enough to be exact. Finally, a few formatting issues are inconsistent
15 with standard SI style guidelines.
16
17 - If the value is less than the divisor, skip the entire rounding
18 step. This prints out all small values including zero as integers,
19 without decimals.
20 - Add a space between the value and the symbol for the unit,
21 consistent with standard SI practice.
22 - Lower case k in kB since we are talking about powers of 10.
23 - Finally, change "int" to "unsigned int" in one place to shut up a
24 gcc warning when compiling the code out-of-kernel for testing.
25
26 Signed-off-by: H. Peter Anvin <hpa@zytor.com>
27 Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
28 Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
29
30 ---
31 lib/string_helpers.c | 38 +++++++++++++++++++++-----------------
32 1 file changed, 21 insertions(+), 17 deletions(-)
33
34 --- a/lib/string_helpers.c
35 +++ b/lib/string_helpers.c
36 @@ -23,7 +23,7 @@
37 int string_get_size(u64 size, const enum string_size_units units,
38 char *buf, int len)
39 {
40 - const char *units_10[] = { "B", "KB", "MB", "GB", "TB", "PB",
41 + const char *units_10[] = { "B", "kB", "MB", "GB", "TB", "PB",
42 "EB", "ZB", "YB", NULL};
43 const char *units_2[] = {"B", "KiB", "MiB", "GiB", "TiB", "PiB",
44 "EiB", "ZiB", "YiB", NULL };
45 @@ -31,7 +31,7 @@ int string_get_size(u64 size, const enum
46 [STRING_UNITS_10] = units_10,
47 [STRING_UNITS_2] = units_2,
48 };
49 - const int divisor[] = {
50 + const unsigned int divisor[] = {
51 [STRING_UNITS_10] = 1000,
52 [STRING_UNITS_2] = 1024,
53 };
54 @@ -40,23 +40,27 @@ int string_get_size(u64 size, const enum
55 char tmp[8];
56
57 tmp[0] = '\0';
58 -
59 - for (i = 0; size > divisor[units] && units_str[units][i]; i++)
60 - remainder = do_div(size, divisor[units]);
61 -
62 - sf_cap = size;
63 - for (j = 0; sf_cap*10 < 1000; j++)
64 - sf_cap *= 10;
65 -
66 - if (j) {
67 - remainder *= 1000;
68 - do_div(remainder, divisor[units]);
69 - snprintf(tmp, sizeof(tmp), ".%03lld",
70 - (unsigned long long)remainder);
71 - tmp[j+1] = '\0';
72 + i = 0;
73 + if (size >= divisor[units]) {
74 + while (size >= divisor[units] && units_str[units][i]) {
75 + remainder = do_div(size, divisor[units]);
76 + i++;
77 + }
78 +
79 + sf_cap = size;
80 + for (j = 0; sf_cap*10 < 1000; j++)
81 + sf_cap *= 10;
82 +
83 + if (j) {
84 + remainder *= 1000;
85 + do_div(remainder, divisor[units]);
86 + snprintf(tmp, sizeof(tmp), ".%03lld",
87 + (unsigned long long)remainder);
88 + tmp[j+1] = '\0';
89 + }
90 }
91
92 - snprintf(buf, len, "%lld%s%s", (unsigned long long)size,
93 + snprintf(buf, len, "%lld%s %s", (unsigned long long)size,
94 tmp, units_str[units][i]);
95
96 return 0;