]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
crimson/os/seastore/linked_tree_node: add get_parent_node for retrieving
authorXuehan Xu <xuxuehan@qianxin.com>
Wed, 23 Apr 2025 03:40:14 +0000 (11:40 +0800)
committerXuehan Xu <xuxuehan@qianxin.com>
Tue, 1 Jul 2025 07:36:37 +0000 (15:36 +0800)
accessible parents

Signed-off-by: Xuehan Xu <xuxuehan@qianxin.com>
src/crimson/os/seastore/linked_tree_node.h

index 809268d8a61310f61a33dec2a44768548bbc95f1..2dd152b07e766b356b34e6429ad2e29710c5ed6c 100644 (file)
@@ -304,27 +304,15 @@ class ParentNode {
    *   cannot be rewritten) because their parents must be mutated upon remapping.
    */
 public:
-  TCachedExtentRef<T> find_pending_version(Transaction &t, node_key_t key) {
+  std::pair<bool, TCachedExtentRef<T>> resolve_transaction(
+    Transaction &t, node_key_t key) {
     auto &me = down_cast();
-    assert(me.is_stable());
-    auto mut_iter = me.mutation_pending_extents.find(
-      t.get_trans_id(), trans_spec_view_t::cmp_t());
-    if (mut_iter != me.mutation_pending_extents.end()) {
-      assert(copy_dests_by_trans.find(t.get_trans_id()) ==
-       copy_dests_by_trans.end());
-      return static_cast<T*>(&(*mut_iter));
+    ceph_assert(me.is_valid());
+    auto [viewable, state] = me.is_viewable_by_trans(t);
+    if (viewable) {
+      return {viewable, &me};
     }
-    auto iter = copy_dests_by_trans.find(
-      t.get_trans_id(), trans_spec_view_t::cmp_t());
-    ceph_assert(iter != copy_dests_by_trans.end());
-    auto &copy_dests = static_cast<copy_dests_t&>(*iter);
-    auto it = copy_dests.dests_by_key.lower_bound(key);
-    if (it == copy_dests.dests_by_key.end() || (*it)->get_begin() > key) {
-      ceph_assert(it != copy_dests.dests_by_key.begin());
-      --it;
-    }
-    ceph_assert((*it)->get_begin() <= key && key < (*it)->get_end());
-    return *it;
+    return {viewable, find_pending_version(t, key, state)};
   }
 
   template <typename ChildT>
@@ -406,6 +394,33 @@ protected:
     auto &me = down_cast();
     maybe_expand_children(me.get_size());
   }
+
+  TCachedExtentRef<T> find_pending_version(
+    Transaction &t, node_key_t key, CachedExtent::viewable_state_t &hint) {
+    auto &me = down_cast();
+    assert(me.is_stable());
+    if (hint == CachedExtent::viewable_state_t::stable_become_pending) {
+      auto mut_iter = me.mutation_pending_extents.find(
+       t.get_trans_id(), trans_spec_view_t::cmp_t());
+      assert(mut_iter != me.mutation_pending_extents.end());
+      assert(copy_dests_by_trans.find(t.get_trans_id()) ==
+       copy_dests_by_trans.end());
+      return static_cast<T*>(&(*mut_iter));
+    }
+    ceph_assert(hint == CachedExtent::viewable_state_t::stable_become_retired);
+    auto iter = copy_dests_by_trans.find(
+      t.get_trans_id(), trans_spec_view_t::cmp_t());
+    ceph_assert(iter != copy_dests_by_trans.end());
+    auto &copy_dests = static_cast<copy_dests_t&>(*iter);
+    auto it = copy_dests.dests_by_key.lower_bound(key);
+    if (it == copy_dests.dests_by_key.end() || (*it)->get_begin() > key) {
+      ceph_assert(it != copy_dests.dests_by_key.begin());
+      --it;
+    }
+    ceph_assert((*it)->get_begin() <= key && key < (*it)->get_end());
+    return *it;
+  }
+
   void add_copy_dest(Transaction &t, TCachedExtentRef<T> dest) {
     ceph_assert(down_cast().is_stable());
     ceph_assert(dest->is_pending());
@@ -987,6 +1002,24 @@ private:
 // as the parents, so they are ChildNodes.
 template <typename ParentT, typename T, typename key_t>
 class ChildNode : public BaseChildNode<ParentT, key_t> {
+public:
+  using get_parent_node_iertr = get_child_iertr;
+  using get_parent_node_ret =
+    get_parent_node_iertr::future<TCachedExtentRef<ParentT>>;
+  get_parent_node_ret get_parent_node(
+    Transaction &t,
+    ExtentTransViewRetriever &etvr)
+  {
+    auto &me = down_cast();
+    if (this->has_parent_tracker()) {
+      return this->_get_parent_node(t, etvr, me.get_begin());
+    } else {
+      assert(me.is_mutation_pending());
+      auto prior = me.get_prior_instance()->template cast<T>();
+      return prior->_get_parent_node(t, etvr, prior->get_begin());
+    }
+  }
+
 protected:
   void on_invalidated() {
     this->reset_parent_tracker();
@@ -1016,6 +1049,19 @@ private:
     return *static_cast<const T*>(this);
   }
 
+  get_parent_node_ret _get_parent_node(
+    Transaction &t,
+    ExtentTransViewRetriever &etvr,
+    key_t key)
+  {
+    return etvr.maybe_wait_accessible(
+      t, *this->peek_parent_node()
+    ).si_then([&t, key, this] {
+      auto parent = this->peek_parent_node();
+      return parent->resolve_transaction(t, key).second;
+    });
+  }
+
   void _take_parent_from_prior() {
     auto &me = down_cast();
     assert(!me.is_btree_root());