Skip to content

Commit e143d4a

Browse files
authored
Merge pull request ceph#56246 from xxhdx1985126/wip-64957
crimson/os/seastore/btree: check for reserved ptrs when determining children stability Reviewed-by: Yingxin Cheng <[email protected]> Reviewed-by: Chunmei Liu <[email protected]>
2 parents 8282158 + 7dcd74a commit e143d4a

File tree

6 files changed

+48
-17
lines changed

6 files changed

+48
-17
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_btree.h

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,6 @@
1515
#include "crimson/os/seastore/btree/btree_range_pin.h"
1616
#include "crimson/os/seastore/root_block.h"
1717

18-
#define RESERVATION_PTR reinterpret_cast<ChildableCachedExtent*>(0x1)
19-
2018
namespace crimson::os::seastore::lba_manager::btree {
2119
struct lba_map_val_t;
2220
}
@@ -25,6 +23,12 @@ namespace crimson::os::seastore {
2523

2624
bool is_valid_child_ptr(ChildableCachedExtent* child);
2725

26+
bool is_reserved_ptr(ChildableCachedExtent* child);
27+
28+
inline ChildableCachedExtent* get_reserved_ptr() {
29+
return (ChildableCachedExtent*)0x1;
30+
}
31+
2832
template <typename T>
2933
phy_tree_root_t& get_phy_tree_root(root_t& r);
3034

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

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,11 @@
66
namespace crimson::os::seastore {
77

88
bool is_valid_child_ptr(ChildableCachedExtent* child) {
9-
return child != nullptr && child != RESERVATION_PTR;
9+
return child != nullptr && child != get_reserved_ptr();
10+
}
11+
12+
bool is_reserved_ptr(ChildableCachedExtent* child) {
13+
return child == get_reserved_ptr();
1014
}
1115

1216
} // namespace crimson::os::seastore

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

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -134,7 +134,7 @@ struct FixedKVNode : ChildableCachedExtent {
134134
// copy sources when committing this lba node, because
135135
// we rely on pointers' "nullness" to avoid copying
136136
// pointers for updated values
137-
children[offset] = RESERVATION_PTR;
137+
children[offset] = get_reserved_ptr();
138138
}
139139
}
140140

@@ -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);
@@ -431,7 +432,7 @@ struct FixedKVNode : ChildableCachedExtent {
431432
if (!child) {
432433
child = source.children[foreign_it.get_offset()];
433434
// child can be either valid if present, nullptr if absent,
434-
// or RESERVATION_PTR.
435+
// or reserved ptr.
435436
}
436437
foreign_it++;
437438
local_it++;
@@ -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
}
@@ -972,6 +973,7 @@ struct FixedKVLeafNode
972973
get_child_ret_t<LogicalCachedExtent>
973974
get_logical_child(op_context_t<NODE_KEY> c, uint16_t pos) final {
974975
auto child = this->children[pos];
976+
ceph_assert(!is_reserved_ptr(child));
975977
if (is_valid_child_ptr(child)) {
976978
ceph_assert(child->is_logical());
977979
return c.cache.template get_extent_viewable_by_trans<
@@ -996,19 +998,26 @@ struct FixedKVLeafNode
996998
// children are considered stable if any of the following case is true:
997999
// 1. The child extent is absent in cache
9981000
// 2. The child extent is stable
999-
bool is_child_stable(uint16_t pos) const final {
1001+
//
1002+
// For reserved mappings, the return values are undefined.
1003+
bool is_child_stable(op_context_t<NODE_KEY> c, uint16_t pos) const final {
10001004
auto child = this->children[pos];
1001-
if (is_valid_child_ptr(child)) {
1005+
if (is_reserved_ptr(child)) {
1006+
return true;
1007+
} else if (is_valid_child_ptr(child)) {
10021008
ceph_assert(child->is_logical());
1003-
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);
10041013
} else if (this->is_pending()) {
10051014
auto key = this->iter_idx(pos).get_key();
10061015
auto &sparent = this->get_stable_for_key(key);
10071016
auto spos = sparent.child_pos_for_key(key);
10081017
auto child = sparent.children[spos];
10091018
if (is_valid_child_ptr(child)) {
10101019
ceph_assert(child->is_logical());
1011-
return child->is_stable();
1020+
return c.cache.is_viewable_extent_stable(c.trans, child);
10121021
} else {
10131022
return true;
10141023
}

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: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -426,6 +426,9 @@ class CachedExtent
426426
/// Returns true if extent is stable and shared among transactions
427427
bool is_stable() const {
428428
return is_stable_written() ||
429+
// MUTATION_PENDING and under-io extents are to-be-stable extents,
430+
// for the sake of caveats that checks the correctness of extents
431+
// states, we consider them stable.
429432
(is_mutation_pending() &&
430433
is_pending_io());
431434
}
@@ -615,6 +618,11 @@ class CachedExtent
615618
return last_committed_crc;
616619
}
617620

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+
618626
private:
619627
template <typename T>
620628
friend class read_set_item_t;
@@ -645,11 +653,6 @@ class CachedExtent
645653
ptr = nptr;
646654
}
647655

648-
/// Returns true if the extent part of the open transaction
649-
bool is_pending_in_trans(transaction_id_t id) const {
650-
return is_pending() && pending_for_transaction == id;
651-
}
652-
653656
/// hook for intrusive ref list (mainly dirty or lru list)
654657
boost::intrusive::list_member_hook<> primary_ref_list_hook;
655658
using primary_ref_list_member_options = boost::intrusive::member_hook<
@@ -1062,6 +1065,8 @@ class PhysicalNodeMapping {
10621065
child_pos->link_child(c);
10631066
}
10641067

1068+
// For reserved mappings, the return values are
1069+
// undefined although it won't crash
10651070
virtual bool is_stable() const = 0;
10661071
virtual bool is_clone() const = 0;
10671072
bool is_zero_reserved() const {

0 commit comments

Comments
 (0)