template <typename key_t, typename val_t>
bool BtreeNodeMapping<key_t, val_t>::is_stable() const
{
- assert(is_parent_valid());
+ assert(!this->parent_modified());
assert(pos != std::numeric_limits<uint16_t>::max());
auto &p = (FixedKVNode<key_t>&)*parent;
return p.is_child_stable(ctx, pos);
template <typename key_t, typename val_t>
bool BtreeNodeMapping<key_t, val_t>::is_data_stable() const
{
- assert(is_parent_valid());
+ assert(!this->parent_modified());
assert(pos != std::numeric_limits<uint16_t>::max());
auto &p = (FixedKVNode<key_t>&)*parent;
return p.is_child_data_stable(ctx, pos);
node_layout_t(this->get_bptr().c_str()) {}
FixedKVLeafNode(const FixedKVLeafNode &rhs)
: FixedKVNode<NODE_KEY>(rhs),
- node_layout_t(this->get_bptr().c_str()) {}
+ node_layout_t(this->get_bptr().c_str()),
+ modifications(rhs.modifications) {}
static constexpr bool do_has_children = has_children;
+ // for the stable extent, modifications is always 0;
+ // it will increase for each transaction-local change, so that
+ // modifications can be detected (see BtreeLBAMapping.parent_modifications)
+ uint64_t modifications = 0;
+
bool have_children() const final {
return do_has_children;
}
+ void on_modify() {
+ modifications++;
+ }
+
+ bool modified_since(uint64_t v) const {
+ ceph_assert(v <= modifications);
+ return v != modifications;
+ }
+
bool is_leaf_and_has_children() const final {
return has_children;
}
this->copy_sources.clear();
}
}
+ modifications = 0;
assert(this->is_initial_pending()
? this->copy_sources.empty():
true);
} else {
this->set_parent_tracker_from_prior_instance();
}
+ modifications = 0;
}
uint16_t lower_bound_offset(NODE_KEY key) const final {
return !get_val().is_real();
}
virtual bool is_parent_valid() const = 0;
+ virtual bool parent_modified() const {
+ ceph_abort("impossible");
+ return false;
+ };
virtual ~PhysicalNodeMapping() {}
protected:
: BtreeNodeMapping(ctx) {}
BtreeLBAMapping(
op_context_t<laddr_t> c,
- CachedExtentRef parent,
+ LBALeafNodeRef parent,
uint16_t pos,
lba_map_val_t &val,
lba_node_meta_t meta)
intermediate_key(indirect ? val.pladdr.get_laddr() : L_ADDR_NULL),
intermediate_length(indirect ? val.len : 0),
raw_val(val.pladdr),
- map_val(val)
+ map_val(val),
+ parent_modifications(parent->modifications)
{}
lba_map_val_t get_map_val() const {
len = length;
}
+ uint64_t get_parent_modifications() const {
+ return parent_modifications;
+ }
+
+ bool parent_modified() const final {
+ ceph_assert(parent);
+ ceph_assert(is_parent_valid());
+ auto &p = static_cast<LBALeafNode&>(*parent);
+ return p.modified_since(parent_modifications);
+ }
+
protected:
std::unique_ptr<BtreeNodeMapping<laddr_t, paddr_t>> _duplicate(
op_context_t<laddr_t> ctx) const final {
pin->indirect = indirect;
pin->raw_val = raw_val;
pin->map_val = map_val;
+ pin->parent_modifications = parent_modifications;
return pin;
}
private:
extent_len_t intermediate_length = 0;
pladdr_t raw_val;
lba_map_val_t map_val;
+ uint64_t parent_modifications = 0;
};
using BtreeLBAMappingRef = std::unique_ptr<BtreeLBAMapping>;
{
out << ", size=" << this->get_size()
<< ", meta=" << this->get_meta()
+ << ", modifications=" << this->modifications
<< ", my_tracker=" << (void*)this->my_tracker;
if (this->my_tracker) {
out << ", my_tracker->parent=" << (void*)this->my_tracker->get_parent().get();
assert(nextent->has_parent_tracker()
&& nextent->get_parent_node<LBALeafNode>().get() == this);
}
+ this->on_modify();
if (val.pladdr.is_paddr()) {
val.pladdr = maybe_generate_relative(val.pladdr.get_paddr());
}
iter.get_offset(),
addr,
(void*)nextent);
+ this->on_modify();
this->insert_child_ptr(iter, nextent);
if (val.pladdr.is_paddr()) {
val.pladdr = maybe_generate_relative(val.pladdr.get_paddr());
iter.get_offset(),
iter.get_key());
assert(iter != this->end());
+ this->on_modify();
this->remove_child_ptr(iter);
return this->journal_remove(
iter,
LBAMappingRef pin,
extent_types_t type)
{
- ceph_assert(pin->is_parent_valid());
+ ceph_assert(!pin->parent_modified());
auto v = pin->get_logical_extent(t);
// checking the lba child must be atomic with creating
// and linking the absent child