1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:nil -*-
2 // vim: ts=8 sw=2 smarttab expandtab
4 #include "crimson/os/seastore/segment_manager_group.h"
6 #include "crimson/os/seastore/logging.h"
8 SET_SUBSYS(seastore_journal
);
10 namespace crimson::os::seastore
{
12 SegmentManagerGroup::read_segment_tail_ret
13 SegmentManagerGroup::read_segment_tail(segment_id_t segment
)
15 assert(has_device(segment
.device_id()));
16 auto& segment_manager
= *segment_managers
[segment
.device_id()];
17 return segment_manager
.read(
18 paddr_t::make_seg_paddr(
20 segment_manager
.get_segment_size() - get_rounded_tail_length()),
21 get_rounded_tail_length()
23 read_segment_header_ertr::pass_further
{},
24 crimson::ct_error::assert_all
{
25 "Invalid error in SegmentManagerGroup::read_segment_tail"
27 ).safe_then([=, &segment_manager
](bufferptr bptr
) -> read_segment_tail_ret
{
28 LOG_PREFIX(SegmentManagerGroup::read_segment_tail
);
29 DEBUG("segment {} bptr size {}", segment
, bptr
.length());
35 DEBUG("segment {} block crc {}",
37 bl
.begin().crc32c(segment_manager
.get_block_size(), 0));
39 auto bp
= bl
.cbegin();
42 } catch (ceph::buffer::error
&e
) {
43 DEBUG("segment {} unable to decode tail, skipping -- {}",
45 return crimson::ct_error::enodata::make();
47 DEBUG("segment {} tail {}", segment
, tail
);
48 return read_segment_tail_ret(
49 read_segment_tail_ertr::ready_future_marker
{},
54 SegmentManagerGroup::read_segment_header_ret
55 SegmentManagerGroup::read_segment_header(segment_id_t segment
)
57 assert(has_device(segment
.device_id()));
58 auto& segment_manager
= *segment_managers
[segment
.device_id()];
59 return segment_manager
.read(
60 paddr_t::make_seg_paddr(segment
, 0),
61 get_rounded_header_length()
63 read_segment_header_ertr::pass_further
{},
64 crimson::ct_error::assert_all
{
65 "Invalid error in SegmentManagerGroup::read_segment_header"
67 ).safe_then([=, &segment_manager
](bufferptr bptr
) -> read_segment_header_ret
{
68 LOG_PREFIX(SegmentManagerGroup::read_segment_header
);
69 DEBUG("segment {} bptr size {}", segment
, bptr
.length());
71 segment_header_t header
;
75 DEBUG("segment {} block crc {}",
77 bl
.begin().crc32c(segment_manager
.get_block_size(), 0));
79 auto bp
= bl
.cbegin();
82 } catch (ceph::buffer::error
&e
) {
83 DEBUG("segment {} unable to decode header, skipping -- {}",
85 return crimson::ct_error::enodata::make();
87 DEBUG("segment {} header {}", segment
, header
);
88 return read_segment_header_ret(
89 read_segment_header_ertr::ready_future_marker
{},
94 void SegmentManagerGroup::initialize_cursor(
95 scan_valid_records_cursor
&cursor
)
97 LOG_PREFIX(SegmentManagerGroup::initialize_cursor
);
98 assert(has_device(cursor
.get_segment_id().device_id()));
99 auto& segment_manager
=
100 *segment_managers
[cursor
.get_segment_id().device_id()];
101 if (cursor
.get_segment_offset() == 0) {
102 INFO("start to scan segment {}", cursor
.get_segment_id());
103 cursor
.increment_seq(segment_manager
.get_block_size());
105 cursor
.block_size
= segment_manager
.get_block_size();
108 SegmentManagerGroup::read_ret
109 SegmentManagerGroup::read(paddr_t start
, size_t len
)
111 LOG_PREFIX(SegmentManagerGroup::read
);
112 assert(has_device(start
.get_device_id()));
113 auto& segment_manager
= *segment_managers
[start
.get_device_id()];
114 TRACE("reading data {}~{}", start
, len
);
115 return segment_manager
.read(
118 ).safe_then([](auto bptr
) {
120 read_ertr::ready_future_marker
{},
126 SegmentManagerGroup::find_journal_segment_headers_ret
127 SegmentManagerGroup::find_journal_segment_headers()
129 return seastar::do_with(
130 get_segment_managers(),
131 find_journal_segment_headers_ret_bare
{},
132 [this](auto &sms
, auto& ret
) -> find_journal_segment_headers_ret
134 return crimson::do_for_each(sms
,
135 [this, &ret
](SegmentManager
*sm
)
137 LOG_PREFIX(SegmentManagerGroup::find_journal_segment_headers
);
138 auto device_id
= sm
->get_device_id();
139 auto num_segments
= sm
->get_num_segments();
140 DEBUG("processing {} with {} segments",
141 device_id_printer_t
{device_id
}, num_segments
);
142 return crimson::do_for_each(
143 boost::counting_iterator
<device_segment_id_t
>(0),
144 boost::counting_iterator
<device_segment_id_t
>(num_segments
),
145 [this, &ret
, device_id
](device_segment_id_t d_segment_id
)
147 segment_id_t segment_id
{device_id
, d_segment_id
};
148 return read_segment_header(segment_id
149 ).safe_then([segment_id
, &ret
](auto &&header
) {
150 if (header
.get_type() == segment_type_t::JOURNAL
) {
151 ret
.emplace_back(std::make_pair(segment_id
, std::move(header
)));
154 crimson::ct_error::enoent::handle([](auto) {
155 return find_journal_segment_headers_ertr::now();
157 crimson::ct_error::enodata::handle([](auto) {
158 return find_journal_segment_headers_ertr::now();
160 crimson::ct_error::input_output_error::pass_further
{}
163 }).safe_then([&ret
]() mutable {
164 return find_journal_segment_headers_ret
{
165 find_journal_segment_headers_ertr::ready_future_marker
{},
171 } // namespace crimson::os::seastore