]>
Commit | Line | Data |
---|---|---|
20effc67 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 | #pragma once | |
5 | ||
6 | #include "crimson/common/errorator.h" | |
7 | #include "crimson/os/seastore/seastore_types.h" | |
8 | #include "crimson/os/seastore/segment_manager.h" | |
9 | ||
10 | namespace crimson::os::seastore { | |
11 | ||
12 | class SegmentCleaner; | |
13 | class TransactionManager; | |
14 | ||
15 | class ExtentReader { | |
16 | public: | |
17 | segment_off_t get_block_size() const { | |
18 | assert(segment_managers.size()); | |
19 | // assume all segment managers have the same block size | |
20 | return segment_managers[0]->get_block_size(); | |
21 | } | |
22 | ||
23 | using read_ertr = SegmentManager::read_ertr; | |
24 | ExtentReader() { | |
25 | segment_managers.resize(DEVICE_ID_MAX, nullptr); | |
26 | } | |
27 | using read_segment_header_ertr = crimson::errorator< | |
28 | crimson::ct_error::enoent, | |
29 | crimson::ct_error::enodata, | |
30 | crimson::ct_error::input_output_error | |
31 | >; | |
32 | using read_segment_header_ret = read_segment_header_ertr::future< | |
33 | segment_header_t>; | |
34 | read_segment_header_ret read_segment_header(segment_id_t segment); | |
35 | ||
36 | /** | |
37 | * scan_extents | |
38 | * | |
39 | * Scans records beginning at addr until the first record boundary after | |
40 | * addr + bytes_to_read. | |
41 | * | |
42 | * Returns list<extent, extent_info> | |
43 | * cursor.is_complete() will be true when no further extents exist in segment. | |
44 | */ | |
45 | using scan_extents_cursor = scan_valid_records_cursor; | |
46 | using scan_extents_ertr = read_ertr::extend<crimson::ct_error::enodata>; | |
47 | using scan_extents_ret_bare = std::list<std::pair<paddr_t, extent_info_t>>; | |
48 | using scan_extents_ret = scan_extents_ertr::future<scan_extents_ret_bare>; | |
49 | scan_extents_ret scan_extents( | |
50 | scan_extents_cursor &cursor, | |
51 | extent_len_t bytes_to_read | |
52 | ); | |
53 | ||
54 | using scan_valid_records_ertr = read_ertr::extend<crimson::ct_error::enodata>; | |
55 | using scan_valid_records_ret = scan_valid_records_ertr::future< | |
56 | size_t>; | |
57 | using found_record_handler_t = std::function< | |
58 | scan_valid_records_ertr::future<>( | |
59 | record_locator_t record_locator, | |
60 | // callee may assume header and bl will remain valid until | |
61 | // returned future resolves | |
62 | const record_group_header_t &header, | |
63 | const bufferlist &mdbuf)>; | |
64 | scan_valid_records_ret scan_valid_records( | |
65 | scan_valid_records_cursor &cursor, ///< [in, out] cursor, updated during call | |
66 | segment_nonce_t nonce, ///< [in] nonce for segment | |
67 | size_t budget, ///< [in] max budget to use | |
68 | found_record_handler_t &handler ///< [in] handler for records | |
69 | ); ///< @return used budget | |
70 | ||
71 | void add_segment_manager(SegmentManager* segment_manager) { | |
72 | assert(!segment_managers[segment_manager->get_device_id()] || | |
73 | segment_manager == segment_managers[segment_manager->get_device_id()]); | |
74 | segment_managers[segment_manager->get_device_id()] = segment_manager; | |
75 | } | |
76 | ||
77 | read_ertr::future<> read( | |
78 | paddr_t addr, | |
79 | size_t len, | |
80 | ceph::bufferptr &out) { | |
81 | assert(segment_managers[addr.get_device_id()]); | |
82 | return segment_managers[addr.get_device_id()]->read(addr, len, out); | |
83 | } | |
84 | ||
85 | private: | |
86 | std::vector<SegmentManager*> segment_managers; | |
87 | ||
88 | std::vector<SegmentManager*>& get_segment_managers() { | |
89 | return segment_managers; | |
90 | } | |
91 | /// read record metadata for record starting at start | |
92 | using read_validate_record_metadata_ertr = read_ertr; | |
93 | using read_validate_record_metadata_ret = | |
94 | read_validate_record_metadata_ertr::future< | |
95 | std::optional<std::pair<record_group_header_t, bufferlist>> | |
96 | >; | |
97 | read_validate_record_metadata_ret read_validate_record_metadata( | |
98 | paddr_t start, | |
99 | segment_nonce_t nonce); | |
100 | ||
101 | /// read and validate data | |
102 | using read_validate_data_ertr = read_ertr; | |
103 | using read_validate_data_ret = read_validate_data_ertr::future<bool>; | |
104 | read_validate_data_ret read_validate_data( | |
105 | paddr_t record_base, | |
106 | const record_group_header_t &header ///< caller must ensure lifetime through | |
107 | /// future resolution | |
108 | ); | |
109 | ||
110 | using consume_record_group_ertr = scan_valid_records_ertr; | |
111 | consume_record_group_ertr::future<> consume_next_records( | |
112 | scan_valid_records_cursor& cursor, | |
113 | found_record_handler_t& handler, | |
114 | std::size_t& budget_used); | |
115 | ||
116 | friend class TransactionManager; | |
117 | }; | |
118 | ||
119 | using ExtentReaderRef = std::unique_ptr<ExtentReader>; | |
120 | ||
121 | } // namespace crimson::os::seastore |