}
};
+template <typename T>
+struct is_fixed_kv_tree : std::false_type {};
+
+template <
+ typename node_key_t,
+ typename node_val_t,
+ typename internal_node_t,
+ typename leaf_node_t,
+ size_t node_size>
+struct is_fixed_kv_tree<
+ FixedKVBtree<
+ node_key_t,
+ node_val_t,
+ internal_node_t,
+ leaf_node_t,
+ node_size>> : std::true_type {};
+
+template <typename T>
+phy_tree_root_t& get_phy_tree_root(root_t& r);
+
+template <
+ typename tree_type_t,
+ typename node_key_t,
+ typename F,
+ std::enable_if_t<is_fixed_kv_tree<tree_type_t>::value, int> = 0>
+auto with_btree(
+ Cache &cache,
+ op_context_t<node_key_t> c,
+ F &&f) {
+ using base_ertr = crimson::errorator<
+ crimson::ct_error::input_output_error>;
+ using base_iertr = trans_iertr<base_ertr>;
+ return cache.get_root(
+ c.trans
+ ).si_then([c, f=std::forward<F>(f), &cache](RootBlockRef croot) mutable {
+ return seastar::do_with(
+ tree_type_t(get_phy_tree_root<tree_type_t>(croot->get_root())),
+ [c, croot, f=std::move(f), &cache](auto &btree) mutable {
+ return f(
+ btree
+ ).si_then([c, croot, &btree, &cache] {
+ if (btree.is_root_dirty()) {
+ auto mut_croot = cache.duplicate_for_write(
+ c.trans, croot
+ )->template cast<RootBlock>();
+ get_phy_tree_root<tree_type_t>(mut_croot->get_root()) =
+ btree.get_root_undirty();
+ }
+ return base_iertr::now();
+ });
+ });
+ });
+}
+
+template <
+ typename tree_type_t,
+ typename State,
+ typename node_key_t,
+ typename F,
+ std::enable_if_t<is_fixed_kv_tree<tree_type_t>::value, int> = 0>
+auto with_btree_state(
+ Cache &cache,
+ op_context_t<node_key_t> c,
+ State &&init,
+ F &&f) {
+ return seastar::do_with(
+ std::forward<State>(init),
+ [&cache, c, f=std::forward<F>(f)](auto &state) mutable {
+ return with_btree<tree_type_t>(
+ cache,
+ c,
+ [&state, f=std::move(f)](auto &btree) mutable {
+ return f(btree, state);
+ }).si_then([&state] {
+ return seastar::make_ready_future<State>(std::move(state));
+ });
+ });
+}
+
+template <
+ typename tree_type_t,
+ typename State,
+ typename node_key_t,
+ typename F,
+ std::enable_if_t<is_fixed_kv_tree<tree_type_t>::value, int> = 0>
+auto with_btree_state(
+ Cache &cache,
+ op_context_t<node_key_t> c,
+ F &&f) {
+ return crimson::os::seastore::with_btree_state<tree_type_t, State>(
+ cache, c, State{}, std::forward<F>(f));
+}
+
+template <
+ typename tree_type_t,
+ typename Ret,
+ typename node_key_t,
+ typename F>
+auto with_btree_ret(
+ Cache &cache,
+ op_context_t<node_key_t> c,
+ F &&f) {
+ return with_btree_state<tree_type_t, Ret>(
+ cache,
+ c,
+ [f=std::forward<F>(f)](auto &btree, auto &ret) mutable {
+ return f(
+ btree
+ ).si_then([&ret](auto &&_ret) {
+ ret = std::move(_ret);
+ });
+ });
+}
+
}
crimson::os::seastore::lba_manager::btree::LBABtree>(Transaction &t) {
return t.get_lba_tree_stats();
}
+
+template<>
+phy_tree_root_t& get_phy_tree_root<
+ crimson::os::seastore::lba_manager::btree::LBABtree>(root_t &r) {
+ return r.lba_root;
+}
+
}
namespace crimson::os::seastore::lba_manager::btree {
LOG_PREFIX(BtreeLBAManager::get_mappings);
TRACET("{}~{}", t, offset, length);
auto c = get_context(t);
- return with_btree_state<lba_pin_list_t>(
+ return with_btree_state<LBABtree, lba_pin_list_t>(
+ cache,
c,
[c, offset, length, FNAME](auto &btree, auto &ret) {
return LBABtree::iterate_repeat(
LOG_PREFIX(BtreeLBAManager::get_mapping);
TRACET("{}", t, offset);
auto c = get_context(t);
- return with_btree_ret<LBAPinRef>(
+ return with_btree_ret<LBABtree, LBAPinRef>(
+ cache,
c,
[FNAME, c, offset](auto &btree) {
return btree.lower_bound(
auto c = get_context(t);
++stats.num_alloc_extents;
auto lookup_attempts = stats.num_alloc_extents_iter_nexts;
- return with_btree_state<state_t>(
+ return crimson::os::seastore::with_btree_state<LBABtree, state_t>(
+ cache,
c,
hint,
[this, FNAME, c, hint, len, addr, lookup_attempts, &t](auto &btree, auto &state) {
TRACET("{}", t, *e);
return seastar::do_with(bool(), [this, e, &t](bool &ret) {
auto c = get_context(t);
- return with_btree(c, [c, e, &ret](auto &btree)
+ return with_btree<LBABtree>(cache, c, [c, e, &ret](auto &btree)
-> base_iertr::future<> {
LOG_PREFIX(BtreeLBAManager::init_cached_extent);
DEBUGT("extent {}", c.trans, *e);
DEBUGT("begin: {}, end: {}", t, begin, end);
auto c = get_context(t);
- return with_btree(
+ return with_btree<LBABtree>(
+ cache,
c,
[c, f=std::move(f), begin, end](auto &btree) mutable {
return LBABtree::iterate_repeat(
return seastar::do_with(
std::move(f),
[this, c](auto &visitor) {
- return with_btree(
+ return with_btree<LBABtree>(
+ cache,
c,
[c, &visitor](auto &btree) {
return LBABtree::iterate_repeat(
if (is_lba_node(*extent)) {
DEBUGT("rewriting lba extent -- {}", t, *extent);
auto c = get_context(t);
- return with_btree(
+ return with_btree<LBABtree>(
+ cache,
c,
[c, extent](auto &btree) mutable {
return btree.rewrite_extent(c, extent);
t, type, laddr, addr, len);
ceph_assert(is_lba_node(type));
auto c = get_context(t);
- return with_btree_ret<CachedExtentRef>(
+ return with_btree_ret<LBABtree, CachedExtentRef>(
+ cache,
c,
[c, type, addr, laddr, len](auto &btree) {
if (type == extent_types_t::LADDR_INTERNAL) {
update_func_t &&f)
{
auto c = get_context(t);
- return with_btree_ret<lba_map_val_t>(
+ return with_btree_ret<LBABtree, lba_map_val_t>(
+ cache,
c,
[f=std::move(f), c, addr](auto &btree) mutable {
return btree.lower_bound(
namespace crimson::os::seastore::lba_manager::btree {
-using LBABtree = FixedKVBtree<laddr_t, lba_map_val_t, LBAInternalNode, LBALeafNode, LBA_BLOCK_SIZE>;
+using LBABtree = FixedKVBtree<
+ laddr_t, lba_map_val_t, LBAInternalNode,
+ LBALeafNode, LBA_BLOCK_SIZE>;
using BtreeLBAPin = BtreeNodePin<laddr_t>;
seastar::metrics::metric_group metrics;
void register_metrics();
- template <typename F, typename... Args>
- auto with_btree(
- op_context_t<laddr_t> c,
- F &&f) {
- return cache.get_root(
- c.trans
- ).si_then([this, c, f=std::forward<F>(f)](RootBlockRef croot) mutable {
- return seastar::do_with(
- LBABtree(croot->get_root().lba_root),
- [this, c, croot, f=std::move(f)](auto &btree) mutable {
- return f(
- btree
- ).si_then([this, c, croot, &btree] {
- if (btree.is_root_dirty()) {
- auto mut_croot = cache.duplicate_for_write(
- c.trans, croot
- )->cast<RootBlock>();
- mut_croot->get_root().lba_root = btree.get_root_undirty();
- }
- return base_iertr::now();
- });
- });
- });
- }
-
- template <typename State, typename F>
- auto with_btree_state(
- op_context_t<laddr_t> c,
- State &&init,
- F &&f) {
- return seastar::do_with(
- std::forward<State>(init),
- [this, c, f=std::forward<F>(f)](auto &state) mutable {
- (void)this; // silence incorrect clang warning about capture
- return with_btree(c, [&state, f=std::move(f)](auto &btree) mutable {
- return f(btree, state);
- }).si_then([&state] {
- return seastar::make_ready_future<State>(std::move(state));
- });
- });
- }
-
- template <typename State, typename F>
- auto with_btree_state(
- op_context_t<laddr_t> c,
- F &&f) {
- return with_btree_state<State, F>(c, State{}, std::forward<F>(f));
- }
-
- template <typename Ret, typename F>
- auto with_btree_ret(
- op_context_t<laddr_t> c,
- F &&f) {
- return with_btree_state<Ret>(
- c,
- [f=std::forward<F>(f)](auto &btree, auto &ret) mutable {
- return f(
- btree
- ).si_then([&ret](auto &&_ret) {
- ret = std::move(_ret);
- });
- });
- }
/**
* update_refcount