Skip to content

Commit adc6f2d

Browse files
Merge pull request ceph#58898 from neesingh-rh/wip-fix-strict-iec-cast
src/common : proper handling of units in `strict_iec_cast` Reviewed-by: Patrick Donnelly <[email protected]> Reviewed-by: Rishabh Dave <[email protected]> Reviewed-by: Dhairya Parmar <[email protected]>
2 parents 0e12e24 + 0b09d16 commit adc6f2d

File tree

3 files changed

+72
-31
lines changed

3 files changed

+72
-31
lines changed

qa/tasks/cephfs/test_quota.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -115,9 +115,11 @@ def test_human_readable_quota_values(self):
115115

116116
readable_values = {"10K": "10240",
117117
"100Ki": "102400",
118+
"100KiB": "102400",
118119
"10M": "10485760",
119120
"100Mi": "104857600",
120121
"2G": "2147483648",
122+
"2GB": "2147483648",
121123
"4Gi": "4294967296",
122124
"1T": "1099511627776",
123125
"2Ti": "2199023255552"}
@@ -135,7 +137,8 @@ def test_human_readable_quota_invalid_values(self):
135137

136138
self.mount_a.run_shell(["mkdir", "subdir"])
137139

138-
invalid_values = ["10A", "1y00Ki", "af00", "G", "", " ", "-1t", "-1"]
140+
invalid_values = ["10A", "1y00Ki", "af00", "G", "", " ", "-1t", "-1",
141+
"1GT", "2MM", "5Di", "8Bi", "i", "7iB"]
139142
for invalid_value in invalid_values:
140143
with self.assertRaises(CommandFailedError):
141144
self.mount_a.setfattr("./subdir", "ceph.quota.max_bytes",

src/common/strtol.cc

Lines changed: 41 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -146,43 +146,54 @@ T strict_iec_cast(std::string_view str, std::string *err)
146146
if (u != std::string_view::npos) {
147147
n = str.substr(0, u);
148148
unit = str.substr(u, str.length() - u);
149+
// handling cases when prefixes entered as KB, MB, ...
150+
// and KiB, MiB, ....
151+
if (unit.length() > 1 && unit.back() == 'B') {
152+
unit = unit.substr(0, unit.length() - 1);
153+
}
149154
// we accept both old si prefixes as well as the proper iec prefixes
150155
// i.e. K, M, ... and Ki, Mi, ...
151-
if (unit.back() == 'i') {
152-
if (unit.front() == 'B') {
153-
*err = "strict_iecstrtoll: illegal prefix \"Bi\"";
154-
return 0;
155-
}
156-
}
157156
if (unit.length() > 2) {
158157
*err = "strict_iecstrtoll: illegal prefix (length > 2)";
159158
return 0;
160159
}
161-
switch(unit.front()) {
162-
case 'K':
163-
m = 10;
164-
break;
165-
case 'M':
166-
m = 20;
167-
break;
168-
case 'G':
169-
m = 30;
170-
break;
171-
case 'T':
172-
m = 40;
173-
break;
174-
case 'P':
175-
m = 50;
176-
break;
177-
case 'E':
178-
m = 60;
179-
break;
180-
case 'B':
181-
break;
182-
default:
183-
*err = "strict_iecstrtoll: unit prefix not recognized";
184-
return 0;
160+
if ((unit.back() == 'i') || (unit.length() == 1)) {
161+
if (unit.back() == 'i') {
162+
if (unit.front() == 'B') {
163+
*err = "strict_iecstrtoll: illegal prefix \"Bi\"";
164+
return 0;
165+
}
166+
}
167+
switch(unit.front()) {
168+
case 'K':
169+
m = 10;
170+
break;
171+
case 'M':
172+
m = 20;
173+
break;
174+
case 'G':
175+
m = 30;
176+
break;
177+
case 'T':
178+
m = 40;
179+
break;
180+
case 'P':
181+
m = 50;
182+
break;
183+
case 'E':
184+
m = 60;
185+
break;
186+
case 'B':
187+
break;
188+
default:
189+
*err = ("strict_iecstrtoll: unit prefix not recognized '" + std::string{unit} + "' ");
190+
return 0;
191+
}
185192
}
193+
else {
194+
*err = ("strict_iecstrtoll: illegal prefix '" + std::string{unit} + "' ");
195+
return 0;
196+
}
186197
}
187198

188199
long long ll = strict_strtoll(n, 10, err);

src/test/strtol.cc

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -184,6 +184,18 @@ TEST(IECStrToLL, WithUnits) {
184184
units["Ti"] = 40;
185185
units["Pi"] = 50;
186186
units["Ei"] = 60;
187+
units["KB"] = 10;
188+
units["MB"] = 20;
189+
units["GB"] = 30;
190+
units["TB"] = 40;
191+
units["PB"] = 50;
192+
units["EB"] = 60;
193+
units["KiB"] = 10;
194+
units["MiB"] = 20;
195+
units["GiB"] = 30;
196+
units["TiB"] = 40;
197+
units["PiB"] = 50;
198+
units["EiB"] = 60;
187199

188200
for (std::map<std::string,int>::iterator p = units.begin();
189201
p != units.end(); ++p) {
@@ -257,6 +269,21 @@ TEST(StrictIECCast, Error) {
257269
(void)strict_iec_cast<int>("1T", &err);
258270
ASSERT_NE(err, "");
259271
}
272+
{
273+
std::string err;
274+
(void)strict_iec_cast<int64_t>("1GT", &err);
275+
ASSERT_NE(err, "");
276+
}
277+
{
278+
std::string err;
279+
(void)strict_iec_cast<int64_t>("1TG", &err);
280+
ASSERT_NE(err, "");
281+
}
282+
{
283+
std::string err;
284+
(void)strict_iec_cast<int64_t>("1KD", &err);
285+
ASSERT_NE(err, "");
286+
}
260287
{
261288
std::string err;
262289
(void)strict_iec_cast<int64_t>("2E", &err);

0 commit comments

Comments
 (0)