]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
crimson/os/seastore/lba_manager: add scan_mapped_space
authorXuehan Xu <xuxuehan@qianxin.com>
Wed, 17 Dec 2025 07:49:17 +0000 (15:49 +0800)
committerXuehan Xu <xuxuehan@qianxin.com>
Fri, 16 Jan 2026 08:32:05 +0000 (16:32 +0800)
Signed-off-by: Xuehan Xu <xuxuehan@qianxin.com>
src/crimson/os/seastore/btree/fixed_kv_btree.h
src/crimson/os/seastore/lba/btree_lba_manager.cc
src/crimson/os/seastore/lba/btree_lba_manager.h
src/crimson/os/seastore/lba_manager.h

index cb3624ba2daf92a3165bd41b0a66c8751c1b1450..15849be4cd08d06f2891ace0c98d1432e78f0ef9 100644 (file)
@@ -8,6 +8,7 @@
 #include <memory>
 #include <string.h>
 
+#include "crimson/common/coroutine.h"
 #include "crimson/os/seastore/logging.h"
 
 #include "crimson/os/seastore/cache.h"
@@ -2362,6 +2363,13 @@ private:
 template <typename T>
 struct is_fixed_kv_tree : std::false_type {};
 
+template <typename tree_type_t>
+Cache::get_root_iertr::future<tree_type_t>
+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,
index 9da688d6652fcd058ebb5139165f700e0e9e4eb3..8bc4d6d1adf8b1c483bafdc85601d6aa5fd445bd 100644 (file)
@@ -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<LBABtree>(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,
index d2b460ca62ecc026851f840c368f3c82fc72b672..97d7c43a300f7d8ed1ea6baa1f5da8bb9c8046f9 100644 (file)
@@ -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;
 
index 33b9facada13f36153d7f92f3ba829fe4fd59055..49182d6edcd40a2292436e2c5e986b97d415a95e 100644 (file)
@@ -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<LBAManager>;