|
4 | 4 | #include "crimson/os/seastore/btree/btree_types.h" |
5 | 5 | #include "crimson/os/seastore/lba/lba_btree_node.h" |
6 | 6 | #include "crimson/os/seastore/backref/backref_tree_node.h" |
| 7 | +#include "crimson/os/seastore/lba/btree_lba_manager.h" |
7 | 8 |
|
8 | 9 | namespace crimson::os::seastore { |
9 | 10 |
|
| 11 | +LBACursor::base_iertr::future<> LBACursor::refresh() |
| 12 | +{ |
| 13 | + LOG_PREFIX(LBACursor::refresh); |
| 14 | + return with_btree<lba::LBABtree>( |
| 15 | + ctx.cache, |
| 16 | + ctx, |
| 17 | + [this, FNAME, c=ctx](auto &btree) { |
| 18 | + c.trans.cursor_stats.num_refresh_parent_total++; |
| 19 | + |
| 20 | + if (!parent->is_valid()) { |
| 21 | + c.trans.cursor_stats.num_refresh_invalid_parent++; |
| 22 | + SUBTRACET( |
| 23 | + seastore_lba, |
| 24 | + "cursor {} parent is invalid, re-search from scratch", |
| 25 | + c.trans, *this); |
| 26 | + return btree.lower_bound(c, this->get_laddr() |
| 27 | + ).si_then([this](lba::LBABtree::iterator iter) { |
| 28 | + auto leaf = iter.get_leaf_node(); |
| 29 | + parent = leaf; |
| 30 | + modifications = leaf->modifications; |
| 31 | + pos = iter.get_leaf_pos(); |
| 32 | + if (!is_end()) { |
| 33 | + ceph_assert(!iter.is_end()); |
| 34 | + ceph_assert(iter.get_key() == get_laddr()); |
| 35 | + val = iter.get_val(); |
| 36 | + assert(is_viewable()); |
| 37 | + } |
| 38 | + }); |
| 39 | + } |
| 40 | + assert(parent->is_stable() || |
| 41 | + parent->is_pending_in_trans(c.trans.get_trans_id())); |
| 42 | + auto leaf = parent->cast<lba::LBALeafNode>(); |
| 43 | + if (leaf->is_pending_in_trans(c.trans.get_trans_id())) { |
| 44 | + if (leaf->modified_since(modifications)) { |
| 45 | + c.trans.cursor_stats.num_refresh_modified_viewable_parent++; |
| 46 | + } else { |
| 47 | + // no need to refresh |
| 48 | + return base_iertr::now(); |
| 49 | + } |
| 50 | + } else { |
| 51 | + auto [viewable, l] = leaf->resolve_transaction(c.trans, key); |
| 52 | + SUBTRACET( |
| 53 | + seastore_lba, |
| 54 | + "cursor: {} viewable: {}", |
| 55 | + c.trans, *this, viewable); |
| 56 | + if (!viewable) { |
| 57 | + leaf = l; |
| 58 | + c.trans.cursor_stats.num_refresh_unviewable_parent++; |
| 59 | + parent = leaf; |
| 60 | + } else { |
| 61 | + assert(leaf.get() == l.get()); |
| 62 | + assert(leaf->is_stable()); |
| 63 | + return base_iertr::now(); |
| 64 | + } |
| 65 | + } |
| 66 | + |
| 67 | + modifications = leaf->modifications; |
| 68 | + if (is_end()) { |
| 69 | + pos = leaf->get_size(); |
| 70 | + assert(!val); |
| 71 | + } else { |
| 72 | + auto i = leaf->lower_bound(get_laddr()); |
| 73 | + pos = i.get_offset(); |
| 74 | + val = i.get_val(); |
| 75 | + |
| 76 | + auto iter = lba::LBALeafNode::iterator(leaf.get(), pos); |
| 77 | + ceph_assert(iter.get_key() == key); |
| 78 | + ceph_assert(iter.get_val() == val); |
| 79 | + assert(is_viewable()); |
| 80 | + } |
| 81 | + |
| 82 | + return base_iertr::now(); |
| 83 | + }); |
| 84 | +} |
| 85 | + |
10 | 86 | namespace lba { |
11 | 87 |
|
12 | 88 | std::ostream& operator<<(std::ostream& out, const lba_map_val_t& v) |
@@ -58,7 +134,6 @@ bool BtreeCursor<key_t, val_t>::is_viewable() const { |
58 | 134 | } |
59 | 135 |
|
60 | 136 | auto [viewable, state] = parent->is_viewable_by_trans(ctx.trans); |
61 | | - assert(state != CachedExtent::viewable_state_t::invalid); |
62 | 137 | SUBTRACET(seastore_cache, "{} with viewable state {}", |
63 | 138 | ctx.trans, *parent, state); |
64 | 139 | return viewable; |
|
0 commit comments