in_progress.reset();
}
+ /// Flush all pending writes/removals into a Transaction, then reset.
+ /// This ensures in-flight cached state is persisted before the cache
+ /// is cleared (e.g. on PG interval change).
+ void flush_and_reset(Transaction<K, V> *t) {
+ std::map<K, V> to_set;
+ std::set<K> to_remove;
+ K key{};
+ std::pair<K, boost::optional<V>> cached;
+ while (in_progress.get_next(key, &cached)) {
+ if (cached.second) {
+ to_set[cached.first] = cached.second.get();
+ } else {
+ to_remove.insert(cached.first);
+ }
+ key = cached.first;
+ }
+ if (!to_set.empty()) {
+ t->set_keys(to_set);
+ }
+ if (!to_remove.empty()) {
+ t->remove_keys(to_remove);
+ }
+ in_progress.reset();
+ }
+
/// Fetch first key/value std::pair after specified key
int get_next(
K key, ///< [in] key after which to get next
// is save and in time.
peering_state.state_clear(PG_STATE_SNAPTRIM);
peering_state.state_clear(PG_STATE_SNAPTRIM_ERROR);
- snap_mapper.reset_backend();
+ auto _t = osdriver.get_transaction(&t);
+ snap_mapper.flush_and_reset_backend(&_t);
reset_pglog_based_recovery_op();
}
return prefix_itr;
}
- /// reset the MapCacher backend, this should be called on pg interval change
- void reset_backend() {
- backend.reset();
+ /// Flush pending snap-mapper writes into the provided transaction,
+ /// then reset the MapCacher backend. This should be called on pg
+ /// interval change to ensure in-flight snap-mapper state is persisted
+ /// before the cache is cleared.
+ void flush_and_reset_backend(
+ MapCacher::Transaction<std::string, ceph::buffer::list> *t) {
+ backend.flush_and_reset(t);
}
/// Update snaps for oid, empty new_snaps removes the mapping