Skip to content

Commit ad8b3f2

Browse files
committed
crimson/os/seastore: check correct crc for inplace-rewritten extents after replay is done
Signed-off-by: Myoungwon Oh <[email protected]>
1 parent cba051d commit ad8b3f2

File tree

8 files changed

+56
-26
lines changed

8 files changed

+56
-26
lines changed

src/crimson/os/seastore/cache.cc

Lines changed: 19 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1732,22 +1732,25 @@ Cache::replay_delta(
17321732
segment_seq_printer_t{delta_paddr_segment_seq},
17331733
delta_paddr_segment_type,
17341734
delta);
1735-
return replay_delta_ertr::make_ready_future<bool>(false);
1735+
return replay_delta_ertr::make_ready_future<std::pair<bool, CachedExtentRef>>(
1736+
std::make_pair(false, nullptr));
17361737
}
17371738
}
17381739
}
17391740

17401741
if (delta.type == extent_types_t::JOURNAL_TAIL) {
17411742
// this delta should have been dealt with during segment cleaner mounting
1742-
return replay_delta_ertr::make_ready_future<bool>(false);
1743+
return replay_delta_ertr::make_ready_future<std::pair<bool, CachedExtentRef>>(
1744+
std::make_pair(false, nullptr));
17431745
}
17441746

17451747
// replay alloc
17461748
if (delta.type == extent_types_t::ALLOC_INFO) {
17471749
if (journal_seq < alloc_tail) {
17481750
DEBUG("journal_seq {} < alloc_tail {}, don't replay {}",
17491751
journal_seq, alloc_tail, delta);
1750-
return replay_delta_ertr::make_ready_future<bool>(false);
1752+
return replay_delta_ertr::make_ready_future<std::pair<bool, CachedExtentRef>>(
1753+
std::make_pair(false, nullptr));
17511754
}
17521755

17531756
alloc_delta_t alloc_delta;
@@ -1771,14 +1774,16 @@ Cache::replay_delta(
17711774
if (!backref_list.empty()) {
17721775
backref_batch_update(std::move(backref_list), journal_seq);
17731776
}
1774-
return replay_delta_ertr::make_ready_future<bool>(true);
1777+
return replay_delta_ertr::make_ready_future<std::pair<bool, CachedExtentRef>>(
1778+
std::make_pair(true, nullptr));
17751779
}
17761780

17771781
// replay dirty
17781782
if (journal_seq < dirty_tail) {
17791783
DEBUG("journal_seq {} < dirty_tail {}, don't replay {}",
17801784
journal_seq, dirty_tail, delta);
1781-
return replay_delta_ertr::make_ready_future<bool>(false);
1785+
return replay_delta_ertr::make_ready_future<std::pair<bool, CachedExtentRef>>(
1786+
std::make_pair(false, nullptr));
17821787
}
17831788

17841789
if (delta.type == extent_types_t::ROOT) {
@@ -1792,7 +1797,8 @@ Cache::replay_delta(
17921797
journal_seq, record_base, delta, *root);
17931798
root->set_modify_time(modify_time);
17941799
add_extent(root);
1795-
return replay_delta_ertr::make_ready_future<bool>(true);
1800+
return replay_delta_ertr::make_ready_future<std::pair<bool, CachedExtentRef>>(
1801+
std::make_pair(true, root));
17961802
} else {
17971803
auto _get_extent_if_cached = [this](paddr_t addr)
17981804
-> get_extent_ertr::future<CachedExtentRef> {
@@ -1832,28 +1838,25 @@ Cache::replay_delta(
18321838
DEBUG("replay extent is not present, so delta is obsolete at {} {} -- {}",
18331839
journal_seq, record_base, delta);
18341840
assert(delta.pversion > 0);
1835-
return replay_delta_ertr::make_ready_future<bool>(true);
1841+
return replay_delta_ertr::make_ready_future<std::pair<bool, CachedExtentRef>>(
1842+
std::make_pair(true, nullptr));
18361843
}
18371844

18381845
DEBUG("replay extent delta at {} {} ... -- {}, prv_extent={}",
18391846
journal_seq, record_base, delta, *extent);
18401847

18411848
if (delta.paddr.get_addr_type() == paddr_types_t::SEGMENT ||
18421849
!can_inplace_rewrite(delta.type)) {
1843-
assert(extent->last_committed_crc == delta.prev_crc);
1850+
ceph_assert_always(extent->last_committed_crc == delta.prev_crc);
18441851
assert(extent->version == delta.pversion);
18451852
extent->apply_delta_and_adjust_crc(record_base, delta.bl);
18461853
extent->set_modify_time(modify_time);
1847-
assert(extent->last_committed_crc == delta.final_crc);
1854+
ceph_assert_always(extent->last_committed_crc == delta.final_crc);
18481855
} else {
18491856
assert(delta.paddr.get_addr_type() == paddr_types_t::RANDOM_BLOCK);
18501857
extent->apply_delta_and_adjust_crc(record_base, delta.bl);
18511858
extent->set_modify_time(modify_time);
1852-
// Since rewrite_dirty can conflict with other transaction after
1853-
// inplace rewrite is complete, crc may not be matched
1854-
if (delta.final_crc == extent->last_committed_crc) {
1855-
assert(extent->version == delta.pversion);
1856-
}
1859+
// crc will be checked after journal replay is done
18571860
}
18581861

18591862
extent->version++;
@@ -1866,7 +1869,8 @@ Cache::replay_delta(
18661869
journal_seq, record_base, delta, *extent);
18671870
}
18681871
mark_dirty(extent);
1869-
return replay_delta_ertr::make_ready_future<bool>(true);
1872+
return replay_delta_ertr::make_ready_future<std::pair<bool, CachedExtentRef>>(
1873+
std::make_pair(true, extent));
18701874
});
18711875
}
18721876
}

src/crimson/os/seastore/cache.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1039,7 +1039,8 @@ class Cache {
10391039
*/
10401040
using replay_delta_ertr = crimson::errorator<
10411041
crimson::ct_error::input_output_error>;
1042-
using replay_delta_ret = replay_delta_ertr::future<bool>;
1042+
using replay_delta_ret = replay_delta_ertr::future<
1043+
std::pair<bool, CachedExtentRef>>;
10431044
replay_delta_ret replay_delta(
10441045
journal_seq_t seq,
10451046
paddr_t record_block_base,

src/crimson/os/seastore/cached_extent.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -611,6 +611,10 @@ class CachedExtent
611611
return prior_instance;
612612
}
613613

614+
uint32_t get_last_committed_crc() const {
615+
return last_committed_crc;
616+
}
617+
614618
private:
615619
template <typename T>
616620
friend class read_set_item_t;

src/crimson/os/seastore/journal.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
#include "crimson/os/seastore/ordering_handle.h"
99
#include "crimson/os/seastore/seastore_types.h"
1010
#include "crimson/os/seastore/segment_seq_allocator.h"
11+
#include "crimson/os/seastore/cached_extent.h"
1112

1213
namespace crimson::os::seastore {
1314

@@ -88,7 +89,7 @@ class Journal {
8889
crimson::ct_error::erange>;
8990
using replay_ret = replay_ertr::future<>;
9091
using delta_handler_t = std::function<
91-
replay_ertr::future<bool>(
92+
replay_ertr::future<std::pair<bool, CachedExtentRef>>(
9293
const record_locator_t&,
9394
const delta_info_t&,
9495
const journal_seq_t&, // dirty_tail

src/crimson/os/seastore/journal/circular_bounded_journal.cc

Lines changed: 21 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -316,7 +316,8 @@ Journal::replay_ret CircularBoundedJournal::replay(
316316
return seastar::do_with(
317317
std::move(delta_handler),
318318
std::map<paddr_t, journal_seq_t>(),
319-
[this](auto &d_handler, auto &map) {
319+
std::map<paddr_t, std::pair<CachedExtentRef, uint32_t>>(),
320+
[this](auto &d_handler, auto &map, auto &crc_info) {
320321
auto build_paddr_seq_map = [&map](
321322
const auto &offsets,
322323
const auto &e,
@@ -339,8 +340,8 @@ Journal::replay_ret CircularBoundedJournal::replay(
339340
// The first pass to build the paddr->journal_seq_t map
340341
// from extent allocations
341342
return scan_valid_record_delta(std::move(build_paddr_seq_map), tail
342-
).safe_then([this, &map, &d_handler, tail]() {
343-
auto call_d_handler_if_valid = [this, &map, &d_handler](
343+
).safe_then([this, &map, &d_handler, tail, &crc_info]() {
344+
auto call_d_handler_if_valid = [this, &map, &d_handler, &crc_info](
344345
const auto &offsets,
345346
const auto &e,
346347
sea_time_point modify_time)
@@ -353,12 +354,27 @@ Journal::replay_ret CircularBoundedJournal::replay(
353354
get_dirty_tail(),
354355
get_alloc_tail(),
355356
modify_time
356-
);
357+
).safe_then([&e, &crc_info](auto ret) {
358+
auto [applied, ext] = ret;
359+
if (applied && ext && can_inplace_rewrite(
360+
ext->get_type())) {
361+
crc_info[ext->get_paddr()] =
362+
std::make_pair(ext, e.final_crc);
363+
}
364+
return replay_ertr::make_ready_future<bool>(applied);
365+
});
357366
}
358367
return replay_ertr::make_ready_future<bool>(true);
359368
};
360369
// The second pass to replay deltas
361-
return scan_valid_record_delta(std::move(call_d_handler_if_valid), tail);
370+
return scan_valid_record_delta(std::move(call_d_handler_if_valid), tail
371+
).safe_then([&crc_info]() {
372+
for (auto p : crc_info) {
373+
ceph_assert_always(p.second.first->get_last_committed_crc() == p.second.second);
374+
}
375+
crc_info.clear();
376+
return replay_ertr::now();
377+
});
362378
});
363379
}).safe_then([this]() {
364380
// make sure that committed_to is JOURNAL_SEQ_NULL if jounal is the initial state

src/crimson/os/seastore/journal/segmented_journal.cc

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -291,7 +291,8 @@ SegmentedJournal::replay_segment(
291291
trimmer.get_dirty_tail(),
292292
trimmer.get_alloc_tail(),
293293
modify_time
294-
).safe_then([&stats, delta_type=delta.type](bool is_applied) {
294+
).safe_then([&stats, delta_type=delta.type](auto ret) {
295+
auto [is_applied, ext] = ret;
295296
if (is_applied) {
296297
// see Cache::replay_delta()
297298
assert(delta_type != extent_types_t::JOURNAL_TAIL);

src/test/crimson/seastore/test_cbjournal.cc

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -246,7 +246,8 @@ struct cbjournal_test_t : public seastar_test_suite_t, JournalTrimmer
246246
}
247247
}
248248
assert(found == true);
249-
return Journal::replay_ertr::make_ready_future<bool>(true);
249+
return Journal::replay_ertr::make_ready_future<
250+
std::pair<bool, CachedExtentRef>>(true, nullptr);
250251
});
251252
}
252253

@@ -576,7 +577,8 @@ TEST_F(cbjournal_test_t, multiple_submit_at_end)
576577
auto &dirty_seq,
577578
auto &alloc_seq,
578579
auto last_modified) {
579-
return Journal::replay_ertr::make_ready_future<bool>(true);
580+
return Journal::replay_ertr::make_ready_future<
581+
std::pair<bool, CachedExtentRef>>(true, nullptr);
580582
}).unsafe_get0();
581583
assert(get_written_to() == old_written_to);
582584
});

src/test/crimson/seastore/test_seastore_journal.cc

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -218,7 +218,8 @@ struct journal_test_t : seastar_test_suite_t, SegmentProvider, JournalTrimmer {
218218
delta_checker = std::nullopt;
219219
advance();
220220
}
221-
return Journal::replay_ertr::make_ready_future<bool>(true);
221+
return Journal::replay_ertr::make_ready_future<
222+
std::pair<bool, CachedExtentRef>>(true, nullptr);
222223
}).unsafe_get0();
223224
ASSERT_EQ(record_iter, records.end());
224225
for (auto &i : records) {

0 commit comments

Comments
 (0)