// force a change of primary shard - do not remove pg_temp
// if it is being used for this purpose
if (pool->allows_ecoptimizations()) {
- for (uint8_t i = 0; i < acting_set.size(); ++i) {
- if (acting_set[i] == primary) {
- if (pool->is_nonprimary_shard(shard_id_t(i))) {
- // pg_temp still required
- keep = true;
- }
- }
+ if (nextmap._pick_primary(pg.second) != primary) {
+ // pg_temp still required
+ keep = true;
}
}
if (!keep) {
// Only perform the transform for pools with allow_ec_optimizations set
// that also have pg_temp set
if (pool.allows_ecoptimizations()) {
- if (pg_temp->find(pool.raw_pg_to_pg(pg)) != pg_temp->end()) {
+ if (has_pgtemp(pool.raw_pg_to_pg(pg))) {
std::vector<int> result;
int primaryshard = 0;
int nonprimaryshard = pool.size - pool.nonprimary_shards.size();
}
shard_id_t result = shard;
if (pool.allows_ecoptimizations()) {
- if (pg_temp->find(pool.raw_pg_to_pg(pg)) != pg_temp->end()) {
+ if (has_pgtemp(pool.raw_pg_to_pg(pg))) {
int num_parity_shards = pool.size - pool.nonprimary_shards.size() - 1;
if (shard >= pool.size - num_parity_shards) {
result = shard_id_t(result + num_parity_shards + 1 - pool.size);
}
shard_id_t result = shard;
if (pool.allows_ecoptimizations()) {
- if (pg_temp->find(pool.raw_pg_to_pg(pg)) != pg_temp->end()) {
+ if (has_pgtemp(pool.raw_pg_to_pg(pg))) {
int num_parity_shards = pool.size - pool.nonprimary_shards.size() - 1;
if (shard > num_parity_shards) {
result = shard_id_t(result - num_parity_shards);
void OSDMap::_get_temp_osds(const pg_pool_t& pool, pg_t pg,
vector<int> *temp_pg, int *temp_primary) const
{
+ vector<int> temp;
pg = pool.raw_pg_to_pg(pg);
const auto p = pg_temp->find(pg);
temp_pg->clear();
if (pool.can_shift_osds()) {
continue;
} else {
- temp_pg->push_back(CRUSH_ITEM_NONE);
+ temp.push_back(CRUSH_ITEM_NONE);
}
} else {
- temp_pg->push_back(p->second[i]);
+ temp.push_back(p->second[i]);
}
}
+ *temp_pg = pgtemp_undo_primaryfirst(pool, pg, temp);
}
const auto &pp = primary_temp->find(pg);
*temp_primary = -1;
if (pp != primary_temp->end()) {
*temp_primary = pp->second;
- } else if (!temp_pg->empty()) { // apply pg_temp's primary
- for (unsigned i = 0; i < temp_pg->size(); ++i) {
- if ((*temp_pg)[i] != CRUSH_ITEM_NONE) {
- *temp_primary = (*temp_pg)[i];
+ } else if (!temp.empty()) { // apply pg_temp's primary
+ for (unsigned i = 0; i < temp.size(); ++i) {
+ if (temp[i] != CRUSH_ITEM_NONE) {
+ *temp_primary = temp[i];
break;
}
}
int newupprimary,
int newactingprimary,
const vector<int>& newup,
- const vector<int>& _newacting,
+ const vector<int>& newacting,
OSDMapRef lastmap,
OSDMapRef osdmap)
{
- const vector<int> newacting = osdmap->pgtemp_undo_primaryfirst(
- pool.info,
- info.pgid.pgid,
- _newacting);
if (PastIntervals::is_new_interval(
primary.osd,
newactingprimary,
int new_acting_primary)
{
actingset.clear();
- acting = get_osdmap()->pgtemp_undo_primaryfirst(pool.info,
- info.pgid.pgid,
- newacting);
+ acting = newacting;
for (uint8_t i = 0; i < acting.size(); ++i) {
if (acting[i] != CRUSH_ITEM_NONE)
actingset.insert(
break;
}
}
+ // Calcuating the shard of the acting_primary is tricky because in
+ // error conditions the same osd can be in multiple positions in
+ // the acting_set. Use pgtemp ordering (which places shards which
+ // can become the primary first) to match the code in
+ // OSDMap::_get_temp_osds
+ const OSDMapRef osdmap = get_osdmap();
+ bool has_pgtemp = osdmap->has_pgtemp(spgid.pgid);
+ std::vector<int> pg_temp = acting;
+ if (has_pgtemp) {
+ pg_temp = osdmap->pgtemp_primaryfirst(pool.info, acting);
+ }
for (uint8_t i = 0; i < acting.size(); ++i) {
- if (acting[i] == new_acting_primary) {
- primary = pg_shard_t(acting[i], shard_id_t(i));
+ if (pg_temp[i] == new_acting_primary) {
+ if (has_pgtemp) {
+ primary = pg_shard_t(new_acting_primary,
+ osdmap->pgtemp_undo_primaryfirst(
+ pool.info, spgid.pgid, shard_id_t(i)));
+ } else {
+ primary = pg_shard_t(new_acting_primary, shard_id_t(i));
+ }
break;
}
}