segment_seq_printer_t{delta_paddr_segment_seq},
delta_paddr_segment_type,
delta);
- return replay_delta_ertr::make_ready_future<bool>(false);
+ return replay_delta_ertr::make_ready_future<std::pair<bool, CachedExtentRef>>(
+ std::make_pair(false, nullptr));
}
}
}
if (delta.type == extent_types_t::JOURNAL_TAIL) {
// this delta should have been dealt with during segment cleaner mounting
- return replay_delta_ertr::make_ready_future<bool>(false);
+ return replay_delta_ertr::make_ready_future<std::pair<bool, CachedExtentRef>>(
+ std::make_pair(false, nullptr));
}
// replay alloc
if (journal_seq < alloc_tail) {
DEBUG("journal_seq {} < alloc_tail {}, don't replay {}",
journal_seq, alloc_tail, delta);
- return replay_delta_ertr::make_ready_future<bool>(false);
+ return replay_delta_ertr::make_ready_future<std::pair<bool, CachedExtentRef>>(
+ std::make_pair(false, nullptr));
}
alloc_delta_t alloc_delta;
if (!backref_list.empty()) {
backref_batch_update(std::move(backref_list), journal_seq);
}
- return replay_delta_ertr::make_ready_future<bool>(true);
+ return replay_delta_ertr::make_ready_future<std::pair<bool, CachedExtentRef>>(
+ std::make_pair(true, nullptr));
}
// replay dirty
if (journal_seq < dirty_tail) {
DEBUG("journal_seq {} < dirty_tail {}, don't replay {}",
journal_seq, dirty_tail, delta);
- return replay_delta_ertr::make_ready_future<bool>(false);
+ return replay_delta_ertr::make_ready_future<std::pair<bool, CachedExtentRef>>(
+ std::make_pair(false, nullptr));
}
if (delta.type == extent_types_t::ROOT) {
journal_seq, record_base, delta, *root);
root->set_modify_time(modify_time);
add_extent(root);
- return replay_delta_ertr::make_ready_future<bool>(true);
+ return replay_delta_ertr::make_ready_future<std::pair<bool, CachedExtentRef>>(
+ std::make_pair(true, root));
} else {
auto _get_extent_if_cached = [this](paddr_t addr)
-> get_extent_ertr::future<CachedExtentRef> {
DEBUG("replay extent is not present, so delta is obsolete at {} {} -- {}",
journal_seq, record_base, delta);
assert(delta.pversion > 0);
- return replay_delta_ertr::make_ready_future<bool>(true);
+ return replay_delta_ertr::make_ready_future<std::pair<bool, CachedExtentRef>>(
+ std::make_pair(true, nullptr));
}
DEBUG("replay extent delta at {} {} ... -- {}, prv_extent={}",
if (delta.paddr.get_addr_type() == paddr_types_t::SEGMENT ||
!can_inplace_rewrite(delta.type)) {
- assert(extent->last_committed_crc == delta.prev_crc);
+ ceph_assert_always(extent->last_committed_crc == delta.prev_crc);
assert(extent->version == delta.pversion);
extent->apply_delta_and_adjust_crc(record_base, delta.bl);
extent->set_modify_time(modify_time);
- assert(extent->last_committed_crc == delta.final_crc);
+ ceph_assert_always(extent->last_committed_crc == delta.final_crc);
} else {
assert(delta.paddr.get_addr_type() == paddr_types_t::RANDOM_BLOCK);
extent->apply_delta_and_adjust_crc(record_base, delta.bl);
extent->set_modify_time(modify_time);
- // Since rewrite_dirty can conflict with other transaction after
- // inplace rewrite is complete, crc may not be matched
- if (delta.final_crc == extent->last_committed_crc) {
- assert(extent->version == delta.pversion);
- }
+ // crc will be checked after journal replay is done
}
extent->version++;
journal_seq, record_base, delta, *extent);
}
mark_dirty(extent);
- return replay_delta_ertr::make_ready_future<bool>(true);
+ return replay_delta_ertr::make_ready_future<std::pair<bool, CachedExtentRef>>(
+ std::make_pair(true, extent));
});
}
}
return seastar::do_with(
std::move(delta_handler),
std::map<paddr_t, journal_seq_t>(),
- [this](auto &d_handler, auto &map) {
+ std::map<paddr_t, std::pair<CachedExtentRef, uint32_t>>(),
+ [this](auto &d_handler, auto &map, auto &crc_info) {
auto build_paddr_seq_map = [&map](
const auto &offsets,
const auto &e,
// The first pass to build the paddr->journal_seq_t map
// from extent allocations
return scan_valid_record_delta(std::move(build_paddr_seq_map), tail
- ).safe_then([this, &map, &d_handler, tail]() {
- auto call_d_handler_if_valid = [this, &map, &d_handler](
+ ).safe_then([this, &map, &d_handler, tail, &crc_info]() {
+ auto call_d_handler_if_valid = [this, &map, &d_handler, &crc_info](
const auto &offsets,
const auto &e,
sea_time_point modify_time)
get_dirty_tail(),
get_alloc_tail(),
modify_time
- );
+ ).safe_then([&e, &crc_info](auto ret) {
+ auto [applied, ext] = ret;
+ if (applied && ext && can_inplace_rewrite(
+ ext->get_type())) {
+ crc_info[ext->get_paddr()] =
+ std::make_pair(ext, e.final_crc);
+ }
+ return replay_ertr::make_ready_future<bool>(applied);
+ });
}
return replay_ertr::make_ready_future<bool>(true);
};
// The second pass to replay deltas
- return scan_valid_record_delta(std::move(call_d_handler_if_valid), tail);
+ return scan_valid_record_delta(std::move(call_d_handler_if_valid), tail
+ ).safe_then([&crc_info]() {
+ for (auto p : crc_info) {
+ ceph_assert_always(p.second.first->get_last_committed_crc() == p.second.second);
+ }
+ crc_info.clear();
+ return replay_ertr::now();
+ });
});
}).safe_then([this]() {
// make sure that committed_to is JOURNAL_SEQ_NULL if jounal is the initial state