From: Xuehan Xu Date: Wed, 23 Apr 2025 03:40:14 +0000 (+0800) Subject: crimson/os/seastore/linked_tree_node: add get_parent_node for retrieving X-Git-Url: http://git.apps.os.sepia.ceph.com/?a=commitdiff_plain;h=f709800dbd5ccf92bcf2656bc50221bdc640e25c;p=ceph.git crimson/os/seastore/linked_tree_node: add get_parent_node for retrieving accessible parents Signed-off-by: Xuehan Xu --- diff --git a/src/crimson/os/seastore/linked_tree_node.h b/src/crimson/os/seastore/linked_tree_node.h index 809268d8a6131..2dd152b07e766 100644 --- a/src/crimson/os/seastore/linked_tree_node.h +++ b/src/crimson/os/seastore/linked_tree_node.h @@ -304,27 +304,15 @@ class ParentNode { * cannot be rewritten) because their parents must be mutated upon remapping. */ public: - TCachedExtentRef find_pending_version(Transaction &t, node_key_t key) { + std::pair> 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(&(*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 ©_dests = static_cast(*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 @@ -406,6 +394,33 @@ protected: auto &me = down_cast(); maybe_expand_children(me.get_size()); } + + TCachedExtentRef 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(&(*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 ©_dests = static_cast(*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 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 class ChildNode : public BaseChildNode { +public: + using get_parent_node_iertr = get_child_iertr; + using get_parent_node_ret = + get_parent_node_iertr::future>; + 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(); + 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(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());