}
return !is_unviewable_by_trans(*parent, ctx.trans);
}
+ bool is_parent_valid() const final {
+ ceph_assert(parent);
+ return parent->is_valid();
+ }
};
}
copy_dests.dests_by_key.erase(dest);
}
+ FixedKVNodeRef find_pending_version(Transaction &t, node_key_t key) {
+ assert(is_stable());
+ auto mut_iter = mutation_pendings.find(
+ t.get_trans_id(), trans_spec_view_t::cmp_t());
+ if (mut_iter != mutation_pendings.end()) {
+ assert(copy_dests_by_trans.find(t.get_trans_id()) ==
+ copy_dests_by_trans.end());
+ return (FixedKVNode*)(&(*mut_iter));
+ }
+ auto iter = copy_dests_by_trans.find(
+ t.get_trans_id(), trans_spec_view_t::cmp_t());
+ ceph_assert(iter != copy_dests_by_trans.end());
+ auto ©_dests = static_cast<copy_dests_t&>(*iter);
+ auto it = copy_dests.dests_by_key.lower_bound(key);
+ if ((*it)->range.begin > key) {
+ ceph_assert(it != copy_dests.dests_by_key.begin());
+ --it;
+ }
+ ceph_assert((*it)->range.begin <= key && key < (*it)->range.end);
+ return *it;
+ }
+
bool is_linked() {
assert(!has_parent_tracker() || !(bool)root_block);
return (bool)has_parent_tracker() || (bool)root_block;
virtual val_t get_val() const = 0;
virtual key_t get_key() const = 0;
virtual PhysicalNodeMappingRef<key_t, val_t> duplicate() const = 0;
+ virtual PhysicalNodeMappingRef<key_t, val_t> refresh_with_pending_parent() {
+ ceph_abort("impossible");
+ return {};
+ }
virtual bool has_been_invalidated() const = 0;
virtual CachedExtentRef get_parent() const = 0;
virtual uint16_t get_pos() const = 0;
return !get_val().is_real();
}
virtual bool is_parent_viewable() const = 0;
+ virtual bool is_parent_valid() const = 0;
virtual bool parent_modified() const {
ceph_abort("impossible");
return false;
auto &p = static_cast<LBALeafNode&>(*parent);
p.maybe_fix_mapping_pos(*this);
}
+
+ LBAMappingRef refresh_with_pending_parent() final {
+ assert(is_parent_valid() && !is_parent_viewable());
+ auto &p = static_cast<LBALeafNode&>(*parent);
+ auto &viewable_p = static_cast<LBALeafNode&>(
+ *p.find_pending_version(ctx.trans, get_key()));
+ return viewable_p.get_mapping(ctx, get_key());
+ }
protected:
std::unique_ptr<BtreeNodeMapping<laddr_t, paddr_t>> _duplicate(
op_context_t<laddr_t> ctx) const final {
}
}
+BtreeLBAMappingRef LBALeafNode::get_mapping(
+ op_context_t<laddr_t> c, laddr_t laddr)
+{
+ auto iter = lower_bound(laddr);
+ ceph_assert(iter != end() && iter->get_key() == laddr);
+ auto val = iter.get_val();
+ return std::make_unique<BtreeLBAMapping>(
+ c,
+ this,
+ iter.get_offset(),
+ val,
+ lba_node_meta_t{laddr, val.len, 0});
+}
+
}
std::ostream &_print_detail(std::ostream &out) const final;
void maybe_fix_mapping_pos(BtreeLBAMapping &mapping);
+ std::unique_ptr<BtreeLBAMapping> get_mapping(op_context_t<laddr_t> c, laddr_t laddr);
};
using LBALeafNodeRef = TCachedExtentRef<LBALeafNode>;
{
auto fut = base_iertr::make_ready_future<LBAMappingRef>();
if (!pin->is_parent_viewable()) {
- fut = get_pin(t, pin->get_key()
- ).handle_error_interruptible(
- crimson::ct_error::enoent::assert_failure{"unexpected enoent"},
- crimson::ct_error::input_output_error::pass_further{}
- );
+ if (pin->is_parent_valid()) {
+ pin = pin->refresh_with_pending_parent();
+ fut = base_iertr::make_ready_future<LBAMappingRef>(std::move(pin));
+ } else {
+ fut = get_pin(t, pin->get_key()
+ ).handle_error_interruptible(
+ crimson::ct_error::enoent::assert_failure{"unexpected enoent"},
+ crimson::ct_error::input_output_error::pass_further{}
+ );
+ }
} else {
pin->maybe_fix_pos();
fut = base_iertr::make_ready_future<LBAMappingRef>(std::move(pin));
auto fut = base_iertr::now();
if (!pin->is_indirect()) {
if (!pin->is_parent_viewable()) {
- fut = get_pin(t, pin->get_key()
- ).si_then([&pin](auto npin) {
- assert(npin);
- pin = std::move(npin);
- return seastar::now();
- }).handle_error_interruptible(
- crimson::ct_error::enoent::assert_failure{"unexpected enoent"},
- crimson::ct_error::input_output_error::pass_further{}
- );
+ if (pin->is_parent_valid()) {
+ pin = pin->refresh_with_pending_parent();
+ } else {
+ fut = get_pin(t, pin->get_key()
+ ).si_then([&pin](auto npin) {
+ assert(npin);
+ pin = std::move(npin);
+ return seastar::now();
+ }).handle_error_interruptible(
+ crimson::ct_error::enoent::assert_failure{"unexpected enoent"},
+ crimson::ct_error::input_output_error::pass_further{}
+ );
+ }
} else {
pin->maybe_fix_pos();
}