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 {
<< ")";
}
- template <typename>
+ template <typename, typename>
friend class BtreeNodePin;
~btree_range_pin_t()
{
}
};
-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
*/
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));
}
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 {
#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>
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;
node_val_t,
internal_node_t,
leaf_node_t,
+ pin_t,
node_size>;
public:
using InternalNodeRef = TCachedExtentRef<internal_node_t>;
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;
}
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 });
}
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);
}
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);
}
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<
node_val_t,
internal_node_t,
leaf_node_t,
+ pin_t,
node_size>> : std::true_type {};
template <typename T>
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)
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);
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
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());
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);
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(
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;
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(),
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 "
t,
pin->get_key(),
pin->get_length(),
- pin->get_paddr(),
+ pin->get_val(),
type,
laddr,
len,
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());
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);
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);
std::make_pair(
ret->get_key(),
test_extent_t{
- ret->get_paddr(),
+ ret->get_val(),
ret->get_length(),
1
}
}).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());
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());
}