1 /* 2 * Helpers for formatting and printing strings 3 * 4 * Copyright 31 August 2008 James Bottomley 5 */ 6 #include <linux/kernel.h> 7 #include <linux/math64.h> 8 #include <linux/export.h> 9 #include <linux/string_helpers.h> 10 11 /** 12 * string_get_size - get the size in the specified units 13 * @size: The size to be converted 14 * @units: units to use (powers of 1000 or 1024) 15 * @buf: buffer to format to 16 * @len: length of buffer 17 * 18 * This function returns a string formatted to 3 significant figures 19 * giving the size in the required units. Returns 0 on success or 20 * error on failure. @buf is always zero terminated. 21 * 22 */ 23 int string_get_size(u64 size, const enum string_size_units units, 24 char *buf, int len) 25 { 26 static const char *units_10[] = { "B", "kB", "MB", "GB", "TB", "PB", 27 "EB", "ZB", "YB", NULL}; 28 static const char *units_2[] = {"B", "KiB", "MiB", "GiB", "TiB", "PiB", 29 "EiB", "ZiB", "YiB", NULL }; 30 static const char **units_str[] = { 31 [STRING_UNITS_10] = units_10, 32 [STRING_UNITS_2] = units_2, 33 }; 34 static const unsigned int divisor[] = { 35 [STRING_UNITS_10] = 1000, 36 [STRING_UNITS_2] = 1024, 37 }; 38 int i, j; 39 u64 remainder = 0, sf_cap; 40 char tmp[8]; 41 42 tmp[0] = '\0'; 43 i = 0; 44 if (size >= divisor[units]) { 45 while (size >= divisor[units] && units_str[units][i]) { 46 remainder = do_div(size, divisor[units]); 47 i++; 48 } 49 50 sf_cap = size; 51 for (j = 0; sf_cap*10 < 1000; j++) 52 sf_cap *= 10; 53 54 if (j) { 55 remainder *= 1000; 56 do_div(remainder, divisor[units]); 57 snprintf(tmp, sizeof(tmp), ".%03lld", 58 (unsigned long long)remainder); 59 tmp[j+1] = '\0'; 60 } 61 } 62 63 snprintf(buf, len, "%lld%s %s", (unsigned long long)size, 64 tmp, units_str[units][i]); 65 66 return 0; 67 } 68 EXPORT_SYMBOL(string_get_size); 69