crimson/os/seastore/fixed_kv_btree: generalize btree pins to allow them to hold any kind of value

also add get_type() to PhysicalNodePin

Signed-off-by: Xuehan Xu <xxhdx1985126@gmail.com>
This commit is contained in:
Xuehan Xu 2022-02-21 15:30:57 +08:00
parent b0be25931d
commit ec89b17f2a
9 changed files with 86 additions and 51 deletions

View File

@ -92,8 +92,8 @@ struct fixed_kv_node_meta_le_t {
const fixed_kv_node_meta_le_t<bound_le_t> &) = default;
explicit fixed_kv_node_meta_le_t(
const fixed_kv_node_meta_t<typename bound_le_t::orig_type> &val)
: begin(ceph_le64(val.begin)),
end(ceph_le64(val.end)),
: begin(val.begin),
end(val.end),
depth(init_depth_le(val.depth)) {}
operator fixed_kv_node_meta_t<typename bound_le_t::orig_type>() const {
@ -222,7 +222,7 @@ public:
<< ")";
}
template <typename>
template <typename, typename>
friend class BtreeNodePin;
~btree_range_pin_t()
{
@ -415,8 +415,8 @@ public:
}
};
template <typename key_t>
class BtreeNodePin : public PhysicalNodePin<key_t> {
template <typename key_t, typename val_t>
class BtreeNodePin : public PhysicalNodePin<key_t, val_t> {
/**
* parent
@ -426,17 +426,20 @@ class BtreeNodePin : public PhysicalNodePin<key_t> {
*/
CachedExtentRef parent;
paddr_t paddr;
val_t value;
extent_len_t len;
btree_range_pin_t<key_t> pin;
public:
using val_type = val_t;
BtreeNodePin() = default;
BtreeNodePin(
CachedExtentRef parent,
paddr_t paddr,
val_t &value,
extent_len_t len,
fixed_kv_node_meta_t<key_t> &&meta)
: parent(parent), paddr(paddr) {
: parent(parent), value(value), len(len) {
pin.set_range(std::move(meta));
}
@ -458,28 +461,34 @@ public:
extent_len_t get_length() const final {
ceph_assert(pin.range.end > pin.range.begin);
return pin.range.end - pin.range.begin;
return len;
}
paddr_t get_paddr() const final {
return paddr;
extent_types_t get_type() const override {
ceph_abort("should never happen");
return extent_types_t::ROOT;
}
val_t get_val() const final {
return value;
}
key_t get_key() const final {
return pin.range.begin;
}
PhysicalNodePinRef<key_t> duplicate() const final {
auto ret = std::unique_ptr<BtreeNodePin<key_t>>(
new BtreeNodePin<key_t>);
PhysicalNodePinRef<key_t, val_t> duplicate() const final {
auto ret = std::unique_ptr<BtreeNodePin<key_t, val_t>>(
new BtreeNodePin<key_t, val_t>);
ret->pin.set_range(pin.range);
ret->paddr = paddr;
ret->value = value;
ret->parent = parent;
ret->len = len;
return ret;
}
void take_pin(PhysicalNodePin<key_t> &opin) final {
pin.take_pin(static_cast<BtreeNodePin<key_t>&>(opin).pin);
void take_pin(PhysicalNodePin<key_t, val_t> &opin) final {
pin.take_pin(static_cast<BtreeNodePin<key_t, val_t>&>(opin).pin);
}
bool has_been_invalidated() const final {

View File

@ -14,6 +14,10 @@
#include "crimson/os/seastore/seastore_types.h"
#include "crimson/os/seastore/btree/btree_range_pin.h"
namespace crimson::os::seastore::lba_manager::btree {
struct lba_map_val_t;
}
namespace crimson::os::seastore {
template <typename node_key_t>
@ -31,6 +35,7 @@ template <
typename node_val_t,
typename internal_node_t,
typename leaf_node_t,
typename pin_t,
size_t node_size>
class FixedKVBtree {
static constexpr size_t MAX_DEPTH = 16;
@ -39,6 +44,7 @@ class FixedKVBtree {
node_val_t,
internal_node_t,
leaf_node_t,
pin_t,
node_size>;
public:
using InternalNodeRef = TCachedExtentRef<internal_node_t>;
@ -167,7 +173,11 @@ public:
node_val_t get_val() const {
assert(!is_end());
auto ret = leaf.node->iter_idx(leaf.pos).get_val();
ret.paddr = ret.paddr.maybe_relative_to(leaf.node->get_paddr());
if constexpr (
std::is_same_v<crimson::os::seastore::lba_manager::btree::lba_map_val_t,
node_val_t>) {
ret.paddr = ret.paddr.maybe_relative_to(leaf.node->get_paddr());
}
return ret;
}
@ -184,13 +194,13 @@ public:
return leaf.pos == 0;
}
PhysicalNodePinRef<node_key_t> get_pin() const {
PhysicalNodePinRef<node_key_t, typename pin_t::val_type> get_pin() const {
assert(!is_end());
auto val = get_val();
auto key = get_key();
return std::make_unique<BtreeNodePin<node_key_t>>(
return std::make_unique<pin_t>(
leaf.node,
val.paddr,
val,
fixed_kv_node_meta_t<node_key_t>{ key, key + val.len, 0 });
}
@ -1559,8 +1569,8 @@ private:
op_context_t<node_key_t> c,
depth_t depth,
paddr_t addr,
laddr_t begin,
laddr_t end) {
node_key_t begin,
node_key_t end) {
assert(depth == 1);
return get_leaf_node(c, addr, begin, end);
}
@ -1571,8 +1581,8 @@ private:
op_context_t<node_key_t> c,
depth_t depth,
paddr_t addr,
laddr_t begin,
laddr_t end) {
node_key_t begin,
node_key_t end) {
return get_internal_node(c, depth, addr, begin, end);
}
@ -1687,6 +1697,7 @@ template <
typename node_val_t,
typename internal_node_t,
typename leaf_node_t,
typename pin_t,
size_t node_size>
struct is_fixed_kv_tree<
FixedKVBtree<
@ -1694,6 +1705,7 @@ struct is_fixed_kv_tree<
node_val_t,
internal_node_t,
leaf_node_t,
pin_t,
node_size>> : std::true_type {};
template <typename T>

View File

@ -82,7 +82,7 @@ std::ostream &LogicalCachedExtent::print_detail(std::ostream &out) const
std::ostream &operator<<(std::ostream &out, const LBAPin &rhs)
{
return out << "LBAPin(" << rhs.get_key() << "~" << rhs.get_length()
<< "->" << rhs.get_paddr();
<< "->" << rhs.get_val();
}
std::ostream &operator<<(std::ostream &out, const lba_pin_list_t &rhs)

View File

@ -667,28 +667,29 @@ private:
class LogicalCachedExtent;
template <typename key_t>
template <typename key_t, typename>
class PhysicalNodePin;
template <typename key_t>
using PhysicalNodePinRef = std::unique_ptr<PhysicalNodePin<key_t>>;
template <typename key_t, typename val_t>
using PhysicalNodePinRef = std::unique_ptr<PhysicalNodePin<key_t, val_t>>;
template <typename key_t>
template <typename key_t, typename val_t>
class PhysicalNodePin {
public:
virtual void link_extent(LogicalCachedExtent *ref) = 0;
virtual void take_pin(PhysicalNodePin<key_t> &pin) = 0;
virtual void take_pin(PhysicalNodePin<key_t, val_t> &pin) = 0;
virtual extent_len_t get_length() const = 0;
virtual paddr_t get_paddr() const = 0;
virtual extent_types_t get_type() const = 0;
virtual val_t get_val() const = 0;
virtual key_t get_key() const = 0;
virtual PhysicalNodePinRef<key_t> duplicate() const = 0;
virtual PhysicalNodePinRef<key_t, val_t> duplicate() const = 0;
virtual bool has_been_invalidated() const = 0;
virtual ~PhysicalNodePin() {}
};
using LBAPin = PhysicalNodePin<laddr_t>;
using LBAPinRef = PhysicalNodePinRef<laddr_t>;
using LBAPin = PhysicalNodePin<laddr_t, paddr_t>;
using LBAPinRef = PhysicalNodePinRef<laddr_t, paddr_t>;
std::ostream &operator<<(std::ostream &out, const LBAPin &rhs);

View File

@ -25,11 +25,24 @@
namespace crimson::os::seastore::lba_manager::btree {
class BtreeLBAPin : public BtreeNodePin<laddr_t, paddr_t> {
public:
BtreeLBAPin() = default;
BtreeLBAPin(
CachedExtentRef parent,
lba_map_val_t &val,
lba_node_meta_t &&meta)
: BtreeNodePin(
parent,
val.paddr,
val.len,
std::forward<lba_node_meta_t>(meta))
{}
};
using LBABtree = FixedKVBtree<
laddr_t, lba_map_val_t, LBAInternalNode,
LBALeafNode, LBA_BLOCK_SIZE>;
using BtreeLBAPin = BtreeNodePin<laddr_t>;
LBALeafNode, BtreeLBAPin, LBA_BLOCK_SIZE>;
/**
* BtreeLBAManager

View File

@ -201,7 +201,7 @@ split_ret split_pin_left(context_t ctx, LBAPinRef &pin, laddr_t offset)
return get_iertr::make_ready_future<split_ret_bare>(
std::nullopt,
std::nullopt);
} else if (pin->get_paddr().is_zero()) {
} else if (pin->get_val().is_zero()) {
/* Zero extent unaligned, return largest aligned zero extent to
* the left and the gap between aligned_offset and offset to prepend. */
auto aligned_offset = p2align(offset, (uint64_t)ctx.tm.get_block_size());
@ -242,7 +242,7 @@ split_ret split_pin_right(context_t ctx, LBAPinRef &pin, laddr_t end)
return get_iertr::make_ready_future<split_ret_bare>(
std::nullopt,
std::nullopt);
} else if (pin->get_paddr().is_zero()) {
} else if (pin->get_val().is_zero()) {
auto aligned_end = p2roundup(end, (uint64_t)ctx.tm.get_block_size());
assert_aligned(aligned_end);
ceph_assert(aligned_end >= end);
@ -351,7 +351,7 @@ ObjectDataHandler::clear_ret ObjectDataHandler::trim_data_reservation(
auto pin_offset = pin.get_key() -
object_data.get_reserved_data_base();
if ((pin.get_key() == (object_data.get_reserved_data_base() + size)) ||
(pin.get_paddr().is_zero())) {
(pin.get_val().is_zero())) {
/* First pin is exactly at the boundary or is a zero pin. Either way,
* remove all pins and add a single zero pin to the end. */
to_write.emplace_back(
@ -692,7 +692,7 @@ ObjectDataHandler::read_ret ObjectDataHandler::read(
laddr_t end = std::min(
pin->get_key() + pin->get_length(),
loffset + len);
if (pin->get_paddr().is_zero()) {
if (pin->get_val().is_zero()) {
ceph_assert(end > current); // See LBAManager::get_mappings
ret.append_zero(end - current);
current = end;
@ -762,7 +762,7 @@ ObjectDataHandler::fiemap_ret ObjectDataHandler::fiemap(
ceph_assert(pins.size() >= 1);
ceph_assert((*pins.begin())->get_key() <= loffset);
for (auto &&i: pins) {
if (!(i->get_paddr().is_zero())) {
if (!(i->get_val().is_zero())) {
auto ret_left = std::max(i->get_key(), loffset);
auto ret_right = std::min(
i->get_key() + i->get_length(),

View File

@ -472,7 +472,7 @@ TransactionManager::get_extent_if_live_ret TransactionManager::get_extent_if_liv
t,
laddr).si_then([=, &t] (LBAPinRef pin) -> inner_ret {
ceph_assert(pin->get_key() == laddr);
if (pin->get_paddr() == addr) {
if (pin->get_val() == addr) {
if (pin->get_length() != (extent_len_t)len) {
ERRORT(
"Invalid pin {}~{} {} found for "
@ -480,7 +480,7 @@ TransactionManager::get_extent_if_live_ret TransactionManager::get_extent_if_liv
t,
pin->get_key(),
pin->get_length(),
pin->get_paddr(),
pin->get_val(),
type,
laddr,
len,

View File

@ -154,7 +154,7 @@ public:
auto &pref = *pin;
return cache->get_extent<T>(
t,
pref.get_paddr(),
pref.get_val(),
pref.get_length(),
[this, pin=std::move(pin)](T &extent) mutable {
assert(!extent.has_pin());
@ -191,7 +191,7 @@ public:
return get_pin(
t, offset
).si_then([this, FNAME, &t, offset, length] (auto pin) {
if (length != pin->get_length() || !pin->get_paddr().is_real()) {
if (length != pin->get_length() || !pin->get_val().is_real()) {
SUBERRORT(seastore_tm,
"offset {} len {} got wrong pin {}",
t, offset, length, *pin);
@ -215,7 +215,7 @@ public:
return get_pin(
t, offset
).si_then([this, FNAME, &t, offset] (auto pin) {
if (!pin->get_paddr().is_real()) {
if (!pin->get_val().is_real()) {
SUBERRORT(seastore_tm,
"offset {} got wrong pin {}",
t, offset, *pin);

View File

@ -404,7 +404,7 @@ struct btree_lba_manager_test : btree_test_base {
std::make_pair(
ret->get_key(),
test_extent_t{
ret->get_paddr(),
ret->get_val(),
ret->get_length(),
1
}
@ -495,7 +495,7 @@ struct btree_lba_manager_test : btree_test_base {
}).unsafe_get0();
EXPECT_EQ(ret_list.size(), 1);
auto &ret = *ret_list.begin();
EXPECT_EQ(i.second.addr, ret->get_paddr());
EXPECT_EQ(i.second.addr, ret->get_val());
EXPECT_EQ(laddr, ret->get_key());
EXPECT_EQ(len, ret->get_length());
@ -505,7 +505,7 @@ struct btree_lba_manager_test : btree_test_base {
return lba_manager->get_mapping(
t, laddr);
}).unsafe_get0();
EXPECT_EQ(i.second.addr, ret_pin->get_paddr());
EXPECT_EQ(i.second.addr, ret_pin->get_val());
EXPECT_EQ(laddr, ret_pin->get_key());
EXPECT_EQ(len, ret_pin->get_length());
}