crimson/os/seastore/btree: "templatize" btree leaf node to distinguish leaf nodes with(out) children

Signed-off-by: Xuehan Xu <xxhdx1985126@gmail.com>
This commit is contained in:
Xuehan Xu 2022-10-27 15:21:32 +08:00
parent 4d9b60e750
commit 55e1924e38
14 changed files with 115 additions and 78 deletions

View File

@ -76,7 +76,8 @@ class BackrefLeafNode
paddr_t, paddr_le_t,
backref_map_val_t, backref_map_val_le_t,
BACKREF_NODE_SIZE,
BackrefLeafNode> {
BackrefLeafNode,
false> {
public:
template <typename... T>
BackrefLeafNode(T&&... t) :

View File

@ -33,7 +33,7 @@ public:
using BackrefBtree = FixedKVBtree<
paddr_t, backref_map_val_t, BackrefInternalNode,
BackrefLeafNode, BtreeBackrefPin, BACKREF_BLOCK_SIZE>;
BackrefLeafNode, BtreeBackrefPin, BACKREF_BLOCK_SIZE, false>;
class BtreeBackrefManager : public BackrefManager {
public:

View File

@ -57,7 +57,8 @@ template <
typename internal_node_t,
typename leaf_node_t,
typename pin_t,
size_t node_size>
size_t node_size,
bool leaf_has_children>
class FixedKVBtree {
static constexpr size_t MAX_DEPTH = 16;
using self_type = FixedKVBtree<
@ -66,7 +67,8 @@ class FixedKVBtree {
internal_node_t,
leaf_node_t,
pin_t,
node_size>;
node_size,
leaf_has_children>;
public:
using InternalNodeRef = TCachedExtentRef<internal_node_t>;
using LeafNodeRef = TCachedExtentRef<leaf_node_t>;
@ -866,7 +868,8 @@ public:
n_fixed_kv_extent->set_modify_time(fixed_kv_extent.get_modify_time());
n_fixed_kv_extent->pin.set_range(n_fixed_kv_extent->get_node_meta());
if (fixed_kv_extent.get_type() == internal_node_t::TYPE) {
if (fixed_kv_extent.get_type() == internal_node_t::TYPE ||
leaf_node_t::do_has_children) {
if (!fixed_kv_extent.is_pending()) {
n_fixed_kv_extent->copy_sources.emplace(&fixed_kv_extent);
n_fixed_kv_extent->prior_instance = &fixed_kv_extent;
@ -2008,7 +2011,8 @@ template <
typename internal_node_t,
typename leaf_node_t,
typename pin_t,
size_t node_size>
size_t node_size,
bool leaf_has_children>
struct is_fixed_kv_tree<
FixedKVBtree<
node_key_t,
@ -2016,7 +2020,8 @@ struct is_fixed_kv_tree<
internal_node_t,
leaf_node_t,
pin_t,
node_size>> : std::true_type {};
node_size,
leaf_has_children>> : std::true_type {};
template <
typename tree_type_t,

View File

@ -915,7 +915,8 @@ template <
typename VAL,
typename VAL_LE,
size_t node_size,
typename node_type_t>
typename node_type_t,
bool has_children>
struct FixedKVLeafNode
: FixedKVNode<NODE_KEY>,
common::FixedKVNodeLayout<
@ -942,6 +943,8 @@ struct FixedKVLeafNode
: FixedKVNode<NODE_KEY>(rhs),
node_layout_t(this->get_bptr().c_str()) {}
static constexpr bool do_has_children = has_children;
uint16_t get_node_split_pivot() final {
return this->get_split_pivot().get_offset();
}

View File

@ -146,6 +146,7 @@ void Cache::register_metrics()
{extent_types_t::ROOT, sm::label_instance("ext", "ROOT")},
{extent_types_t::LADDR_INTERNAL, sm::label_instance("ext", "LADDR_INTERNAL")},
{extent_types_t::LADDR_LEAF, sm::label_instance("ext", "LADDR_LEAF")},
{extent_types_t::DINK_LADDR_LEAF, sm::label_instance("ext", "DINK_LADDR_LEAF")},
{extent_types_t::OMAP_INNER, sm::label_instance("ext", "OMAP_INNER")},
{extent_types_t::OMAP_LEAF, sm::label_instance("ext", "OMAP_LEAF")},
{extent_types_t::ONODE_BLOCK_STAGED, sm::label_instance("ext", "ONODE_BLOCK_STAGED")},
@ -969,7 +970,8 @@ CachedExtentRef Cache::alloc_new_extent_by_type(
case extent_types_t::LADDR_INTERNAL:
return alloc_new_extent<lba_manager::btree::LBAInternalNode>(t, length, hint, gen);
case extent_types_t::LADDR_LEAF:
return alloc_new_extent<lba_manager::btree::LBALeafNode>(t, length, hint, gen);
return alloc_new_extent<lba_manager::btree::LBALeafNode>(
t, length, hint, gen);
case extent_types_t::ONODE_BLOCK_STAGED:
return alloc_new_extent<onode::SeastoreNodeExtent>(t, length, hint, gen);
case extent_types_t::OMAP_INNER:

View File

@ -1119,6 +1119,8 @@ public:
switch (type) {
case extent_types_t::LADDR_INTERNAL:
[[fallthrough]];
case extent_types_t::DINK_LADDR_LEAF:
[[fallthrough]];
case extent_types_t::LADDR_LEAF:
stats.lba_tree_extents_num += delta;
ceph_assert(stats.lba_tree_extents_num >= 0);

View File

@ -30,7 +30,8 @@ template <
typename internal_node_t,
typename leaf_node_t,
typename pin_t,
size_t node_size>
size_t node_size,
bool leaf_has_children>
class FixedKVBtree;
// #define DEBUG_CACHED_EXTENT_REF
@ -189,7 +190,8 @@ class CachedExtent
typename internal_node_t,
typename leaf_node_t,
typename pin_t,
size_t node_size>
size_t node_size,
bool leaf_has_children>
friend class FixedKVBtree;
uint32_t last_committed_crc = 0;

View File

@ -22,8 +22,12 @@ LBAManager::update_mappings(
});
}
template <bool leaf_has_children>
LBAManagerRef lba_manager::create_lba_manager(Cache &cache) {
return LBAManagerRef(new btree::BtreeLBAManager(cache));
return LBAManagerRef(new btree::BtreeLBAManager<leaf_has_children>(cache));
}
template LBAManagerRef lba_manager::create_lba_manager<true>(Cache &cache);
template LBAManagerRef lba_manager::create_lba_manager<false>(Cache &cache);
}

View File

@ -206,6 +206,7 @@ using LBAManagerRef = std::unique_ptr<LBAManager>;
class Cache;
namespace lba_manager {
template <bool leaf_has_children>
LBAManagerRef create_lba_manager(Cache &cache);
}

View File

@ -21,18 +21,27 @@ SET_SUBSYS(seastore_lba);
namespace crimson::os::seastore {
template<>
Transaction::tree_stats_t& get_tree_stats<
crimson::os::seastore::lba_manager::btree::LBABtree>(Transaction &t) {
template <typename T>
Transaction::tree_stats_t& get_tree_stats(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) {
template Transaction::tree_stats_t&
get_tree_stats<
crimson::os::seastore::lba_manager::btree::LBABtree>(
Transaction &t);
template <typename T>
phy_tree_root_t& get_phy_tree_root(root_t &r)
{
return r.lba_root;
}
template phy_tree_root_t&
get_phy_tree_root<
crimson::os::seastore::lba_manager::btree::LBABtree>(root_t &r);
template <>
const get_phy_tree_root_node_ret get_phy_tree_root_node<
crimson::os::seastore::lba_manager::btree::LBABtree>(
@ -89,7 +98,8 @@ void unlink_phy_tree_root_node<laddr_t>(RootBlockRef &root_block) {
namespace crimson::os::seastore::lba_manager::btree {
BtreeLBAManager::mkfs_ret BtreeLBAManager::mkfs(
BtreeLBAManager::mkfs_ret
BtreeLBAManager::mkfs(
Transaction &t)
{
LOG_PREFIX(BtreeLBAManager::mkfs);
@ -125,7 +135,7 @@ BtreeLBAManager::get_mappings(
if (pos.is_end() || pos.get_key() >= (offset + length)) {
TRACET("{}~{} done with {} results",
c.trans, offset, length, ret.size());
return LBABtree::iterate_repeat_ret_inner(
return typename LBABtree::iterate_repeat_ret_inner(
interruptible::ready_future_marker{},
seastar::stop_iteration::yes);
}
@ -133,14 +143,13 @@ BtreeLBAManager::get_mappings(
c.trans, offset, length, pos.get_key(), pos.get_val());
ceph_assert((pos.get_key() + pos.get_val().len) > offset);
ret.push_back(pos.get_pin());
return LBABtree::iterate_repeat_ret_inner(
return typename LBABtree::iterate_repeat_ret_inner(
interruptible::ready_future_marker{},
seastar::stop_iteration::no);
});
});
}
BtreeLBAManager::get_mappings_ret
BtreeLBAManager::get_mappings(
Transaction &t,
@ -155,7 +164,7 @@ BtreeLBAManager::get_mappings(
l->begin(),
l->end(),
[this, &t, &ret](const auto &p) {
return get_mappings(t, p.first, p.second).si_then(
return this->get_mappings(t, p.first, p.second).si_then(
[&ret](auto res) {
ret.splice(ret.end(), res, res.begin(), res.end());
return get_mappings_iertr::now();
@ -205,8 +214,8 @@ BtreeLBAManager::alloc_extent(
struct state_t {
laddr_t last_end;
std::optional<LBABtree::iterator> insert_iter;
std::optional<LBABtree::iterator> ret;
std::optional<typename LBABtree::iterator> insert_iter;
std::optional<typename LBABtree::iterator> ret;
state_t(laddr_t hint) : last_end(hint) {}
};
@ -232,7 +241,7 @@ BtreeLBAManager::alloc_extent(
stats.num_alloc_extents_iter_nexts - lookup_attempts,
state.last_end);
state.insert_iter = pos;
return LBABtree::iterate_repeat_ret_inner(
return typename LBABtree::iterate_repeat_ret_inner(
interruptible::ready_future_marker{},
seastar::stop_iteration::yes);
} else if (pos.get_key() >= (state.last_end + len)) {
@ -243,7 +252,7 @@ BtreeLBAManager::alloc_extent(
state.last_end,
pos.get_val());
state.insert_iter = pos;
return LBABtree::iterate_repeat_ret_inner(
return typename LBABtree::iterate_repeat_ret_inner(
interruptible::ready_future_marker{},
seastar::stop_iteration::yes);
} else {
@ -252,7 +261,7 @@ BtreeLBAManager::alloc_extent(
t, addr, len, hint,
pos.get_key(), pos.get_val().len,
pos.get_val());
return LBABtree::iterate_repeat_ret_inner(
return typename LBABtree::iterate_repeat_ret_inner(
interruptible::ready_future_marker{},
seastar::stop_iteration::no);
}
@ -280,7 +289,8 @@ static bool is_lba_node(const CachedExtent &e)
return is_lba_node(e.get_type());
}
btree_range_pin_t<laddr_t> &BtreeLBAManager::get_pin(CachedExtent &e)
btree_range_pin_t<laddr_t> &BtreeLBAManager::get_pin(
CachedExtent &e)
{
if (is_lba_node(e)) {
return e.cast<LBANode>()->pin;
@ -338,7 +348,8 @@ void BtreeLBAManager::complete_transaction(
}
}
BtreeLBAManager::base_iertr::future<> _init_cached_extent(
BtreeLBAManager::base_iertr::template future<>
_init_cached_extent(
op_context_t<laddr_t> c,
const CachedExtentRef &e,
LBABtree &btree,
@ -377,7 +388,8 @@ BtreeLBAManager::base_iertr::future<> _init_cached_extent(
}
}
BtreeLBAManager::init_cached_extent_ret BtreeLBAManager::init_cached_extent(
BtreeLBAManager::init_cached_extent_ret
BtreeLBAManager::init_cached_extent(
Transaction &t,
CachedExtentRef e)
{
@ -385,16 +397,19 @@ BtreeLBAManager::init_cached_extent_ret BtreeLBAManager::init_cached_extent(
TRACET("{}", t, *e);
return seastar::do_with(bool(), [this, e, &t](bool &ret) {
auto c = get_context(t);
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);
return _init_cached_extent(c, e, btree, ret);
}).si_then([&ret] { return ret; });
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);
return _init_cached_extent(c, e, btree, ret);
}
).si_then([&ret] { return ret; });
});
}
BtreeLBAManager::scan_mappings_ret BtreeLBAManager::scan_mappings(
BtreeLBAManager::scan_mappings_ret
BtreeLBAManager::scan_mappings(
Transaction &t,
laddr_t begin,
laddr_t end,
@ -413,20 +428,21 @@ BtreeLBAManager::scan_mappings_ret BtreeLBAManager::scan_mappings(
btree.upper_bound_right(c, begin),
[f=std::move(f), begin, end](auto &pos) {
if (pos.is_end() || pos.get_key() >= end) {
return LBABtree::iterate_repeat_ret_inner(
return typename LBABtree::iterate_repeat_ret_inner(
interruptible::ready_future_marker{},
seastar::stop_iteration::yes);
}
ceph_assert((pos.get_key() + pos.get_val().len) > begin);
f(pos.get_key(), pos.get_val().paddr, pos.get_val().len);
return LBABtree::iterate_repeat_ret_inner(
return typename LBABtree::iterate_repeat_ret_inner(
interruptible::ready_future_marker{},
seastar::stop_iteration::no);
});
});
}
BtreeLBAManager::rewrite_extent_ret BtreeLBAManager::rewrite_extent(
BtreeLBAManager::rewrite_extent_ret
BtreeLBAManager::rewrite_extent(
Transaction &t,
CachedExtentRef extent)
{
@ -504,18 +520,13 @@ BtreeLBAManager::get_physical_extent_if_live(
if (type == extent_types_t::LADDR_INTERNAL) {
return btree.get_internal_if_live(c, addr, laddr, len);
} else {
assert(type == extent_types_t::LADDR_LEAF);
assert(type == extent_types_t::LADDR_LEAF ||
type == extent_types_t::DINK_LADDR_LEAF);
return btree.get_leaf_if_live(c, addr, laddr, len);
}
});
}
BtreeLBAManager::BtreeLBAManager(Cache &cache)
: cache(cache)
{
register_metrics();
}
void BtreeLBAManager::register_metrics()
{
LOG_PREFIX(BtreeLBAManager::register_metrics);
@ -539,7 +550,8 @@ void BtreeLBAManager::register_metrics()
);
}
BtreeLBAManager::update_refcount_ret BtreeLBAManager::update_refcount(
BtreeLBAManager::update_refcount_ret
BtreeLBAManager::update_refcount(
Transaction &t,
laddr_t addr,
int delta)
@ -565,7 +577,8 @@ BtreeLBAManager::update_refcount_ret BtreeLBAManager::update_refcount(
});
}
BtreeLBAManager::_update_mapping_ret BtreeLBAManager::_update_mapping(
BtreeLBAManager::_update_mapping_ret
BtreeLBAManager::_update_mapping(
Transaction &t,
laddr_t addr,
update_func_t &&f)
@ -606,13 +619,4 @@ BtreeLBAManager::_update_mapping_ret BtreeLBAManager::_update_mapping(
});
}
BtreeLBAManager::~BtreeLBAManager()
{
pin_set.scan([](auto &i) {
LOG_PREFIX(BtreeLBAManager::~BtreeLBAManager);
ERROR("Found {}, has_ref={} -- {}",
i, i.has_ref(), i.get_extent());
});
}
}

View File

@ -42,7 +42,7 @@ public:
using LBABtree = FixedKVBtree<
laddr_t, lba_map_val_t, LBAInternalNode,
LBALeafNode, BtreeLBAPin, LBA_BLOCK_SIZE>;
LBALeafNode, BtreeLBAPin, LBA_BLOCK_SIZE, true>;
/**
* BtreeLBAManager
@ -63,7 +63,11 @@ using LBABtree = FixedKVBtree<
*/
class BtreeLBAManager : public LBAManager {
public:
BtreeLBAManager(Cache &cache);
BtreeLBAManager(Cache &cache)
: cache(cache)
{
register_metrics();
}
mkfs_ret mkfs(
Transaction &t) final;
@ -144,7 +148,13 @@ public:
bpin->set_parent(nullptr);
}
~BtreeLBAManager();
~BtreeLBAManager() {
pin_set.scan([](auto &i) {
LOG_PREFIX(BtreeLBAManager::~BtreeLBAManager);
SUBERROR(seastore_lba, "Found {}, has_ref={} -- {}",
i, i.has_ref(), i.get_extent());
});
}
private:
Cache &cache;

View File

@ -142,7 +142,8 @@ struct LBALeafNode
laddr_t, laddr_le_t,
lba_map_val_t, lba_map_val_le_t,
LBA_BLOCK_SIZE,
LBALeafNode> {
LBALeafNode,
true> {
using Ref = TCachedExtentRef<LBALeafNode>;
using internal_iterator_t = const_iterator;
template <typename... T>

View File

@ -1062,23 +1062,24 @@ enum class extent_types_t : uint8_t {
ROOT = 0,
LADDR_INTERNAL = 1,
LADDR_LEAF = 2,
OMAP_INNER = 3,
OMAP_LEAF = 4,
ONODE_BLOCK_STAGED = 5,
COLL_BLOCK = 6,
OBJECT_DATA_BLOCK = 7,
RETIRED_PLACEHOLDER = 8,
DINK_LADDR_LEAF = 3,
OMAP_INNER = 4,
OMAP_LEAF = 5,
ONODE_BLOCK_STAGED = 6,
COLL_BLOCK = 7,
OBJECT_DATA_BLOCK = 8,
RETIRED_PLACEHOLDER = 9,
// the following two types are not extent types,
// they are just used to indicates paddr allocation deltas
ALLOC_INFO = 9,
JOURNAL_TAIL = 10,
ALLOC_INFO = 10,
JOURNAL_TAIL = 11,
// Test Block Types
TEST_BLOCK = 11,
TEST_BLOCK_PHYSICAL = 12,
BACKREF_INTERNAL = 13,
BACKREF_LEAF = 14,
TEST_BLOCK = 12,
TEST_BLOCK_PHYSICAL = 13,
BACKREF_INTERNAL = 14,
BACKREF_LEAF = 15,
// None and the number of valid extent_types_t
NONE = 15,
NONE = 16,
};
using extent_types_le_t = uint8_t;
constexpr auto EXTENT_TYPES_MAX = static_cast<uint8_t>(extent_types_t::NONE);
@ -1108,7 +1109,8 @@ constexpr bool is_retired_placeholder(extent_types_t type)
constexpr bool is_lba_node(extent_types_t type)
{
return type == extent_types_t::LADDR_INTERNAL ||
type == extent_types_t::LADDR_LEAF;
type == extent_types_t::LADDR_LEAF ||
type == extent_types_t::DINK_LADDR_LEAF;
}
constexpr bool is_backref_node(extent_types_t type)

View File

@ -324,7 +324,7 @@ TEST_F(lba_btree_test, basic)
}
struct btree_lba_manager_test : btree_test_base {
BtreeLBAManagerRef lba_manager;
BtreeLBAManagerRef<false> lba_manager;
btree_lba_manager_test() = default;