aboutsummaryrefslogtreecommitdiff
path: root/net/ceph/osdmap.c
diff options
context:
space:
mode:
authorAndy Shevchenko2017-11-03 13:50:41 +0200
committerAndy Shevchenko2017-11-03 13:50:41 +0200
commit7d9a6ef558f6ff375aab9e29f08124cb0daa9bc5 (patch)
tree3916e6cf9678a41081ae822ef67ec5cae1c1fffa /net/ceph/osdmap.c
parent3fcf2b2a2529e268c537d8ad9dac5987ebc8a2f7 (diff)
parent0224d45c9d46401b6d7018a96cfe049c5da7d91c (diff)
Merge branch 'i2c/cht-wc-fusb302-immutable' of git://git.kernel.org/pub/scm/linux/kernel/git/wsa/linux
Pull i2c/cht-wc-fusb302-immutable immutable branch from Wolfram Sang: as discussed before, here is the immutable branch for the i2c-cht-wc driver, so you can safely apply Hans' patch [1] "platform/x86: intel_cht_int33fe: Update fusb302 type string, add properties" on top of this. [1] http://patchwork.ozlabs.org/patch/824314/
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,
pg = lookup_pg_mapping(&osdmap->pg_upmap_items, pgid);
if (pg) {
- for (i = 0; i < raw->size; i++) {
- for (j = 0; j < pg->pg_upmap_items.len; j++) {
- int from = pg->pg_upmap_items.from_to[j][0];
- int to = pg->pg_upmap_items.from_to[j][1];
-
- if (from == raw->osds[i]) {
- if (!(to != CRUSH_ITEM_NONE &&
- to < osdmap->max_osd &&
- osdmap->osd_weight[to] == 0))
- raw->osds[i] = to;
+ /*
+ * Note: this approach does not allow a bidirectional swap,
+ * e.g., [[1,2],[2,1]] applied to [0,1,2] -> [0,2,1].
+ */
+ for (i = 0; i < pg->pg_upmap_items.len; i++) {
+ int from = pg->pg_upmap_items.from_to[i][0];
+ int to = pg->pg_upmap_items.from_to[i][1];
+ int pos = -1;
+ bool exists = false;
+
+ /* make sure replacement doesn't already appear */
+ for (j = 0; j < raw->size; j++) {
+ int osd = raw->osds[j];
+
+ if (osd == to) {
+ exists = true;
break;
}
+ /* ignore mapping if target is marked out */
+ if (osd == from && pos < 0 &&
+ !(to != CRUSH_ITEM_NONE &&
+ to < osdmap->max_osd &&
+ osdmap->osd_weight[to] == 0)) {
+ pos = j;
+ }
}
+ if (!exists && pos >= 0)
+ raw->osds[pos] = to;
}
}
}