]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
crimson/osd/snap-mapper: flush pending writes on pg interval change 68796/head
authorRonen Friedman <rfriedma@redhat.com>
Thu, 7 May 2026 10:06:28 +0000 (10:06 +0000)
committerRonen Friedman <rfriedma@redhat.com>
Sun, 10 May 2026 13:32:44 +0000 (13:32 +0000)
When a PG interval changes, the snap-mapper's MapCacher backend is
reset to clear any stale state. This change adds a flush-and-reset
method that first flushes any pending writes in the MapCacher into the
objectstore, then resets the backend.

Fixes: https://tracker.ceph.com/issues/76458
Signed-off-by: Ronen Friedman <rfriedma@redhat.com>
src/common/map_cacher.hpp
src/crimson/osd/pg.cc
src/osd/SnapMapper.h

index 3952cf9bb7517840058c4d2aa613609a50bafdf6..ad75c3f52cccae22d60472d72e93354deb797274 100644 (file)
@@ -96,6 +96,31 @@ public:
     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
index bf3ea70d157b27dea6fb5ddc07868986bc83bd00..8c51956e425802801b4d9a3ea8d327c0bdb46e07 100644 (file)
@@ -1701,7 +1701,8 @@ void PG::on_change(ceph::os::Transaction &t) {
   // 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();
 }
 
index c7cab0c344012aeca396b3e6eb6cd9f8f46ee903..8ff9bf3c6c280767554da4adeab5d3553f6fb235 100644 (file)
@@ -337,9 +337,13 @@ private:
     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