aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSage Weil <sage@newdream.net>2009-10-07 13:59:34 -0400
committerSage Weil <sage@newdream.net>2009-10-07 13:59:34 -0400
commitb28813a61d6ffe05ad353a86965607bb7a7fd60f (patch)
treef416befcd63c5b93b227df4280afb18e00335c27
parentb195befd9acb514dd2afb722e63fdd880ed63217 (diff)
ceph: gracefully avoid empty crush buckets
This avoids a divide by zero when the input and/or map are malformed. Signed-off-by: Sage Weil <sage@newdream.net>
-rw-r--r--fs/ceph/crush/mapper.c9
1 files changed, 7 insertions, 2 deletions
diff --git a/fs/ceph/crush/mapper.c b/fs/ceph/crush/mapper.c
index 0f0730c62695..c268393adfcb 100644
--- a/fs/ceph/crush/mapper.c
+++ b/fs/ceph/crush/mapper.c
@@ -299,7 +299,7 @@ static int crush_choose(struct crush_map *map,
299 struct crush_bucket *in = bucket; 299 struct crush_bucket *in = bucket;
300 int r; 300 int r;
301 int i; 301 int i;
302 int item; 302 int item = 0;
303 int itemtype; 303 int itemtype;
304 int collide, reject; 304 int collide, reject;
305 const int orig_tries = 5; /* attempts before we fall back to search */ 305 const int orig_tries = 5; /* attempts before we fall back to search */
@@ -316,6 +316,7 @@ static int crush_choose(struct crush_map *map,
316 /* choose through intervening buckets */ 316 /* choose through intervening buckets */
317 flocal = 0; 317 flocal = 0;
318 do { 318 do {
319 collide = 0;
319 retry_bucket = 0; 320 retry_bucket = 0;
320 r = rep; 321 r = rep;
321 if (in->alg == CRUSH_BUCKET_UNIFORM) { 322 if (in->alg == CRUSH_BUCKET_UNIFORM) {
@@ -340,6 +341,10 @@ static int crush_choose(struct crush_map *map,
340 } 341 }
341 342
342 /* bucket choose */ 343 /* bucket choose */
344 if (in->size == 0) {
345 reject = 1;
346 goto reject;
347 }
343 if (flocal >= (in->size>>1) && 348 if (flocal >= (in->size>>1) &&
344 flocal > orig_tries) 349 flocal > orig_tries)
345 item = bucket_perm_choose(in, x, r); 350 item = bucket_perm_choose(in, x, r);
@@ -363,7 +368,6 @@ static int crush_choose(struct crush_map *map,
363 } 368 }
364 369
365 /* collision? */ 370 /* collision? */
366 collide = 0;
367 for (i = 0; i < outpos; i++) { 371 for (i = 0; i < outpos; i++) {
368 if (out[i] == item) { 372 if (out[i] == item) {
369 collide = 1; 373 collide = 1;
@@ -388,6 +392,7 @@ static int crush_choose(struct crush_map *map,
388 reject = 0; 392 reject = 0;
389 } 393 }
390 394
395reject:
391 if (reject || collide) { 396 if (reject || collide) {
392 ftotal++; 397 ftotal++;
393 flocal++; 398 flocal++;