crimson/os/seastore/journal: factor out read_segment_header

Signed-off-by: Samuel Just <sjust@redhat.com>
This commit is contained in:
Samuel Just 2020-11-05 16:04:49 -08:00
parent 36cc47e69c
commit f2402dc916
2 changed files with 64 additions and 23 deletions

View File

@ -204,6 +204,45 @@ Journal::roll_journal_segment()
);
}
Journal::read_segment_header_ret
Journal::read_segment_header(segment_id_t segment)
{
return segment_manager.read(paddr_t{segment, 0}, block_size
).handle_error(
read_segment_header_ertr::pass_further{},
crimson::ct_error::assert_all{}
).safe_then([=](bufferptr bptr) -> read_segment_header_ret {
logger().debug("segment {} bptr size {}", segment, bptr.length());
segment_header_t header;
bufferlist bl;
bl.push_back(bptr);
logger().debug(
"find_replay_segments: segment {} block crc {}",
segment,
bl.begin().crc32c(block_size, 0));
auto bp = bl.cbegin();
try {
decode(header, bp);
} catch (ceph::buffer::error &e) {
logger().debug(
"find_replay_segments: segment {} unable to decode "
"header, skipping",
segment);
return crimson::ct_error::enodata::make();
}
logger().debug(
"find_replay_segments: segment {} header {}",
segment,
header);
return read_segment_header_ret(
read_segment_header_ertr::ready_future_marker{},
header);
});
}
Journal::open_for_write_ret Journal::open_for_write()
{
return roll_journal_segment().safe_then([this](auto seq) {
@ -227,32 +266,19 @@ Journal::find_replay_segments_fut Journal::find_replay_segments()
boost::make_counting_iterator(segment_id_t{0}),
boost::make_counting_iterator(segment_manager.get_num_segments()),
[this, &segments](auto i) {
return segment_manager.read(paddr_t{i, 0}, block_size
).safe_then([this, &segments, i](bufferptr bptr) mutable {
logger().debug("segment {} bptr size {}", i, bptr.length());
segment_header_t header;
bufferlist bl;
bl.push_back(bptr);
logger().debug(
"find_replay_segments: segment {} block crc {}",
i,
bl.begin().crc32c(block_size, 0));
auto bp = bl.cbegin();
try {
decode(header, bp);
} catch (ceph::buffer::error &e) {
return read_segment_header(i
).safe_then([this, &segments, i](auto header) mutable {
if (generate_nonce(
header.journal_segment_seq,
segment_manager.get_meta()) != header.segment_nonce) {
logger().debug(
"find_replay_segments: segment {} unable to decode "
"header, skipping",
i);
"find_replay_segments: nonce mismatch segment {} header {}",
i,
header);
assert(0 == "impossible");
return find_replay_segments_ertr::now();
}
logger().debug(
"find_replay_segments: segment {} header {}",
i,
header);
segments.emplace_back(i, std::move(header));
return find_replay_segments_ertr::now();
}).handle_error(
@ -262,6 +288,12 @@ Journal::find_replay_segments_fut Journal::find_replay_segments()
i);
return find_replay_segments_ertr::now();
}),
crimson::ct_error::enodata::handle([i](auto) {
logger().debug(
"find_replay_segments: segment {} header undecodable",
i);
return find_replay_segments_ertr::now();
}),
find_replay_segments_ertr::pass_further{},
crimson::ct_error::assert_all{}
);

View File

@ -283,6 +283,15 @@ private:
/// returns true iff current segment has insufficient space
bool needs_roll(segment_off_t length) const;
using read_segment_header_ertr = crimson::errorator<
crimson::ct_error::enoent,
crimson::ct_error::enodata,
crimson::ct_error::input_output_error
>;
using read_segment_header_ret = read_segment_header_ertr::future<
segment_header_t>;
read_segment_header_ret read_segment_header(segment_id_t segment);
/// return ordered vector of segments to replay
using replay_segments_t = std::vector<
std::pair<journal_seq_t, segment_header_t>>;