pg->osd->local_reserver.cancel_reservation(pg->info.pgid);
pg->state_set(PG_STATE_BACKFILL_TOOFULL);
+ for (set<pg_shard_t>::iterator it = pg->backfill_targets.begin();
+ it != pg->backfill_targets.end();
+ ++it) {
+ assert(*it != pg->pg_whoami);
+ ConnectionRef con = pg->osd->get_con_osd_cluster(
+ it->osd, pg->get_osdmap()->get_epoch());
+ if (con) {
+ if (con->has_feature(CEPH_FEATURE_BACKFILL_RESERVATION)) {
+ pg->osd->send_message_osd_cluster(
+ new MBackfillReserve(
+ MBackfillReserve::REJECT,
+ spg_t(pg->info.pgid.pgid, it->shard),
+ pg->get_osdmap()->get_epoch()),
+ con.get());
+ }
+ }
+ }
+
pg->osd->recovery_wq.dequeue(pg);
+ pg->waiting_on_backfill.clear();
+ pg->finish_recovery_op(hobject_t::get_max());
+
pg->schedule_backfill_full_retry();
return transit<NotBackfilling>();
}
{
PG *pg = context< RecoveryMachine >().pg;
pg->reject_reservation();
- return transit<RepNotRecovering>();
+ return discard_event();
}
void PG::RecoveryState::RepRecovering::exit()
}
peer_backfill_info[from] = bi;
- assert(waiting_on_backfill.find(from) != waiting_on_backfill.end());
- waiting_on_backfill.erase(from);
+ if (waiting_on_backfill.find(from) != waiting_on_backfill.end()) {
+ waiting_on_backfill.erase(from);
- if (waiting_on_backfill.empty()) {
- assert(peer_backfill_info.size() == backfill_targets.size());
- finish_recovery_op(hobject_t::get_max());
+ if (waiting_on_backfill.empty()) {
+ assert(peer_backfill_info.size() == backfill_targets.size());
+ finish_recovery_op(hobject_t::get_max());
+ }
+ } else {
+ // we canceled backfill for a while due to a too full, and this
+ // is an extra response from a non-too-full peer
}
}
break;