aboutsummaryrefslogtreecommitdiffstats
path: root/net/ceph/osdmap.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/ceph/osdmap.c')
-rw-r--r--net/ceph/osdmap.c35
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}