]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
crimson/os/seastore: fix cleaner space leak from shadowed result list 68949/head
authorShai Fultheim <shai.fultheim@gmail.com>
Sat, 16 May 2026 20:17:59 +0000 (23:17 +0300)
committerShai Fultheim <shai.fultheim@gmail.com>
Sat, 16 May 2026 21:42:44 +0000 (00:42 +0300)
TransactionManager::get_extents_if_live() declared an inner
std::list<CachedExtentRef> res inside the "extent is cached" branch
that shadowed the outer res returned by the coroutine. When the
queried extent was present in the cache, it was moved into the inner
list and immediately discarded, and the empty outer list was returned
to the caller.

The async cleaner uses this result to decide whether to rewrite an
extent or treat it as dead. For recently-allocated LBA tree internal
nodes (still hot in cache), the shadowed return caused the cleaner to
skip them, so mark_space_free() never paired with the earlier
mark_space_used(). Each affected reclaim leaked exactly one extent
(4 KiB for LADDR_INTERNAL), tripping the live_bytes != 0 assertion in
SegmentCleaner::clean_space() (async_cleaner.cc:1441) once a victim
segment with such a leftover was selected.

The reproducer (at ~70% full) deterministically aborted within ~3
minutes before this fix; with the fix the OSDs run cleanly past the
trigger point.

Fixes: 87a5984b3ae ("crimson/.../transaction_manager: convert get_extents_if_live to coroutine")
Signed-off-by: Shai Fultheim <shai.fultheim@gmail.com>
src/crimson/os/seastore/transaction_manager.cc

index de8b62cb3c49ae3b3e9759ebec0ee9aab88b2e4f..147a2c48b7ffa26001ed4dfede5752c3d910a42e 100644 (file)
@@ -827,7 +827,6 @@ TransactionManager::get_extents_if_live(
     DEBUGT("{} {}~0x{:x} {} is cached and alive -- {}",
           t, type, laddr, len, paddr, *extent);
     assert(extent->get_length() == len);
-    std::list<CachedExtentRef> res;
     res.emplace_back(std::move(extent));
   } else if (is_logical_type(type)) {
     auto pin_list = co_await lba_manager->get_cursors(