From 77702576e3dac1ec2c759cf2fea90194d1dd697f Mon Sep 17 00:00:00 2001 From: Alex Ainscow Date: Fri, 3 Oct 2025 15:32:22 +0100 Subject: [PATCH] osdc: Add stub for ability to force an op to always go to a particular shard This will eventually be used by SplitIo to direct ops to the correct OSD. Signed-off-by: Alex Ainscow --- src/osdc/Objecter.cc | 19 +++++++++++++++---- src/osdc/Objecter.h | 1 + 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/src/osdc/Objecter.cc b/src/osdc/Objecter.cc index 0db2ba28473..9218f9de5ab 100644 --- a/src/osdc/Objecter.cc +++ b/src/osdc/Objecter.cc @@ -3081,7 +3081,18 @@ int Objecter::_calc_target(op_target_t *t, bool any_change) t->pg_num_mask = pg_num_mask; t->pg_num_pending = pg_num_pending; spg_t spgid(actual_pgid); - if (pi->is_erasure()) { + if (t->force_shard) { + t->osd = t->acting[int(*t->force_shard)]; + // In some redrive scenarios, the acting set can change. Fail the IO + // and retry. + if (!osdmap->exists(t->osd)) { + t->osd = -1; + return RECALC_OP_TARGET_POOL_DNE; + } + if (pi->is_erasure()) { + spgid.reset_shard(osdmap->pgtemp_undo_primaryfirst(*pi, actual_pgid, *t->force_shard)); + } + } else 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 @@ -3110,7 +3121,7 @@ int Objecter::_calc_target(op_target_t *t, bool any_change) << " acting " << t->acting << " primary " << acting_primary << dendl; t->used_replica = false; - if ((t->flags & (CEPH_OSD_FLAG_BALANCE_READS | + if (!t->force_shard && (t->flags & (CEPH_OSD_FLAG_BALANCE_READS | CEPH_OSD_FLAG_LOCALIZE_READS)) && !is_write && pi->is_replicated() && t->acting.size() > 1) { int osd; @@ -3147,7 +3158,7 @@ int Objecter::_calc_target(op_target_t *t, bool any_change) osd = t->acting[best]; } t->osd = osd; - } else { + } else if (!t->force_shard) { t->osd = acting_primary; } } @@ -3710,7 +3721,7 @@ void Objecter::handle_osd_op_reply(MOSDOpReply *m) } } - if (rc == -EAGAIN) { + if (rc == -EAGAIN && !op->target.force_shard) { ldout(cct, 7) << " got -EAGAIN, resubmitting" << dendl; if (op->has_completion()) num_in_flight--; diff --git a/src/osdc/Objecter.h b/src/osdc/Objecter.h index 416bc6975d6..0772acd7014 100644 --- a/src/osdc/Objecter.h +++ b/src/osdc/Objecter.h @@ -1874,6 +1874,7 @@ public: bool paused = false; int osd = -1; ///< the final target osd, or -1 + std::optional force_shard; // If set, only this shard may be used. epoch_t last_force_resend = 0; -- 2.39.5