]> git.ipfire.org Git - people/pmueller/ipfire-2.x.git/blobdiff - src/patches/suse-2.6.27.31/patches.fixes/scsi-lib-string_get_size-don-t-hang-on-zero-no-decimals-on-exact.patch
Reenabled linux-xen, added patches for Xen Kernel Version 2.6.27.31,
[people/pmueller/ipfire-2.x.git] / src / patches / suse-2.6.27.31 / patches.fixes / scsi-lib-string_get_size-don-t-hang-on-zero-no-decimals-on-exact.patch
diff --git a/src/patches/suse-2.6.27.31/patches.fixes/scsi-lib-string_get_size-don-t-hang-on-zero-no-decimals-on-exact.patch b/src/patches/suse-2.6.27.31/patches.fixes/scsi-lib-string_get_size-don-t-hang-on-zero-no-decimals-on-exact.patch
new file mode 100644 (file)
index 0000000..19798bf
--- /dev/null
@@ -0,0 +1,96 @@
+From a8659597bf744b0f8d2560e2a734b5c941569e0e Mon Sep 17 00:00:00 2001
+From: H. Peter Anvin <hpa@zytor.com>
+Date: Tue, 14 Oct 2008 11:34:21 -0700
+Subject: SCSI lib: string_get_size(): don't hang on zero; no decimals on exact
+Patch-mainline: 2.6.28
+References: bnc#500429
+
+From: H. Peter Anvin <hpa@zytor.com>
+
+commit a8659597bf744b0f8d2560e2a734b5c941569e0e upstream.
+
+We would hang forever when passing a zero to string_get_size().
+Furthermore, string_get_size() would produce decimals on a value small
+enough to be exact.  Finally, a few formatting issues are inconsistent
+with standard SI style guidelines.
+
+- If the value is less than the divisor, skip the entire rounding
+  step.  This prints out all small values including zero as integers,
+  without decimals.
+- Add a space between the value and the symbol for the unit,
+  consistent with standard SI practice.
+- Lower case k in kB since we are talking about powers of 10.
+- Finally, change "int" to "unsigned int" in one place to shut up a
+  gcc warning when compiling the code out-of-kernel for testing.
+
+Signed-off-by: H. Peter Anvin <hpa@zytor.com>
+Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ lib/string_helpers.c |   38 +++++++++++++++++++++-----------------
+ 1 file changed, 21 insertions(+), 17 deletions(-)
+
+--- a/lib/string_helpers.c
++++ b/lib/string_helpers.c
+@@ -23,7 +23,7 @@
+ 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",
++      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 };
+@@ -31,7 +31,7 @@ int string_get_size(u64 size, const enum
+               [STRING_UNITS_10] =  units_10,
+               [STRING_UNITS_2] = units_2,
+       };
+-      const int divisor[] = {
++      const unsigned int divisor[] = {
+               [STRING_UNITS_10] = 1000,
+               [STRING_UNITS_2] = 1024,
+       };
+@@ -40,23 +40,27 @@ int string_get_size(u64 size, const enum
+       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",
+-                       (unsigned long long)remainder);
+-              tmp[j+1] = '\0';
++      i = 0;
++      if (size >= divisor[units]) {
++              while (size >= divisor[units] && units_str[units][i]) {
++                      remainder = do_div(size, divisor[units]);
++                      i++;
++              }
++
++              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",
++                               (unsigned long long)remainder);
++                      tmp[j+1] = '\0';
++              }
+       }
+-      snprintf(buf, len, "%lld%s%s", (unsigned long long)size,
++      snprintf(buf, len, "%lld%s %s", (unsigned long long)size,
+                tmp, units_str[units][i]);
+       return 0;