post_event(RequestPrimaryScanning{});
return;
} else {
- if (backfill_state().progress_tracker->tracked_objects_completed()
+ if (backfill_state().progress_tracker->tracked_pushes_completed()
&& Enqueuing::all_enqueued(peering_state(),
backfill_state().backfill_info,
backfill_state().peer_backfill_info)) {
+ backfill_state().progress_tracker->complete_drops();
backfill_state().last_backfill_started = hobject_t::get_max();
backfill_listener().update_peers_last_backfill(hobject_t::get_max());
}
{
[[maybe_unused]] const auto [it, first_seen] = registry.try_emplace(
obj, registry_item_t{op_stage_t::enqueued_push, std::nullopt});
+ if (first_seen) {
+ // multiple targets may enqueue the same object; only count it once
+ ++num_pending_pushes;
+ }
return first_seen;
}
DEBUGDPP("obj={}", pg(), obj);
if (auto completion_iter = registry.find(obj);
completion_iter != std::end(registry)) {
+ if (completion_iter->second.stage == op_stage_t::enqueued_push) {
+ ceph_assert(num_pending_pushes > 0);
+ --num_pending_pushes;
+ }
completion_iter->second = \
registry_item_t{ op_stage_t::completed_push, stats };
} else {
}
}
+void BackfillState::ProgressTracker::complete_drops()
+{
+ LOG_PREFIX(BackfillState::ProgressTracker::complete_drops);
+ ceph_assert(num_pending_pushes == 0);
+ auto new_last_backfill = peering_state().earliest_backfill();
+ for (auto it = std::begin(registry);
+ it != std::end(registry);
+ it = registry.erase(it)) {
+ const auto& [soid, item] = *it;
+ ceph_assert(item.stage == op_stage_t::enqueued_drop);
+ assert(item.stats);
+ DEBUGDPP("draining drop obj={}", pg(), soid);
+ peering_state().update_complete_backfill_object_stats(
+ soid,
+ *item.stats);
+ assert(soid > new_last_backfill);
+ new_last_backfill = soid;
+ }
+ backfill_listener().update_peers_last_backfill(new_last_backfill);
+}
+
void BackfillState::enqueue_standalone_push(
const hobject_t &obj,
const eversion_t &v,
BackfillMachine& backfill_machine;
std::map<hobject_t, registry_item_t> registry;
+ // count of registry entries at enqueued_push stage, awaiting ObjectPushed.
+ size_t num_pending_pushes = 0;
BackfillState& backfill_state() {
return backfill_machine.backfill_state;
bool tracked_objects_completed() const;
+ // true when no push operations are awaiting ObjectPushed completion.
+ bool tracked_pushes_completed() const {
+ return num_pending_pushes == 0;
+ }
+
bool enqueue_push(const hobject_t&);
void enqueue_drop(const hobject_t&);
void complete_to(const hobject_t&, const pg_stat_t&, bool may_push_to_max);
+
+ // drain all remaining drop entries from the registry, updating stats.
+ void complete_drops();
};
} // namespace crimson::osd