Skip to content

Commit 89d1065

Browse files
zhscnMatan-B
authored andcommitted
crimson/os/seastore/BtreeLBAManager: support refresh LBAMapping
Signed-off-by: Zhang Song <[email protected]> (cherry picked from commit dca4e56)
1 parent 1dbdc3e commit 89d1065

File tree

7 files changed

+152
-48
lines changed

7 files changed

+152
-48
lines changed

src/crimson/os/seastore/lba_manager.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -230,6 +230,12 @@ class LBAManager {
230230
laddr_t laddr,
231231
extent_len_t len) = 0;
232232

233+
using refresh_lba_mapping_iertr = base_iertr;
234+
using refresh_lba_mapping_ret = refresh_lba_mapping_iertr::future<LBAMapping>;
235+
virtual refresh_lba_mapping_ret refresh_lba_mapping(
236+
Transaction &t,
237+
LBAMapping mapping) = 0;
238+
233239
virtual ~LBAManager() {}
234240
};
235241
using LBAManagerRef = std::unique_ptr<LBAManager>;

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

Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -721,6 +721,100 @@ BtreeLBAManager::get_physical_extent_if_live(
721721
});
722722
}
723723

724+
BtreeLBAManager::refresh_lba_mapping_ret
725+
BtreeLBAManager::refresh_lba_mapping(Transaction &t, LBAMapping mapping)
726+
{
727+
assert(mapping.is_linked_direct());
728+
if (mapping.is_viewable()) {
729+
return refresh_lba_mapping_iertr::make_ready_future<
730+
LBAMapping>(std::move(mapping));
731+
}
732+
auto c = get_context(t);
733+
return with_btree_state<LBABtree, LBAMapping>(
734+
cache,
735+
c,
736+
std::move(mapping),
737+
[c, this](LBABtree &btree, LBAMapping &mapping) mutable
738+
{
739+
return refresh_lba_cursor(c, btree, *mapping.direct_cursor
740+
).si_then([c, this, &btree, &mapping] {
741+
if (mapping.indirect_cursor) {
742+
return refresh_lba_cursor(c, btree, *mapping.indirect_cursor);
743+
}
744+
return refresh_lba_cursor_iertr::make_ready_future();
745+
#ifndef NDEBUG
746+
}).si_then([&mapping] {
747+
assert(mapping.is_viewable());
748+
#endif
749+
});
750+
});
751+
}
752+
753+
BtreeLBAManager::refresh_lba_cursor_ret
754+
BtreeLBAManager::refresh_lba_cursor(
755+
op_context_t c,
756+
LBABtree &btree,
757+
LBACursor &cursor)
758+
{
759+
LOG_PREFIX(BtreeLBAManager::refresh_lba_cursor);
760+
stats.num_refresh_parent_total++;
761+
762+
if (!cursor.parent->is_valid()) {
763+
stats.num_refresh_invalid_parent++;
764+
TRACET("cursor {} parent is invalid, re-search from scratch",
765+
c.trans, cursor);
766+
return btree.lower_bound(c, cursor.get_laddr()
767+
).si_then([&cursor](LBABtree::iterator iter) {
768+
auto leaf = iter.get_leaf_node();
769+
cursor.parent = leaf;
770+
cursor.modifications = leaf->modifications;
771+
cursor.pos = iter.get_leaf_pos();
772+
if (!cursor.is_end()) {
773+
ceph_assert(!iter.is_end());
774+
ceph_assert(iter.get_key() == cursor.get_laddr());
775+
cursor.val = iter.get_val();
776+
assert(cursor.is_viewable());
777+
}
778+
});
779+
}
780+
781+
auto [viewable, state] = cursor.parent->is_viewable_by_trans(c.trans);
782+
auto leaf = cursor.parent->cast<LBALeafNode>();
783+
784+
TRACET("cursor: {} viewable: {} state: {}",
785+
c.trans, cursor, viewable, state);
786+
787+
if (!viewable) {
788+
stats.num_refresh_unviewable_parent++;
789+
leaf = leaf->find_pending_version(c.trans, cursor.get_laddr());
790+
cursor.parent = leaf;
791+
}
792+
793+
if (!viewable ||
794+
leaf->modified_since(cursor.modifications)) {
795+
if (viewable) {
796+
stats.num_refresh_modified_viewable_parent++;
797+
}
798+
799+
cursor.modifications = leaf->modifications;
800+
if (cursor.is_end()) {
801+
cursor.pos = leaf->get_size();
802+
assert(!cursor.val);
803+
} else {
804+
auto i = leaf->lower_bound(cursor.get_laddr());
805+
cursor.pos = i.get_offset();
806+
cursor.val = i.get_val();
807+
808+
auto iter = LBALeafNode::iterator(leaf.get(), cursor.pos);
809+
ceph_assert(iter.get_key() == cursor.key);
810+
ceph_assert(iter.get_val() == cursor.val);
811+
assert(cursor.is_viewable());
812+
}
813+
}
814+
815+
return refresh_lba_cursor_iertr::make_ready_future();
816+
}
817+
724818
void BtreeLBAManager::register_metrics()
725819
{
726820
LOG_PREFIX(BtreeLBAManager::register_metrics);
@@ -740,6 +834,26 @@ void BtreeLBAManager::register_metrics()
740834
stats.num_alloc_extents_iter_nexts,
741835
sm::description("total number of iterator next operations during extent allocation")
742836
),
837+
sm::make_counter(
838+
"refresh_parent_total",
839+
stats.num_refresh_parent_total,
840+
sm::description("total number of refreshed cursors")
841+
),
842+
sm::make_counter(
843+
"refresh_invalid_parent",
844+
stats.num_refresh_invalid_parent,
845+
sm::description("total number of refreshed cursors with invalid parents")
846+
),
847+
sm::make_counter(
848+
"refresh_unviewable_parent",
849+
stats.num_refresh_unviewable_parent,
850+
sm::description("total number of refreshed cursors with unviewable parents")
851+
),
852+
sm::make_counter(
853+
"refresh_modified_viewable_parent",
854+
stats.num_refresh_modified_viewable_parent,
855+
sm::description("total number of refreshed cursors with viewable but modified parents")
856+
),
743857
}
744858
);
745859
}

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

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -263,12 +263,21 @@ class BtreeLBAManager : public LBAManager {
263263
paddr_t addr,
264264
laddr_t laddr,
265265
extent_len_t len) final;
266+
267+
refresh_lba_mapping_ret refresh_lba_mapping(
268+
Transaction &t,
269+
LBAMapping mapping) final;
270+
266271
private:
267272
Cache &cache;
268273

269274
struct {
270275
uint64_t num_alloc_extents = 0;
271276
uint64_t num_alloc_extents_iter_nexts = 0;
277+
uint64_t num_refresh_parent_total = 0;
278+
uint64_t num_refresh_invalid_parent = 0;
279+
uint64_t num_refresh_unviewable_parent = 0;
280+
uint64_t num_refresh_modified_viewable_parent = 0;
272281
} stats;
273282

274283
struct alloc_mapping_info_t {
@@ -510,6 +519,13 @@ class BtreeLBAManager : public LBAManager {
510519
Transaction &t,
511520
laddr_t addr,
512521
extent_len_t len);
522+
523+
using refresh_lba_cursor_iertr = base_iertr;
524+
using refresh_lba_cursor_ret = refresh_lba_cursor_iertr::future<>;
525+
refresh_lba_cursor_ret refresh_lba_cursor(
526+
op_context_t c,
527+
LBABtree &btree,
528+
LBACursor &cursor);
513529
};
514530
using BtreeLBAManagerRef = std::unique_ptr<BtreeLBAManager>;
515531

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

Lines changed: 0 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -44,39 +44,6 @@ void LBALeafNode::resolve_relative_addrs(paddr_t base)
4444
}
4545
}
4646

47-
void LBALeafNode::maybe_fix_mapping_pos(BtreeLBAMapping &mapping)
48-
{
49-
assert(mapping.get_parent() == this);
50-
auto key = mapping.is_indirect()
51-
? mapping.get_intermediate_base()
52-
: mapping.get_key();
53-
if (key != iter_idx(mapping.get_pos()).get_key()) {
54-
auto iter = lower_bound(key);
55-
{
56-
// a mapping that no longer exist or has its value
57-
// modified is considered an outdated one, and
58-
// shouldn't be used anymore
59-
ceph_assert(iter != end());
60-
assert(iter.get_val() == mapping.get_map_val());
61-
}
62-
mapping._new_pos(iter.get_offset());
63-
}
64-
}
65-
66-
BtreeLBAMappingRef LBALeafNode::get_mapping(
67-
op_context_t c, laddr_t laddr)
68-
{
69-
auto iter = lower_bound(laddr);
70-
ceph_assert(iter != end() && iter->get_key() == laddr);
71-
auto val = iter.get_val();
72-
return std::make_unique<BtreeLBAMapping>(
73-
c,
74-
this,
75-
iter.get_offset(),
76-
val,
77-
lba_node_meta_t{laddr, (laddr + val.len).checked_to_laddr(), 0});
78-
}
79-
8047
void LBALeafNode::update(
8148
internal_const_iterator_t iter,
8249
lba_map_val_t val)

src/crimson/os/seastore/lba_manager/btree/lba_btree_node.h

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -278,9 +278,6 @@ struct LBALeafNode
278278
}
279279

280280
std::ostream &print_detail(std::ostream &out) const final;
281-
282-
void maybe_fix_mapping_pos(BtreeLBAMapping &mapping);
283-
std::unique_ptr<BtreeLBAMapping> get_mapping(op_context_t c, laddr_t laddr);
284281
};
285282
using LBALeafNodeRef = TCachedExtentRef<LBALeafNode>;
286283

src/crimson/os/seastore/transaction_manager.h

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -277,10 +277,9 @@ class TransactionManager : public ExtentCallbackInterface {
277277
SUBDEBUGT(seastore_tm, "{} {} 0x{:x}~0x{:x} direct_off=0x{:x} ...",
278278
t, T::TYPE, pin, partial_off, partial_len, direct_partial_off);
279279

280-
auto fut = base_iertr::make_ready_future<LBAMapping>();
281-
// TODO: refresh pin
282-
return fut.si_then([&t, this, direct_partial_off, partial_len,
283-
maybe_init=std::move(maybe_init)](auto npin) mutable {
280+
return lba_manager->refresh_lba_mapping(t, std::move(pin)
281+
).si_then([&t, this, direct_partial_off, partial_len,
282+
maybe_init=std::move(maybe_init)](auto npin) mutable {
284283
// checking the lba child must be atomic with creating
285284
// and linking the absent child
286285
auto ret = get_extent_if_linked<T>(t, std::move(npin));
@@ -525,12 +524,12 @@ class TransactionManager : public ExtentCallbackInterface {
525524
t, original_laddr, original_len, original_paddr, remaps.size(), pin);
526525
// The according extent might be stable or pending.
527526
auto fut = base_iertr::now();
528-
if (!pin->is_indirect()) {
529-
ceph_assert(!pin->is_clone());
530-
531-
// TODO: refresh pin
532-
533-
fut = fut.si_then([this, &t, &pin] {
527+
if (!pin.is_indirect()) {
528+
ceph_assert(!pin.is_clone());
529+
fut = fut.si_then([this, &t, &pin]() mutable {
530+
return lba_manager->refresh_lba_mapping(t, std::move(pin));
531+
}).si_then([this, &t, &pin](auto newpin) {
532+
pin = std::move(newpin);
534533
if (full_extent_integrity_check) {
535534
return read_pin<T>(t, pin.duplicate()
536535
).si_then([](auto maybe_indirect_extent) {

src/test/crimson/seastore/test_transaction_manager.cc

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -726,6 +726,12 @@ struct transaction_manager_test_t :
726726
}).unsafe_get();
727727
}
728728

729+
LBAMapping refresh_lba_mapping(test_transaction_t &t, LBAMapping mapping) {
730+
return with_trans_intr(*t.t, [this, mapping=std::move(mapping)](auto &t) mutable {
731+
return lba_manager->refresh_lba_mapping(t, std::move(mapping));
732+
}).unsafe_get();
733+
}
734+
729735
bool try_submit_transaction(test_transaction_t t) {
730736
using ertr = with_trans_ertr<TransactionManager::submit_transaction_iertr>;
731737
using ret = ertr::future<bool>;
@@ -2135,8 +2141,7 @@ TEST_P(tm_single_device_test_t, invalid_lba_mapping_detect)
21352141
assert(pin.is_viewable());
21362142
std::ignore = alloc_extent(t, get_laddr_hint((LEAF_NODE_CAPACITY + 1) * 4096), 4096, 'a');
21372143
assert(!pin.is_viewable());
2138-
// TODO: refresh pin
2139-
// pin->maybe_fix_pos();
2144+
pin = refresh_lba_mapping(t, pin.duplicate());
21402145
auto extent2 = with_trans_intr(*(t.t), [&pin](auto& trans) {
21412146
auto v = pin.get_logical_extent(trans);
21422147
assert(v.has_child());

0 commit comments

Comments
 (0)