});
}
-Journal::scan_segment_ret Journal::scan_segment(
- paddr_t addr,
- extent_len_t bytes_to_read,
- segment_nonce_t nonce,
- delta_scan_handler_t *delta_handler,
- extent_handler_t *extent_info_handler)
-{
- logger().debug("Journal::scan_segment: starting at {}", addr);
- return seastar::do_with(
- addr,
- [=](paddr_t ¤t) {
- return crimson::do_until(
- [=, ¤t]() -> scan_segment_ertr::future<bool> {
- return read_validate_record_metadata(current, nonce).safe_then
- ([=, ¤t](auto p)
- -> scan_segment_ertr::future<bool> {
- if (!p.has_value()) {
- current = P_ADDR_NULL;
- return scan_segment_ertr::make_ready_future<bool>(true);
- }
-
- auto &[header, bl] = *p;
-
- if (header.segment_nonce != nonce) {
- logger().debug(
- "Journal::scan_segment: record offset {} nonce mismatch {} vs {}",
- current,
- nonce,
- header.segment_nonce);
- return scan_segment_ertr::make_ready_future<bool>(true);
- }
-
- logger().debug(
- "Journal::scan_segment: next record offset {} mdlength {} dlength {}",
- current,
- header.mdlength,
- header.dlength);
-
- auto record_start = current;
- current.offset += header.mdlength + header.dlength;
-
- return seastar::do_with(
- header,
- bl,
- [=, ¤t](auto &header, auto &bl) {
- return scan_segment_ertr::now(
- ).safe_then(
- [=, &header, &bl]()
- -> scan_segment_ertr::future<> {
- if (!delta_handler) {
- return scan_segment_ertr::now();
- }
-
- auto deltas = try_decode_deltas(
- header,
- bl);
- if (!deltas) {
- logger().error(
- "Journal::scan_segment unable to decode deltas for record {}",
- addr);
- return crimson::ct_error::input_output_error::make();
- }
-
- return seastar::do_with(
- std::move(*deltas),
- [=](auto &deltas) {
- return crimson::do_for_each(
- deltas,
- [=](auto &info) {
- return (*delta_handler)(
- record_start,
- record_start.add_offset(header.mdlength),
- info);
- });
- });
- }).safe_then(
- [=, &header, &bl]() -> scan_segment_ertr::future<> {
- if (!extent_info_handler) {
- return scan_segment_ertr::now();
- }
-
- auto infos = try_decode_extent_infos(
- header,
- bl);
- if (!infos) {
- logger().error(
- "Journal::scan_segment unable to decode extent infos for record {}",
- addr);
- return crimson::ct_error::input_output_error::make();
- }
-
- return seastar::do_with(
- segment_off_t(0),
- std::move(*infos),
- [=](auto &pos, auto &deltas) {
- return crimson::do_for_each(
- deltas,
- [=, &pos](auto &info) {
- auto addr = record_start
- .add_offset(header.mdlength)
- .add_offset(pos);
- pos += info.len;
- return (*extent_info_handler)(
- addr,
- info);
- });
- });
- return scan_segment_ertr::now();
- });
- }).safe_then([=, ¤t] {
- if ((segment_off_t)(addr.offset + bytes_to_read)
- <= current.offset) {
- return scan_segment_ertr::make_ready_future<bool>(true);
- } else {
- return scan_segment_ertr::make_ready_future<bool>(false);
- }
- });
- });
- }).safe_then([¤t] {
- return scan_segment_ertr::make_ready_future<paddr_t>(current);
- });
- });
-}
-
Journal::scan_valid_records_ret Journal::scan_valid_records(
scan_valid_records_cursor &cursor,
segment_nonce_t nonce,
paddr_t start,
segment_nonce_t nonce);
- /**
- * scan_segment
- *
- * Scans bytes_to_read forward from addr to the first record after
- * addr+bytes_to_read invoking delta_handler and extent_info_handler
- * on deltas and extent_infos respectively. deltas, extent_infos
- * will only be decoded if the corresponding handler is included.
- *
- * @return next address to read from, P_ADDR_NULL if segment complete
- */
- using scan_segment_ertr = SegmentManager::read_ertr;
- using scan_segment_ret = scan_segment_ertr::future<paddr_t>;
- using delta_scan_handler_t = std::function<
- replay_ret(paddr_t record_start,
- paddr_t record_block_base,
- const delta_info_t&)>;
- using extent_handler_t = std::function<
- scan_segment_ertr::future<>(paddr_t addr,
- const extent_info_t &info)>;
- scan_segment_ret scan_segment(
- paddr_t addr,
- extent_len_t bytes_to_read,
- segment_nonce_t nonce,
- delta_scan_handler_t *delta_handler,
- extent_handler_t *extent_info_handler
- );
public:
/// scan segment for end incrementally
struct scan_valid_records_cursor {