From: Xuehan Xu Date: Wed, 17 Dec 2025 07:49:17 +0000 (+0800) Subject: crimson/os/seastore/lba_manager: add scan_mapped_space X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=56dc9cd1682b20285282145dab3692ebdd2b3286;p=ceph.git crimson/os/seastore/lba_manager: add scan_mapped_space Signed-off-by: Xuehan Xu --- diff --git a/src/crimson/os/seastore/btree/fixed_kv_btree.h b/src/crimson/os/seastore/btree/fixed_kv_btree.h index cb3624ba2daf..15849be4cd08 100644 --- a/src/crimson/os/seastore/btree/fixed_kv_btree.h +++ b/src/crimson/os/seastore/btree/fixed_kv_btree.h @@ -8,6 +8,7 @@ #include #include +#include "crimson/common/coroutine.h" #include "crimson/os/seastore/logging.h" #include "crimson/os/seastore/cache.h" @@ -2362,6 +2363,13 @@ private: template struct is_fixed_kv_tree : std::false_type {}; +template +Cache::get_root_iertr::future +get_btree(op_context_t c) { + auto cache_root = co_await c.cache.get_root(c.trans); + co_return tree_type_t(cache_root); +} + template < typename node_key_t, typename node_val_t, diff --git a/src/crimson/os/seastore/lba/btree_lba_manager.cc b/src/crimson/os/seastore/lba/btree_lba_manager.cc index 9da688d6652f..8bc4d6d1adf8 100644 --- a/src/crimson/os/seastore/lba/btree_lba_manager.cc +++ b/src/crimson/os/seastore/lba/btree_lba_manager.cc @@ -1187,6 +1187,59 @@ BtreeLBAManager::_update_mapping( }); } +BtreeLBAManager::scan_mapped_space_ret +BtreeLBAManager::scan_mapped_space( + Transaction &t, + BtreeLBAManager::scan_mapped_space_func_t &&f) +{ + LOG_PREFIX(BtreeLBAManager::scan_mapped_space); + DEBUGT("scan lba tree", t); + auto c = get_context(t); + auto scan_visitor = std::move(f); + auto btree = co_await get_btree(c); + auto block_size = cache.get_block_size(); + auto pos = co_await btree.lower_bound(c, L_ADDR_MIN); + while (!pos.is_end()) { + if (pos.get_val().pladdr.is_laddr() || + pos.get_val().pladdr.get_paddr().is_zero()) { + pos = co_await pos.next(c); + continue; + } + TRACET("tree value {}~{} {}~{} used", + c.trans, + pos.get_key(), + pos.get_val().len, + pos.get_val().pladdr.get_paddr(), + pos.get_val().len); + ceph_assert(pos.get_val().len > 0 && + pos.get_val().len % block_size == 0); + ceph_assert(pos.get_val().pladdr != L_ADDR_NULL); + scan_visitor( + pos.get_val().pladdr.get_paddr(), + pos.get_val().len, + extent_types_t::NONE, + pos.get_key()); + pos = co_await pos.next(c); + } + + LBABtree::mapped_space_visitor_t tree_visitor = + [&scan_visitor, block_size, FNAME, c]( + paddr_t paddr, laddr_t key, extent_len_t len, + depth_t depth, extent_types_t type, LBABtree::iterator&) { + TRACET("tree node {}~{} {}, depth={} used", + c.trans, paddr, len, type, depth); + ceph_assert(paddr.is_absolute()); + ceph_assert(len > 0 && len % block_size == 0); + ceph_assert(depth >= 1); + return scan_visitor(paddr, len, type, key); + }; + + pos = co_await btree.lower_bound(c, L_ADDR_MIN, &tree_visitor); + while (!pos.is_end()) { + pos = co_await pos.next(c, &tree_visitor); + } +} + BtreeLBAManager::_get_cursor_ret BtreeLBAManager::get_containing_cursor( op_context_t c, diff --git a/src/crimson/os/seastore/lba/btree_lba_manager.h b/src/crimson/os/seastore/lba/btree_lba_manager.h index d2b460ca62ec..97d7c43a300f 100644 --- a/src/crimson/os/seastore/lba/btree_lba_manager.h +++ b/src/crimson/os/seastore/lba/btree_lba_manager.h @@ -358,6 +358,10 @@ public: Transaction &t, LBAMapping mapping) final; + scan_mapped_space_ret scan_mapped_space( + Transaction &t, + scan_mapped_space_func_t &&f) final; + private: Cache &cache; diff --git a/src/crimson/os/seastore/lba_manager.h b/src/crimson/os/seastore/lba_manager.h index 33b9facada13..49182d6edcd4 100644 --- a/src/crimson/os/seastore/lba_manager.h +++ b/src/crimson/os/seastore/lba_manager.h @@ -338,6 +338,21 @@ public: Transaction &t, LBAMapping mapping) = 0; + /* + * scan all extents in the tree, including logical extents + * and lba extents, visit them with scan_mapped_space_func_t. + * + * Note that it's only when both the main and secondary devices + * are RBMs that this method can be used to scan the disk space + */ + using scan_mapped_space_iertr = base_iertr; + using scan_mapped_space_ret = scan_mapped_space_iertr::future<>; + using scan_mapped_space_func_t = std::function< + void(paddr_t, extent_len_t, extent_types_t, laddr_t)>; + virtual scan_mapped_space_ret scan_mapped_space( + Transaction &t, + scan_mapped_space_func_t &&f) = 0; + virtual ~LBAManager() {} }; using LBAManagerRef = std::unique_ptr;