]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
rgw/datalog: DataLogBackends::trim_entries: fix crash when target_gen > head_gen 69113/head
authorOguzhan Ozmen <oozmen@bloomberg.net>
Tue, 19 May 2026 22:12:35 +0000 (22:12 +0000)
committerOguzhan Ozmen <oozmen@bloomberg.net>
Tue, 26 May 2026 19:09:04 +0000 (19:09 +0000)
When a cluster has no sync zones (single-zone), DataLogTrimCR passes
max_marker() as the trim marker, which encodes target_gen = UINT64_MAX
from gencursor(). In DataLogBackends::trim_entries, after trimming the
head (last) generation, the break condition

    if (be->gen_id == target_gen)

is false (e.g. 0 != UINT64_MAX), so the loop attempts its increment
expression:

    be = upper_bound(be->gen_id)->second

upper_bound(head_gen) returns end(), and dereferencing end()->second
causes crash.

Fix: also break when be->gen_id >= head_gen. Once we've trimmed the
head generation there are no further backends in the map, so the
upper_bound dereference in the loop increment will be skipped.

This is a general bug that affects any cluster using max_marker() as a
trim target (i.e. every single-zone deployment).

Signed-off-by: Oguzhan Ozmen <oozmen@bloomberg.net>
(cherry picked from commit 61b6d72226072d8eae791909b066471ce42d746c)

src/rgw/driver/rados/rgw_datalog.cc
src/test/rgw/test_datalog.cc

index dce254c364111c7256d33a42f58e4b35944bd085..696c2e6af582a3f414e3b00d61365b12586dea5b 100644 (file)
@@ -1183,7 +1183,7 @@ asio::awaitable<void> DataLogBackends::trim_entries(
     l.unlock();
     auto c = be->gen_id == target_gen ? cursor : be->max_marker();
     co_await be->trim(dpp, shard_id, c);
-    if (be->gen_id == target_gen)
+    if (be->gen_id == target_gen || be->gen_id >= head_gen)
       break;
     l.lock();
   };
index 15f2b40e37e21a968bbdb99a85e0de42f95cd340..680d0637424307737a55d4454bfe21966466eb8a 100644 (file)
@@ -442,8 +442,6 @@ CORO_TEST_F(DataLogBulky, BulkyCycleRecovery, DataLogBulky) {
 }
 
 // trim_entries with max_marker() must not crash on a single-generation cluster.
-// Without the fix, the loop increment would call upper_bound(head_gen)->second,
-// dereferencing end() and causing a SIGSEGV.
 CORO_TEST_F(DataLogBulky, TrimWithMaxMarker, DataLogBulky) {
   for (const auto& bg : bulky) {
     co_await add_entry(dpp(), bg);