virtual get_child_ret_t<LogicalCachedExtent>
get_logical_child(op_context_t<node_key_t> c, uint16_t pos) = 0;
- virtual bool is_child_stable(uint16_t pos) const = 0;
+ virtual bool is_child_stable(op_context_t<node_key_t>, uint16_t pos) const = 0;
template <typename T, typename iter_t>
get_child_ret_t<T> get_child(op_context_t<node_key_t> c, iter_t iter) {
auto pos = iter.get_offset();
assert(children.capacity());
auto child = children[pos];
+ ceph_assert(!is_reserved_ptr(child));
if (is_valid_child_ptr(child)) {
ceph_assert(child->get_type() == T::TYPE);
return c.cache.template get_extent_viewable_by_trans<T>(c.trans, (T*)child);
return get_child_ret_t<LogicalCachedExtent>(child_pos_t(nullptr, 0));
}
- bool is_child_stable(uint16_t pos) const final {
+ bool is_child_stable(op_context_t<NODE_KEY>, uint16_t pos) const final {
ceph_abort("impossible");
return false;
}
// 2. The child extent is stable
//
// For reserved mappings, the return values are undefined.
- bool is_child_stable(uint16_t pos) const final {
+ bool is_child_stable(op_context_t<NODE_KEY> c, uint16_t pos) const final {
auto child = this->children[pos];
if (is_reserved_ptr(child)) {
return true;
} else if (is_valid_child_ptr(child)) {
ceph_assert(child->is_logical());
- return child->is_stable();
+ ceph_assert(
+ child->is_pending_in_trans(c.trans.get_trans_id())
+ || this->is_stable_written());
+ return c.cache.is_viewable_extent_stable(c.trans, child);
} else if (this->is_pending()) {
auto key = this->iter_idx(pos).get_key();
auto &sparent = this->get_stable_for_key(key);
auto child = sparent.children[spos];
if (is_valid_child_ptr(child)) {
ceph_assert(child->is_logical());
- return child->is_stable();
+ return c.cache.is_viewable_extent_stable(c.trans, child);
} else {
return true;
}
return get_absent_extent<T>(t, offset, length, [](T &){});
}
+ bool is_viewable_extent_stable(
+ Transaction &t,
+ CachedExtentRef extent)
+ {
+ assert(extent);
+ auto view = extent->get_transactional_view(t);
+ return view->is_stable();
+ }
+
using get_extent_ertr = base_ertr;
get_extent_ertr::future<CachedExtentRef>
get_extent_viewable_by_trans(
return last_committed_crc;
}
+ /// Returns true if the extent part of the open transaction
+ bool is_pending_in_trans(transaction_id_t id) const {
+ return is_pending() && pending_for_transaction == id;
+ }
+
private:
template <typename T>
friend class read_set_item_t;
ptr = nptr;
}
- /// Returns true if the extent part of the open transaction
- bool is_pending_in_trans(transaction_id_t id) const {
- return is_pending() && pending_for_transaction == id;
- }
-
/// hook for intrusive ref list (mainly dirty or lru list)
boost::intrusive::list_member_hook<> primary_ref_list_hook;
using primary_ref_list_member_options = boost::intrusive::member_hook<