25
25
* string_get_size - get the size in the specified units
26
26
* @size: The size to be converted in blocks
27
27
* @blk_size: Size of the block (use 1 for size in bytes)
28
- * @units: units to use (powers of 1000 or 1024)
28
+ * @units: Units to use (powers of 1000 or 1024), whether to include space separator
29
29
* @buf: buffer to format to
30
30
* @len: length of buffer
31
31
*
39
39
int string_get_size (u64 size , u64 blk_size , const enum string_size_units units ,
40
40
char * buf , int len )
41
41
{
42
+ enum string_size_units units_base = units & STRING_UNITS_MASK ;
42
43
static const char * const units_10 [] = {
43
- "B " , "kB " , "MB " , "GB " , "TB " , "PB " , "EB " , "ZB " , "YB"
44
+ "" , "k " , "M " , "G " , "T " , "P " , "E " , "Z " , "Y" ,
44
45
};
45
46
static const char * const units_2 [] = {
46
- "B " , "KiB " , "MiB " , "GiB " , "TiB " , "PiB " , "EiB " , "ZiB " , "YiB"
47
+ "" , "Ki " , "Mi " , "Gi " , "Ti " , "Pi " , "Ei " , "Zi " , "Yi" ,
47
48
};
48
49
static const char * const * const units_str [] = {
49
50
[STRING_UNITS_10 ] = units_10 ,
@@ -68,7 +69,7 @@ int string_get_size(u64 size, u64 blk_size, const enum string_size_units units,
68
69
69
70
/* This is Napier's algorithm. Reduce the original block size to
70
71
*
71
- * coefficient * divisor[units ]^i
72
+ * coefficient * divisor[units_base ]^i
72
73
*
73
74
* we do the reduction so both coefficients are just under 32 bits so
74
75
* that multiplying them together won't overflow 64 bits and we keep
@@ -78,12 +79,12 @@ int string_get_size(u64 size, u64 blk_size, const enum string_size_units units,
78
79
* precision is in the coefficients.
79
80
*/
80
81
while (blk_size >> 32 ) {
81
- do_div (blk_size , divisor [units ]);
82
+ do_div (blk_size , divisor [units_base ]);
82
83
i ++ ;
83
84
}
84
85
85
86
while (size >> 32 ) {
86
- do_div (size , divisor [units ]);
87
+ do_div (size , divisor [units_base ]);
87
88
i ++ ;
88
89
}
89
90
@@ -92,8 +93,8 @@ int string_get_size(u64 size, u64 blk_size, const enum string_size_units units,
92
93
size *= blk_size ;
93
94
94
95
/* and logarithmically reduce it until it's just under the divisor */
95
- while (size >= divisor [units ]) {
96
- remainder = do_div (size , divisor [units ]);
96
+ while (size >= divisor [units_base ]) {
97
+ remainder = do_div (size , divisor [units_base ]);
97
98
i ++ ;
98
99
}
99
100
@@ -103,10 +104,10 @@ int string_get_size(u64 size, u64 blk_size, const enum string_size_units units,
103
104
for (j = 0 ; sf_cap * 10 < 1000 ; j ++ )
104
105
sf_cap *= 10 ;
105
106
106
- if (units == STRING_UNITS_2 ) {
107
+ if (units_base == STRING_UNITS_2 ) {
107
108
/* express the remainder as a decimal. It's currently the
108
109
* numerator of a fraction whose denominator is
109
- * divisor[units ], which is 1 << 10 for STRING_UNITS_2 */
110
+ * divisor[units_base ], which is 1 << 10 for STRING_UNITS_2 */
110
111
remainder *= 1000 ;
111
112
remainder >>= 10 ;
112
113
}
@@ -128,10 +129,12 @@ int string_get_size(u64 size, u64 blk_size, const enum string_size_units units,
128
129
if (i >= ARRAY_SIZE (units_2 ))
129
130
unit = "UNK" ;
130
131
else
131
- unit = units_str [units ][i ];
132
+ unit = units_str [units_base ][i ];
132
133
133
- return snprintf (buf , len , "%u%s %s" , (u32 )size ,
134
- tmp , unit );
134
+ return snprintf (buf , len , "%u%s%s%s%s" , (u32 )size , tmp ,
135
+ (units & STRING_UNITS_NO_SPACE ) ? "" : " " ,
136
+ unit ,
137
+ (units & STRING_UNITS_NO_BYTES ) ? "" : "B" );
135
138
}
136
139
EXPORT_SYMBOL (string_get_size );
137
140
0 commit comments