@@ -3099,7 +3099,18 @@ int Objecter::_calc_target(op_target_t *t, bool any_change)
30993099 t->pg_num_mask = pg_num_mask;
31003100 t->pg_num_pending = pg_num_pending;
31013101 spg_t spgid (actual_pgid);
3102- if (pi->is_erasure ()) {
3102+ if (t->force_shard ) {
3103+ t->osd = t->acting [int (*t->force_shard )];
3104+ // In some redrive scenarios, the acting set can change. Fail the IO
3105+ // and retry.
3106+ if (!osdmap->exists (t->osd )) {
3107+ t->osd = -1 ;
3108+ return RECALC_OP_TARGET_POOL_DNE;
3109+ }
3110+ if (pi->is_erasure ()) {
3111+ spgid.reset_shard (osdmap->pgtemp_undo_primaryfirst (*pi, actual_pgid, *t->force_shard ));
3112+ }
3113+ } else if (pi->is_erasure ()) {
31033114 // Optimized EC pools need to be careful when calculating the shard
31043115 // because an OSD may have multiple shards and the primary shard
31053116 // might not be the first one in the acting set. The lookup
@@ -3128,7 +3139,7 @@ int Objecter::_calc_target(op_target_t *t, bool any_change)
31283139 << " acting " << t->acting
31293140 << " primary " << acting_primary << dendl;
31303141 t->used_replica = false ;
3131- if ((t->flags & (CEPH_OSD_FLAG_BALANCE_READS |
3142+ if (!t-> force_shard && (t->flags & (CEPH_OSD_FLAG_BALANCE_READS |
31323143 CEPH_OSD_FLAG_LOCALIZE_READS)) &&
31333144 !is_write && pi->is_replicated () && t->acting .size () > 1 ) {
31343145 int osd;
@@ -3165,7 +3176,7 @@ int Objecter::_calc_target(op_target_t *t, bool any_change)
31653176 osd = t->acting [best];
31663177 }
31673178 t->osd = osd;
3168- } else {
3179+ } else if (!t-> force_shard ) {
31693180 t->osd = acting_primary;
31703181 }
31713182 }
@@ -3728,7 +3739,7 @@ void Objecter::handle_osd_op_reply(MOSDOpReply *m)
37283739 }
37293740 }
37303741
3731- if (rc == -EAGAIN) {
3742+ if (rc == -EAGAIN && !op-> target . force_shard ) {
37323743 ldout (cct, 7 ) << " got -EAGAIN, resubmitting" << dendl;
37333744 if (op->has_completion ())
37343745 num_in_flight--;
0 commit comments