]> git.proxmox.com Git - ceph.git/blob - ceph/src/crimson/os/seastore/segment_manager_group.cc
332b794b70ee2a43a0d8ff9a733c4fc428e5ed4e
[ceph.git] / ceph / src / crimson / os / seastore / segment_manager_group.cc
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
94 void SegmentManagerGroup::initialize_cursor(
95 scan_valid_records_cursor &cursor)
96 {
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());
104 }
105 cursor.block_size = segment_manager.get_block_size();
106 }
107
108 SegmentManagerGroup::read_ret
109 SegmentManagerGroup::read(paddr_t start, size_t len)
110 {
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(
116 start,
117 len
118 ).safe_then([](auto bptr) {
119 return read_ret(
120 read_ertr::ready_future_marker{},
121 std::move(bptr)
122 );
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