From dff0dd4222b148a5de741abd8db02c8f67ed7a89 Mon Sep 17 00:00:00 2001 From: Bill Scales Date: Wed, 25 Jun 2025 10:26:17 +0100 Subject: [PATCH] osdc: Optimized EC pools routing bug Fix bug with routing to an acting set like [None,Y,X,X]p(X) for a 3+1 optimzed pool where osd X is representing more than one shard. For an optimized EC pool we want it to choose shard 3 because shard 2 is a non-primary. If we just search the acting set for the first OSD that matches X this will pick shard 2, so we have to convert the order to primary's first, then find the matching OSD and then convert this back to the normal ordering to get shard 3. Signed-off-by: Bill Scales (cherry picked from commit 3310f97859109090706b84824cac2f8a6cfe6928) --- src/osdc/Objecter.cc | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/osdc/Objecter.cc b/src/osdc/Objecter.cc index 4fb94549242..893a3fb2c7e 100644 --- a/src/osdc/Objecter.cc +++ b/src/osdc/Objecter.cc @@ -3022,8 +3022,16 @@ int Objecter::_calc_target(op_target_t *t, Connection *con, bool any_change) t->pg_num_pending = pg_num_pending; spg_t spgid(actual_pgid); if (pi->is_erasure()) { + // Optimized EC pools need to be careful when calculating the shard + // because an OSD may have multiple shards and the primary shard + // might not be the first one in the acting set. The lookup + // therefoere has to be done in primaryfirst order. + std::vector pg_temp = t->acting; + if (osdmap->has_pgtemp(actual_pgid)) { + pg_temp = osdmap->pgtemp_primaryfirst(*pi, t->acting); + } for (uint8_t i = 0; i < t->acting.size(); ++i) { - if (t->acting[i] == acting_primary) { + if (pg_temp[i] == acting_primary) { spgid.reset_shard(osdmap->pgtemp_undo_primaryfirst(*pi, actual_pgid, shard_id_t(i))); break; } -- 2.39.5