Skip to content

Commit a6cf5bb

Browse files
committed
crimson/os/seastore/cached_extent: add the "refresh" ability to lba
mappings So that we don't have to re-iterate through the whole lba tree to get a "parent-viewable" mapping in most cases. Signed-off-by: Xuehan Xu <[email protected]>
1 parent 077cedf commit a6cf5bb

File tree

7 files changed

+77
-14
lines changed

7 files changed

+77
-14
lines changed

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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -225,6 +225,10 @@ class BtreeNodeMapping : public PhysicalNodeMapping<key_t, val_t> {
225225
}
226226
return !is_unviewable_by_trans(*parent, ctx.trans);
227227
}
228+
bool is_parent_valid() const final {
229+
ceph_assert(parent);
230+
return parent->is_valid();
231+
}
228232
};
229233

230234
}

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

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,28 @@ struct FixedKVNode : ChildableCachedExtent {
134134
copy_dests.dests_by_key.erase(dest);
135135
}
136136

137+
FixedKVNodeRef find_pending_version(Transaction &t, node_key_t key) {
138+
assert(is_stable());
139+
auto mut_iter = mutation_pendings.find(
140+
t.get_trans_id(), trans_spec_view_t::cmp_t());
141+
if (mut_iter != mutation_pendings.end()) {
142+
assert(copy_dests_by_trans.find(t.get_trans_id()) ==
143+
copy_dests_by_trans.end());
144+
return (FixedKVNode*)(&(*mut_iter));
145+
}
146+
auto iter = copy_dests_by_trans.find(
147+
t.get_trans_id(), trans_spec_view_t::cmp_t());
148+
ceph_assert(iter != copy_dests_by_trans.end());
149+
auto &copy_dests = static_cast<copy_dests_t&>(*iter);
150+
auto it = copy_dests.dests_by_key.lower_bound(key);
151+
if ((*it)->range.begin > key) {
152+
ceph_assert(it != copy_dests.dests_by_key.begin());
153+
--it;
154+
}
155+
ceph_assert((*it)->range.begin <= key && key < (*it)->range.end);
156+
return *it;
157+
}
158+
137159
bool is_linked() {
138160
assert(!has_parent_tracker() || !(bool)root_block);
139161
return (bool)has_parent_tracker() || (bool)root_block;

src/crimson/os/seastore/cached_extent.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1121,6 +1121,10 @@ class PhysicalNodeMapping {
11211121
virtual val_t get_val() const = 0;
11221122
virtual key_t get_key() const = 0;
11231123
virtual PhysicalNodeMappingRef<key_t, val_t> duplicate() const = 0;
1124+
virtual PhysicalNodeMappingRef<key_t, val_t> refresh_with_pending_parent() {
1125+
ceph_abort("impossible");
1126+
return {};
1127+
}
11241128
virtual bool has_been_invalidated() const = 0;
11251129
virtual CachedExtentRef get_parent() const = 0;
11261130
virtual uint16_t get_pos() const = 0;
@@ -1155,6 +1159,7 @@ class PhysicalNodeMapping {
11551159
return !get_val().is_real();
11561160
}
11571161
virtual bool is_parent_viewable() const = 0;
1162+
virtual bool is_parent_valid() const = 0;
11581163
virtual bool parent_modified() const {
11591164
ceph_abort("impossible");
11601165
return false;

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

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,14 @@ class BtreeLBAMapping : public BtreeNodeMapping<laddr_t, paddr_t> {
176176
auto &p = static_cast<LBALeafNode&>(*parent);
177177
p.maybe_fix_mapping_pos(*this);
178178
}
179+
180+
LBAMappingRef refresh_with_pending_parent() final {
181+
assert(is_parent_valid() && !is_parent_viewable());
182+
auto &p = static_cast<LBALeafNode&>(*parent);
183+
auto &viewable_p = static_cast<LBALeafNode&>(
184+
*p.find_pending_version(ctx.trans, get_key()));
185+
return viewable_p.get_mapping(ctx, get_key());
186+
}
179187
protected:
180188
std::unique_ptr<BtreeNodeMapping<laddr_t, paddr_t>> _duplicate(
181189
op_context_t<laddr_t> ctx) const final {

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

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,4 +72,18 @@ void LBALeafNode::maybe_fix_mapping_pos(BtreeLBAMapping &mapping)
7272
}
7373
}
7474

75+
BtreeLBAMappingRef LBALeafNode::get_mapping(
76+
op_context_t<laddr_t> c, laddr_t laddr)
77+
{
78+
auto iter = lower_bound(laddr);
79+
ceph_assert(iter != end() && iter->get_key() == laddr);
80+
auto val = iter.get_val();
81+
return std::make_unique<BtreeLBAMapping>(
82+
c,
83+
this,
84+
iter.get_offset(),
85+
val,
86+
lba_node_meta_t{laddr, val.len, 0});
87+
}
88+
7589
}

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -294,6 +294,7 @@ struct LBALeafNode
294294
std::ostream &_print_detail(std::ostream &out) const final;
295295

296296
void maybe_fix_mapping_pos(BtreeLBAMapping &mapping);
297+
std::unique_ptr<BtreeLBAMapping> get_mapping(op_context_t<laddr_t> c, laddr_t laddr);
297298
};
298299
using LBALeafNodeRef = TCachedExtentRef<LBALeafNode>;
299300

src/crimson/os/seastore/transaction_manager.h

Lines changed: 23 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -184,11 +184,16 @@ class TransactionManager : public ExtentCallbackInterface {
184184
{
185185
auto fut = base_iertr::make_ready_future<LBAMappingRef>();
186186
if (!pin->is_parent_viewable()) {
187-
fut = get_pin(t, pin->get_key()
188-
).handle_error_interruptible(
189-
crimson::ct_error::enoent::assert_failure{"unexpected enoent"},
190-
crimson::ct_error::input_output_error::pass_further{}
191-
);
187+
if (pin->is_parent_valid()) {
188+
pin = pin->refresh_with_pending_parent();
189+
fut = base_iertr::make_ready_future<LBAMappingRef>(std::move(pin));
190+
} else {
191+
fut = get_pin(t, pin->get_key()
192+
).handle_error_interruptible(
193+
crimson::ct_error::enoent::assert_failure{"unexpected enoent"},
194+
crimson::ct_error::input_output_error::pass_further{}
195+
);
196+
}
192197
} else {
193198
pin->maybe_fix_pos();
194199
fut = base_iertr::make_ready_future<LBAMappingRef>(std::move(pin));
@@ -476,15 +481,19 @@ class TransactionManager : public ExtentCallbackInterface {
476481
auto fut = base_iertr::now();
477482
if (!pin->is_indirect()) {
478483
if (!pin->is_parent_viewable()) {
479-
fut = get_pin(t, pin->get_key()
480-
).si_then([&pin](auto npin) {
481-
assert(npin);
482-
pin = std::move(npin);
483-
return seastar::now();
484-
}).handle_error_interruptible(
485-
crimson::ct_error::enoent::assert_failure{"unexpected enoent"},
486-
crimson::ct_error::input_output_error::pass_further{}
487-
);
484+
if (pin->is_parent_valid()) {
485+
pin = pin->refresh_with_pending_parent();
486+
} else {
487+
fut = get_pin(t, pin->get_key()
488+
).si_then([&pin](auto npin) {
489+
assert(npin);
490+
pin = std::move(npin);
491+
return seastar::now();
492+
}).handle_error_interruptible(
493+
crimson::ct_error::enoent::assert_failure{"unexpected enoent"},
494+
crimson::ct_error::input_output_error::pass_further{}
495+
);
496+
}
488497
} else {
489498
pin->maybe_fix_pos();
490499
}

0 commit comments

Comments
 (0)