diff options
Diffstat (limited to 'net/ceph/osdmap.c')
-rw-r--r-- | net/ceph/osdmap.c | 35 |
1 files changed, 25 insertions, 10 deletions
diff --git a/net/ceph/osdmap.c b/net/ceph/osdmap.c index f358d0bfa76b..79d14d70b7ea 100644 --- a/net/ceph/osdmap.c +++ b/net/ceph/osdmap.c | |||
@@ -2445,19 +2445,34 @@ static void apply_upmap(struct ceph_osdmap *osdmap, | |||
2445 | 2445 | ||
2446 | pg = lookup_pg_mapping(&osdmap->pg_upmap_items, pgid); | 2446 | pg = lookup_pg_mapping(&osdmap->pg_upmap_items, pgid); |
2447 | if (pg) { | 2447 | if (pg) { |
2448 | for (i = 0; i < raw->size; i++) { | 2448 | /* |
2449 | for (j = 0; j < pg->pg_upmap_items.len; j++) { | 2449 | * Note: this approach does not allow a bidirectional swap, |
2450 | int from = pg->pg_upmap_items.from_to[j][0]; | 2450 | * e.g., [[1,2],[2,1]] applied to [0,1,2] -> [0,2,1]. |
2451 | int to = pg->pg_upmap_items.from_to[j][1]; | 2451 | */ |
2452 | 2452 | for (i = 0; i < pg->pg_upmap_items.len; i++) { | |
2453 | if (from == raw->osds[i]) { | 2453 | int from = pg->pg_upmap_items.from_to[i][0]; |
2454 | if (!(to != CRUSH_ITEM_NONE && | 2454 | int to = pg->pg_upmap_items.from_to[i][1]; |
2455 | to < osdmap->max_osd && | 2455 | int pos = -1; |
2456 | osdmap->osd_weight[to] == 0)) | 2456 | bool exists = false; |
2457 | raw->osds[i] = to; | 2457 | |
2458 | /* make sure replacement doesn't already appear */ | ||
2459 | for (j = 0; j < raw->size; j++) { | ||
2460 | int osd = raw->osds[j]; | ||
2461 | |||
2462 | if (osd == to) { | ||
2463 | exists = true; | ||
2458 | break; | 2464 | break; |
2459 | } | 2465 | } |
2466 | /* ignore mapping if target is marked out */ | ||
2467 | if (osd == from && pos < 0 && | ||
2468 | !(to != CRUSH_ITEM_NONE && | ||
2469 | to < osdmap->max_osd && | ||
2470 | osdmap->osd_weight[to] == 0)) { | ||
2471 | pos = j; | ||
2472 | } | ||
2460 | } | 2473 | } |
2474 | if (!exists && pos >= 0) | ||
2475 | raw->osds[pos] = to; | ||
2461 | } | 2476 | } |
2462 | } | 2477 | } |
2463 | } | 2478 | } |