diff options
author | Sage Weil <sage@inktank.com> | 2012-05-07 18:35:24 -0400 |
---|---|---|
committer | Sage Weil <sage@inktank.com> | 2012-05-07 18:38:51 -0400 |
commit | a1f4895be8bf1ba56c2306b058f51619e9b0e8f8 (patch) | |
tree | f5bdd809f4bcc24daa0dfe1f7bcc8eb2d56227bb /net/ceph/crush | |
parent | c90f95ed46393e29d843686e21947d1c6fcb1164 (diff) |
crush: be more tolerant of nonsensical crush maps
If we get a map that doesn't make sense, error out or ignore the badness
instead of BUGging out. This reflects the ceph.git commits
9895f0bff7dc68e9b49b572613d242315fb11b6c and
8ded26472058d5205803f244c2f33cb6cb10de79.
Reviewed-by: Alex Elder <elder@inktank.com>
Signed-off-by: Sage Weil <sage@inktank.com>
Diffstat (limited to 'net/ceph/crush')
-rw-r--r-- | net/ceph/crush/mapper.c | 33 |
1 files changed, 24 insertions, 9 deletions
diff --git a/net/ceph/crush/mapper.c b/net/ceph/crush/mapper.c index 583f644b0e28..00baad5d3bde 100644 --- a/net/ceph/crush/mapper.c +++ b/net/ceph/crush/mapper.c | |||
@@ -152,8 +152,8 @@ static int bucket_list_choose(struct crush_bucket_list *bucket, | |||
152 | return bucket->h.items[i]; | 152 | return bucket->h.items[i]; |
153 | } | 153 | } |
154 | 154 | ||
155 | BUG_ON(1); | 155 | dprintk("bad list sums for bucket %d\n", bucket->h.id); |
156 | return 0; | 156 | return bucket->h.items[0]; |
157 | } | 157 | } |
158 | 158 | ||
159 | 159 | ||
@@ -239,6 +239,7 @@ static int bucket_straw_choose(struct crush_bucket_straw *bucket, | |||
239 | static int crush_bucket_choose(struct crush_bucket *in, int x, int r) | 239 | static int crush_bucket_choose(struct crush_bucket *in, int x, int r) |
240 | { | 240 | { |
241 | dprintk(" crush_bucket_choose %d x=%d r=%d\n", in->id, x, r); | 241 | dprintk(" crush_bucket_choose %d x=%d r=%d\n", in->id, x, r); |
242 | BUG_ON(in->size == 0); | ||
242 | switch (in->alg) { | 243 | switch (in->alg) { |
243 | case CRUSH_BUCKET_UNIFORM: | 244 | case CRUSH_BUCKET_UNIFORM: |
244 | return bucket_uniform_choose((struct crush_bucket_uniform *)in, | 245 | return bucket_uniform_choose((struct crush_bucket_uniform *)in, |
@@ -253,7 +254,7 @@ static int crush_bucket_choose(struct crush_bucket *in, int x, int r) | |||
253 | return bucket_straw_choose((struct crush_bucket_straw *)in, | 254 | return bucket_straw_choose((struct crush_bucket_straw *)in, |
254 | x, r); | 255 | x, r); |
255 | default: | 256 | default: |
256 | BUG_ON(1); | 257 | dprintk("unknown bucket %d alg %d\n", in->id, in->alg); |
257 | return in->items[0]; | 258 | return in->items[0]; |
258 | } | 259 | } |
259 | } | 260 | } |
@@ -354,7 +355,11 @@ static int crush_choose(const struct crush_map *map, | |||
354 | item = bucket_perm_choose(in, x, r); | 355 | item = bucket_perm_choose(in, x, r); |
355 | else | 356 | else |
356 | item = crush_bucket_choose(in, x, r); | 357 | item = crush_bucket_choose(in, x, r); |
357 | BUG_ON(item >= map->max_devices); | 358 | if (item >= map->max_devices) { |
359 | dprintk(" bad item %d\n", item); | ||
360 | skip_rep = 1; | ||
361 | break; | ||
362 | } | ||
358 | 363 | ||
359 | /* desired type? */ | 364 | /* desired type? */ |
360 | if (item < 0) | 365 | if (item < 0) |
@@ -365,8 +370,12 @@ static int crush_choose(const struct crush_map *map, | |||
365 | 370 | ||
366 | /* keep going? */ | 371 | /* keep going? */ |
367 | if (itemtype != type) { | 372 | if (itemtype != type) { |
368 | BUG_ON(item >= 0 || | 373 | if (item >= 0 || |
369 | (-1-item) >= map->max_buckets); | 374 | (-1-item) >= map->max_buckets) { |
375 | dprintk(" bad item type %d\n", type); | ||
376 | skip_rep = 1; | ||
377 | break; | ||
378 | } | ||
370 | in = map->buckets[-1-item]; | 379 | in = map->buckets[-1-item]; |
371 | retry_bucket = 1; | 380 | retry_bucket = 1; |
372 | continue; | 381 | continue; |
@@ -478,7 +487,10 @@ int crush_do_rule(const struct crush_map *map, | |||
478 | int numrep; | 487 | int numrep; |
479 | int firstn; | 488 | int firstn; |
480 | 489 | ||
481 | BUG_ON(ruleno >= map->max_rules); | 490 | if ((__u32)ruleno >= map->max_rules) { |
491 | dprintk(" bad ruleno %d\n", ruleno); | ||
492 | return 0; | ||
493 | } | ||
482 | 494 | ||
483 | rule = map->rules[ruleno]; | 495 | rule = map->rules[ruleno]; |
484 | result_len = 0; | 496 | result_len = 0; |
@@ -528,7 +540,8 @@ int crush_do_rule(const struct crush_map *map, | |||
528 | firstn = 1; | 540 | firstn = 1; |
529 | case CRUSH_RULE_CHOOSE_LEAF_INDEP: | 541 | case CRUSH_RULE_CHOOSE_LEAF_INDEP: |
530 | case CRUSH_RULE_CHOOSE_INDEP: | 542 | case CRUSH_RULE_CHOOSE_INDEP: |
531 | BUG_ON(wsize == 0); | 543 | if (wsize == 0) |
544 | break; | ||
532 | 545 | ||
533 | recurse_to_leaf = | 546 | recurse_to_leaf = |
534 | rule->steps[step].op == | 547 | rule->steps[step].op == |
@@ -597,7 +610,9 @@ int crush_do_rule(const struct crush_map *map, | |||
597 | break; | 610 | break; |
598 | 611 | ||
599 | default: | 612 | default: |
600 | BUG_ON(1); | 613 | dprintk(" unknown op %d at step %d\n", |
614 | curstep->op, step); | ||
615 | break; | ||
601 | } | 616 | } |
602 | } | 617 | } |
603 | return result_len; | 618 | return result_len; |