Skip to content

Commit 7dcd74a

Browse files
committed
crimson/os/seastore/btree: always check the stability of extents within
the current transaction's view Signed-off-by: Xuehan Xu <[email protected]>
1 parent b1c59ca commit 7dcd74a

File tree

4 files changed

+24
-11
lines changed

4 files changed

+24
-11
lines changed

src/crimson/os/seastore/btree/btree_range_pin.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ bool BtreeNodeMapping<key_t, val_t>::is_stable() const
2929
assert(parent->is_valid());
3030
assert(pos != std::numeric_limits<uint16_t>::max());
3131
auto &p = (FixedKVNode<key_t>&)*parent;
32-
return p.is_child_stable(pos);
32+
return p.is_child_stable(ctx, pos);
3333
}
3434

3535
template class BtreeNodeMapping<laddr_t, paddr_t>;

src/crimson/os/seastore/btree/fixed_kv_node.h

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -229,13 +229,14 @@ struct FixedKVNode : ChildableCachedExtent {
229229
virtual get_child_ret_t<LogicalCachedExtent>
230230
get_logical_child(op_context_t<node_key_t> c, uint16_t pos) = 0;
231231

232-
virtual bool is_child_stable(uint16_t pos) const = 0;
232+
virtual bool is_child_stable(op_context_t<node_key_t>, uint16_t pos) const = 0;
233233

234234
template <typename T, typename iter_t>
235235
get_child_ret_t<T> get_child(op_context_t<node_key_t> c, iter_t iter) {
236236
auto pos = iter.get_offset();
237237
assert(children.capacity());
238238
auto child = children[pos];
239+
ceph_assert(!is_reserved_ptr(child));
239240
if (is_valid_child_ptr(child)) {
240241
ceph_assert(child->get_type() == T::TYPE);
241242
return c.cache.template get_extent_viewable_by_trans<T>(c.trans, (T*)child);
@@ -596,7 +597,7 @@ struct FixedKVInternalNode
596597
return get_child_ret_t<LogicalCachedExtent>(child_pos_t(nullptr, 0));
597598
}
598599

599-
bool is_child_stable(uint16_t pos) const final {
600+
bool is_child_stable(op_context_t<NODE_KEY>, uint16_t pos) const final {
600601
ceph_abort("impossible");
601602
return false;
602603
}
@@ -999,21 +1000,24 @@ struct FixedKVLeafNode
9991000
// 2. The child extent is stable
10001001
//
10011002
// For reserved mappings, the return values are undefined.
1002-
bool is_child_stable(uint16_t pos) const final {
1003+
bool is_child_stable(op_context_t<NODE_KEY> c, uint16_t pos) const final {
10031004
auto child = this->children[pos];
10041005
if (is_reserved_ptr(child)) {
10051006
return true;
10061007
} else if (is_valid_child_ptr(child)) {
10071008
ceph_assert(child->is_logical());
1008-
return child->is_stable();
1009+
ceph_assert(
1010+
child->is_pending_in_trans(c.trans.get_trans_id())
1011+
|| this->is_stable_written());
1012+
return c.cache.is_viewable_extent_stable(c.trans, child);
10091013
} else if (this->is_pending()) {
10101014
auto key = this->iter_idx(pos).get_key();
10111015
auto &sparent = this->get_stable_for_key(key);
10121016
auto spos = sparent.child_pos_for_key(key);
10131017
auto child = sparent.children[spos];
10141018
if (is_valid_child_ptr(child)) {
10151019
ceph_assert(child->is_logical());
1016-
return child->is_stable();
1020+
return c.cache.is_viewable_extent_stable(c.trans, child);
10171021
} else {
10181022
return true;
10191023
}

src/crimson/os/seastore/cache.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -443,6 +443,15 @@ class Cache {
443443
return get_absent_extent<T>(t, offset, length, [](T &){});
444444
}
445445

446+
bool is_viewable_extent_stable(
447+
Transaction &t,
448+
CachedExtentRef extent)
449+
{
450+
assert(extent);
451+
auto view = extent->get_transactional_view(t);
452+
return view->is_stable();
453+
}
454+
446455
using get_extent_ertr = base_ertr;
447456
get_extent_ertr::future<CachedExtentRef>
448457
get_extent_viewable_by_trans(

src/crimson/os/seastore/cached_extent.h

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -618,6 +618,11 @@ class CachedExtent
618618
return last_committed_crc;
619619
}
620620

621+
/// Returns true if the extent part of the open transaction
622+
bool is_pending_in_trans(transaction_id_t id) const {
623+
return is_pending() && pending_for_transaction == id;
624+
}
625+
621626
private:
622627
template <typename T>
623628
friend class read_set_item_t;
@@ -648,11 +653,6 @@ class CachedExtent
648653
ptr = nptr;
649654
}
650655

651-
/// Returns true if the extent part of the open transaction
652-
bool is_pending_in_trans(transaction_id_t id) const {
653-
return is_pending() && pending_for_transaction == id;
654-
}
655-
656656
/// hook for intrusive ref list (mainly dirty or lru list)
657657
boost::intrusive::list_member_hook<> primary_ref_list_hook;
658658
using primary_ref_list_member_options = boost::intrusive::member_hook<

0 commit comments

Comments
 (0)