mirror of
https://github.com/ceph/ceph
synced 2025-03-25 11:48:05 +00:00
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:
parent
b0be25931d
commit
ec89b17f2a
@ -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 {
|
||||
|
@ -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>
|
||||
|
@ -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)
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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
|
||||
|
@ -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(),
|
||||
|
@ -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,
|
||||
|
@ -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);
|
||||
|
@ -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());
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user