]>
Commit | Line | Data |
---|---|---|
1e59de90 TL |
1 | // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:nil -*- |
2 | // vim: ts=8 sw=2 smarttab expandtab | |
3 | ||
4 | #include "crimson/os/seastore/segment_manager_group.h" | |
5 | ||
6 | #include "crimson/os/seastore/logging.h" | |
7 | ||
8 | SET_SUBSYS(seastore_journal); | |
9 | ||
10 | namespace crimson::os::seastore { | |
11 | ||
12 | SegmentManagerGroup::read_segment_tail_ret | |
13 | SegmentManagerGroup::read_segment_tail(segment_id_t segment) | |
14 | { | |
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( | |
19 | segment, | |
20 | segment_manager.get_segment_size() - get_rounded_tail_length()), | |
21 | get_rounded_tail_length() | |
22 | ).handle_error( | |
23 | read_segment_header_ertr::pass_further{}, | |
24 | crimson::ct_error::assert_all{ | |
25 | "Invalid error in SegmentManagerGroup::read_segment_tail" | |
26 | } | |
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()); | |
30 | ||
31 | segment_tail_t tail; | |
32 | bufferlist bl; | |
33 | bl.push_back(bptr); | |
34 | ||
35 | DEBUG("segment {} block crc {}", | |
36 | segment, | |
37 | bl.begin().crc32c(segment_manager.get_block_size(), 0)); | |
38 | ||
39 | auto bp = bl.cbegin(); | |
40 | try { | |
41 | decode(tail, bp); | |
42 | } catch (ceph::buffer::error &e) { | |
43 | DEBUG("segment {} unable to decode tail, skipping -- {}", | |
44 | segment, e.what()); | |
45 | return crimson::ct_error::enodata::make(); | |
46 | } | |
47 | DEBUG("segment {} tail {}", segment, tail); | |
48 | return read_segment_tail_ret( | |
49 | read_segment_tail_ertr::ready_future_marker{}, | |
50 | tail); | |
51 | }); | |
52 | } | |
53 | ||
54 | SegmentManagerGroup::read_segment_header_ret | |
55 | SegmentManagerGroup::read_segment_header(segment_id_t segment) | |
56 | { | |
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() | |
62 | ).handle_error( | |
63 | read_segment_header_ertr::pass_further{}, | |
64 | crimson::ct_error::assert_all{ | |
65 | "Invalid error in SegmentManagerGroup::read_segment_header" | |
66 | } | |
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()); | |
70 | ||
71 | segment_header_t header; | |
72 | bufferlist bl; | |
73 | bl.push_back(bptr); | |
74 | ||
75 | DEBUG("segment {} block crc {}", | |
76 | segment, | |
77 | bl.begin().crc32c(segment_manager.get_block_size(), 0)); | |
78 | ||
79 | auto bp = bl.cbegin(); | |
80 | try { | |
81 | decode(header, bp); | |
82 | } catch (ceph::buffer::error &e) { | |
83 | DEBUG("segment {} unable to decode header, skipping -- {}", | |
84 | segment, e.what()); | |
85 | return crimson::ct_error::enodata::make(); | |
86 | } | |
87 | DEBUG("segment {} header {}", segment, header); | |
88 | return read_segment_header_ret( | |
89 | read_segment_header_ertr::ready_future_marker{}, | |
90 | header); | |
91 | }); | |
92 | } | |
93 | ||
aee94f69 TL |
94 | void SegmentManagerGroup::initialize_cursor( |
95 | scan_valid_records_cursor &cursor) | |
1e59de90 | 96 | { |
aee94f69 | 97 | LOG_PREFIX(SegmentManagerGroup::initialize_cursor); |
1e59de90 TL |
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()); | |
104 | } | |
aee94f69 | 105 | cursor.block_size = segment_manager.get_block_size(); |
1e59de90 TL |
106 | } |
107 | ||
aee94f69 TL |
108 | SegmentManagerGroup::read_ret |
109 | SegmentManagerGroup::read(paddr_t start, size_t len) | |
1e59de90 | 110 | { |
aee94f69 TL |
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); | |
1e59de90 | 115 | return segment_manager.read( |
aee94f69 TL |
116 | start, |
117 | len | |
118 | ).safe_then([](auto bptr) { | |
119 | return read_ret( | |
120 | read_ertr::ready_future_marker{}, | |
121 | std::move(bptr) | |
122 | ); | |
1e59de90 TL |
123 | }); |
124 | } | |
125 | ||
126 | SegmentManagerGroup::find_journal_segment_headers_ret | |
127 | SegmentManagerGroup::find_journal_segment_headers() | |
128 | { | |
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 | |
133 | { | |
134 | return crimson::do_for_each(sms, | |
135 | [this, &ret](SegmentManager *sm) | |
136 | { | |
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) | |
146 | { | |
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))); | |
152 | } | |
153 | }).handle_error( | |
154 | crimson::ct_error::enoent::handle([](auto) { | |
155 | return find_journal_segment_headers_ertr::now(); | |
156 | }), | |
157 | crimson::ct_error::enodata::handle([](auto) { | |
158 | return find_journal_segment_headers_ertr::now(); | |
159 | }), | |
160 | crimson::ct_error::input_output_error::pass_further{} | |
161 | ); | |
162 | }); | |
163 | }).safe_then([&ret]() mutable { | |
164 | return find_journal_segment_headers_ret{ | |
165 | find_journal_segment_headers_ertr::ready_future_marker{}, | |
166 | std::move(ret)}; | |
167 | }); | |
168 | }); | |
169 | } | |
170 | ||
171 | } // namespace crimson::os::seastore |