Skip to content

Commit cb00a14

Browse files
authored
Merge pull request ceph#54036 from xxhdx1985126/wip-seastore-clone-remap-ut
crimson/os/seastore: add unittests for transaction manager's clone/remap/read_pin and fix bugs Reviewed-by: Yingxin Cheng <[email protected]> Reviewed-by: Myoungwon Oh <[email protected]>
2 parents a666cb4 + 4010045 commit cb00a14

File tree

17 files changed

+323
-118
lines changed

17 files changed

+323
-118
lines changed

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

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,16 @@ BtreeNodeMapping<key_t, val_t>::get_logical_extent(
2222
return v;
2323
}
2424

25+
template <typename key_t, typename val_t>
26+
bool BtreeNodeMapping<key_t, val_t>::is_stable() const
27+
{
28+
assert(parent);
29+
assert(parent->is_valid());
30+
assert(pos != std::numeric_limits<uint16_t>::max());
31+
auto &p = (FixedKVNode<key_t>&)*parent;
32+
return p.is_child_stable(pos);
33+
}
34+
2535
template class BtreeNodeMapping<laddr_t, paddr_t>;
2636
template class BtreeNodeMapping<paddr_t, laddr_t>;
2737
} // namespace crimson::os::seastore

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

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -153,10 +153,6 @@ class BtreeNodeMapping : public PhysicalNodeMapping<key_t, val_t> {
153153
return parent;
154154
}
155155

156-
void set_parent(CachedExtentRef ext) {
157-
parent = ext;
158-
}
159-
160156
uint16_t get_pos() const final {
161157
return pos;
162158
}
@@ -199,6 +195,7 @@ class BtreeNodeMapping : public PhysicalNodeMapping<key_t, val_t> {
199195
}
200196

201197
get_child_ret_t<LogicalCachedExtent> get_logical_extent(Transaction&) final;
198+
bool is_stable() const final;
202199
};
203200

204201
}

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

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -505,7 +505,9 @@ class FixedKVBtree {
505505
i->get_val().maybe_relative_to(node->get_paddr()),
506506
&child_node);
507507
} else {
508-
assert(i->get_val().pladdr.is_paddr());
508+
if (i->get_val().pladdr.is_laddr()) {
509+
continue;
510+
}
509511
ret = c.trans.get_extent(
510512
i->get_val().pladdr.get_paddr().maybe_relative_to(node->get_paddr()),
511513
&child_node);

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

Lines changed: 37 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -157,7 +157,7 @@ struct FixedKVNode : ChildableCachedExtent {
157157
(get_node_size() - offset - 1) * sizeof(ChildableCachedExtent*));
158158
}
159159

160-
FixedKVNode& get_stable_for_key(node_key_t key) {
160+
FixedKVNode& get_stable_for_key(node_key_t key) const {
161161
ceph_assert(is_pending());
162162
if (is_mutation_pending()) {
163163
return (FixedKVNode&)*get_prior_instance();
@@ -229,6 +229,8 @@ 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;
233+
232234
template <typename T, typename iter_t>
233235
get_child_ret_t<T> get_child(op_context_t<node_key_t> c, iter_t iter) {
234236
auto pos = iter.get_offset();
@@ -592,6 +594,11 @@ struct FixedKVInternalNode
592594
return get_child_ret_t<LogicalCachedExtent>(child_pos_t(nullptr, 0));
593595
}
594596

597+
bool is_child_stable(uint16_t pos) const final {
598+
ceph_abort("impossible");
599+
return false;
600+
}
601+
595602
bool validate_stable_children() final {
596603
LOG_PREFIX(FixedKVInternalNode::validate_stable_children);
597604
if (this->children.empty()) {
@@ -984,6 +991,35 @@ struct FixedKVLeafNode
984991
}
985992
}
986993

994+
// children are considered stable if any of the following case is true:
995+
// 1. Not in memory
996+
// 2. being stable
997+
// 3. being mutation pending and under-io
998+
bool is_child_stable(uint16_t pos) const final {
999+
auto child = this->children[pos];
1000+
if (is_valid_child_ptr(child)) {
1001+
ceph_assert(child->is_logical());
1002+
return child->is_stable() ||
1003+
(child->is_mutation_pending() &&
1004+
child->is_pending_io());
1005+
} else if (this->is_pending()) {
1006+
auto key = this->iter_idx(pos).get_key();
1007+
auto &sparent = this->get_stable_for_key(key);
1008+
auto spos = sparent.child_pos_for_key(key);
1009+
auto child = sparent.children[spos];
1010+
if (is_valid_child_ptr(child)) {
1011+
ceph_assert(child->is_logical());
1012+
return child->is_stable() ||
1013+
(child->is_mutation_pending() &&
1014+
child->is_pending_io());
1015+
} else {
1016+
return true;
1017+
}
1018+
} else {
1019+
return true;
1020+
}
1021+
}
1022+
9871023
bool validate_stable_children() override {
9881024
return true;
9891025
}

src/crimson/os/seastore/cached_extent.cc

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -158,8 +158,15 @@ parent_tracker_t::~parent_tracker_t() {
158158

159159
std::ostream &operator<<(std::ostream &out, const LBAMapping &rhs)
160160
{
161-
return out << "LBAMapping(" << rhs.get_key() << "~" << rhs.get_length()
162-
<< "->" << rhs.get_val();
161+
out << "LBAMapping(" << rhs.get_key() << "~" << rhs.get_length()
162+
<< "->" << rhs.get_val();
163+
if (rhs.is_indirect()) {
164+
out << " indirect(" << rhs.get_intermediate_base() << "~"
165+
<< rhs.get_intermediate_key() << "~"
166+
<< rhs.get_intermediate_length() << ")";
167+
}
168+
out << ")";
169+
return out;
163170
}
164171

165172
std::ostream &operator<<(std::ostream &out, const lba_pin_list_t &rhs)

src/crimson/os/seastore/cached_extent.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -595,7 +595,7 @@ class CachedExtent
595595

596596
// a rewrite extent has an invalid prior_instance,
597597
// and a mutation_pending extent has a valid prior_instance
598-
CachedExtentRef get_prior_instance() {
598+
CachedExtentRef get_prior_instance() const {
599599
return prior_instance;
600600
}
601601

@@ -1046,6 +1046,8 @@ class PhysicalNodeMapping {
10461046
child_pos->link_child(c);
10471047
}
10481048

1049+
virtual bool is_stable() const = 0;
1050+
10491051
virtual ~PhysicalNodeMapping() {}
10501052
protected:
10511053
std::optional<child_pos_t> child_pos = std::nullopt;

src/crimson/os/seastore/collection_manager/flat_collection_manager.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ FlatCollectionManager::create(coll_root_t &coll_root, Transaction &t,
8484
get_coll_context(t), cid, info.split_bits
8585
).si_then([=, this, &t](auto result) {
8686
assert(result == CollectionNode::create_result_t::SUCCESS);
87-
return tm.dec_ref(t, extent->get_laddr());
87+
return tm.remove(t, extent->get_laddr());
8888
}).si_then([] (auto) {
8989
return create_iertr::make_ready_future<>();
9090
});

src/crimson/os/seastore/lba_manager.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ class LBAManager {
8989
paddr_t addr,
9090
LogicalCachedExtent &nextent) = 0;
9191

92-
virtual alloc_extent_ret clone_extent(
92+
virtual alloc_extent_ret clone_mapping(
9393
Transaction &t,
9494
laddr_t hint,
9595
extent_len_t len,

src/crimson/os/seastore/lba_manager/btree/btree_lba_manager.cc

Lines changed: 35 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -197,7 +197,7 @@ BtreeLBAManager::_get_original_mappings(
197197
pin->get_key(), pin->get_length(),
198198
pin->get_raw_val().get_laddr());
199199
auto &btree_new_pin = static_cast<BtreeLBAMapping&>(*new_pin);
200-
btree_new_pin.set_key_for_indirect(
200+
btree_new_pin.make_indirect(
201201
pin->get_key(),
202202
pin->get_length(),
203203
pin->get_raw_val().get_laddr());
@@ -287,7 +287,7 @@ BtreeLBAManager::_get_mapping(
287287
c.trans, pin->get_raw_val().get_laddr()
288288
).si_then([&pin](auto new_pin) {
289289
ceph_assert(pin->get_length() == new_pin->get_length());
290-
new_pin->set_key_for_indirect(
290+
new_pin->make_indirect(
291291
pin->get_key(),
292292
pin->get_length());
293293
return new_pin;
@@ -307,7 +307,6 @@ BtreeLBAManager::_alloc_extent(
307307
extent_len_t len,
308308
pladdr_t addr,
309309
paddr_t actual_addr,
310-
laddr_t intermediate_base,
311310
LogicalCachedExtent* nextent)
312311
{
313312
struct state_t {
@@ -321,6 +320,8 @@ BtreeLBAManager::_alloc_extent(
321320

322321
LOG_PREFIX(BtreeLBAManager::_alloc_extent);
323322
TRACET("{}~{}, hint={}", t, addr, len, hint);
323+
324+
ceph_assert(actual_addr != P_ADDR_NULL ? addr.is_laddr() : addr.is_paddr());
324325
auto c = get_context(t);
325326
++stats.num_alloc_extents;
326327
auto lookup_attempts = stats.num_alloc_extents_iter_nexts;
@@ -384,17 +385,9 @@ BtreeLBAManager::_alloc_extent(
384385
state.ret = iter;
385386
});
386387
});
387-
}).si_then([c, actual_addr, addr, intermediate_base](auto &&state) {
388-
auto ret_pin = state.ret->get_pin(c);
389-
if (actual_addr != P_ADDR_NULL) {
390-
ceph_assert(addr.is_laddr());
391-
ret_pin->set_paddr(actual_addr);
392-
ret_pin->set_intermediate_base(intermediate_base);
393-
} else {
394-
ceph_assert(addr.is_paddr());
395-
}
396-
return alloc_extent_iertr::make_ready_future<LBAMappingRef>(
397-
std::move(ret_pin));
388+
}).si_then([c](auto &&state) {
389+
return alloc_extent_iertr::make_ready_future<
390+
LBAMappingRef>(state.ret->get_pin(c));
398391
});
399392
}
400393

@@ -496,7 +489,9 @@ BtreeLBAManager::scan_mappings(
496489
seastar::stop_iteration::yes);
497490
}
498491
ceph_assert((pos.get_key() + pos.get_val().len) > begin);
499-
f(pos.get_key(), pos.get_val().pladdr.get_paddr(), pos.get_val().len);
492+
if (pos.get_val().pladdr.is_paddr()) {
493+
f(pos.get_key(), pos.get_val().pladdr.get_paddr(), pos.get_val().len);
494+
}
500495
return LBABtree::iterate_repeat_ret_inner(
501496
interruptible::ready_future_marker{},
502497
seastar::stop_iteration::no);
@@ -554,7 +549,8 @@ BtreeLBAManager::update_mapping(
554549
return ret;
555550
},
556551
nextent
557-
).si_then([&t, laddr, prev_addr, addr, FNAME](auto result) {
552+
).si_then([&t, laddr, prev_addr, addr, FNAME](auto p) {
553+
auto &result = p.first;
558554
DEBUGT("laddr={}, paddr {} => {} done -- {}",
559555
t, laddr, prev_addr, addr, result);
560556
},
@@ -685,7 +681,9 @@ BtreeLBAManager::update_refcount(
685681
return out;
686682
},
687683
nullptr
688-
).si_then([&t, addr, delta, FNAME, this, cascade_remove](auto result) {
684+
).si_then([&t, addr, delta, FNAME, this, cascade_remove](auto p) {
685+
auto &result = p.first;
686+
auto &mapping = p.second;
689687
DEBUGT("laddr={}, delta={} done -- {}", t, addr, delta, result);
690688
auto fut = ref_iertr::make_ready_future<
691689
std::optional<std::pair<paddr_t, extent_len_t>>>();
@@ -696,19 +694,23 @@ BtreeLBAManager::update_refcount(
696694
result.len
697695
);
698696
}
699-
return fut.si_then([result](auto removed) {
697+
return fut.si_then([result, mapping=std::move(mapping)]
698+
(auto removed) mutable {
700699
if (result.pladdr.is_laddr()
701700
&& removed) {
702-
return ref_update_result_t{
703-
result.refcount,
704-
removed->first,
705-
removed->second};
701+
return std::make_pair(
702+
ref_update_result_t{
703+
result.refcount,
704+
removed->first,
705+
removed->second},
706+
std::move(mapping));
706707
} else {
707-
return ref_update_result_t{
708-
result.refcount,
709-
result.pladdr,
710-
result.len
711-
};
708+
return std::make_pair(
709+
ref_update_result_t{
710+
result.refcount,
711+
result.pladdr,
712+
result.len},
713+
std::move(mapping));
712714
}
713715
});
714716
});
@@ -722,7 +724,7 @@ BtreeLBAManager::_update_mapping(
722724
LogicalCachedExtent* nextent)
723725
{
724726
auto c = get_context(t);
725-
return with_btree_ret<LBABtree, lba_map_val_t>(
727+
return with_btree_ret<LBABtree, _update_mapping_ret_bare>(
726728
cache,
727729
c,
728730
[f=std::move(f), c, addr, nextent](auto &btree) mutable {
@@ -742,16 +744,18 @@ BtreeLBAManager::_update_mapping(
742744
c,
743745
iter
744746
).si_then([ret] {
745-
return ret;
747+
return std::make_pair(
748+
std::move(ret), BtreeLBAMappingRef(nullptr));
746749
});
747750
} else {
748751
return btree.update(
749752
c,
750753
iter,
751754
ret,
752755
nextent
753-
).si_then([ret](auto) {
754-
return ret;
756+
).si_then([c, ret](auto iter) {
757+
return std::make_pair(
758+
std::move(ret), iter.get_pin(c));
755759
});
756760
}
757761
});

0 commit comments

Comments
 (0)