]>
Commit | Line | Data |
---|---|---|
f67539c2 TL |
1 | // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- |
2 | // vim: ts=8 sw=2 smarttab | |
3 | ||
4 | #pragma once | |
5 | ||
6 | #include <iostream> | |
7 | ||
8 | #include <boost/intrusive_ptr.hpp> | |
9 | #include <boost/smart_ptr/intrusive_ref_counter.hpp> | |
10 | #include <seastar/core/future.hh> | |
11 | ||
12 | #include "include/ceph_assert.h" | |
13 | #include "include/buffer_fwd.h" | |
14 | #include "include/interval_set.h" | |
15 | #include "common/interval_map.h" | |
16 | #include "crimson/osd/exceptions.h" | |
17 | ||
18 | #include "crimson/os/seastore/seastore_types.h" | |
19 | #include "crimson/os/seastore/lba_manager.h" | |
20 | #include "crimson/os/seastore/cache.h" | |
21 | #include "crimson/os/seastore/segment_manager.h" | |
22 | ||
23 | #include "crimson/os/seastore/lba_manager/btree/lba_btree_node.h" | |
20effc67 | 24 | #include "crimson/os/seastore/lba_manager/btree/lba_btree.h" |
f67539c2 TL |
25 | |
26 | namespace crimson::os::seastore::lba_manager::btree { | |
27 | ||
28 | /** | |
29 | * BtreeLBAManager | |
30 | * | |
31 | * Uses a wandering btree to track two things: | |
32 | * 1) lba state including laddr_t -> paddr_t mapping | |
33 | * 2) reverse paddr_t -> laddr_t mapping for gc (TODO) | |
34 | * | |
35 | * Generally, any transaction will involve | |
36 | * 1) deltas against lba tree nodes | |
37 | * 2) new lba tree nodes | |
38 | * - Note, there must necessarily be a delta linking | |
39 | * these new nodes into the tree -- might be a | |
40 | * bootstrap_state_t delta if new root | |
41 | * | |
42 | * get_mappings, alloc_extent_*, etc populate a Transaction | |
43 | * which then gets submitted | |
44 | */ | |
45 | class BtreeLBAManager : public LBAManager { | |
46 | public: | |
47 | BtreeLBAManager( | |
48 | SegmentManager &segment_manager, | |
49 | Cache &cache); | |
50 | ||
51 | mkfs_ret mkfs( | |
52 | Transaction &t) final; | |
53 | ||
20effc67 | 54 | get_mappings_ret get_mappings( |
f67539c2 TL |
55 | Transaction &t, |
56 | laddr_t offset, extent_len_t length) final; | |
57 | ||
58 | get_mappings_ret get_mappings( | |
59 | Transaction &t, | |
60 | laddr_list_t &&list) final; | |
61 | ||
20effc67 TL |
62 | get_mapping_ret get_mapping( |
63 | Transaction &t, | |
64 | laddr_t offset) final; | |
65 | ||
f67539c2 TL |
66 | alloc_extent_ret alloc_extent( |
67 | Transaction &t, | |
68 | laddr_t hint, | |
69 | extent_len_t len, | |
70 | paddr_t addr) final; | |
71 | ||
f67539c2 TL |
72 | ref_ret decref_extent( |
73 | Transaction &t, | |
74 | laddr_t addr) final { | |
75 | return update_refcount(t, addr, -1); | |
76 | } | |
77 | ||
78 | ref_ret incref_extent( | |
79 | Transaction &t, | |
80 | laddr_t addr) final { | |
81 | return update_refcount(t, addr, 1); | |
82 | } | |
83 | ||
20effc67 | 84 | void complete_transaction( |
f67539c2 TL |
85 | Transaction &t) final; |
86 | ||
87 | init_cached_extent_ret init_cached_extent( | |
88 | Transaction &t, | |
89 | CachedExtentRef e) final; | |
90 | ||
91 | scan_mappings_ret scan_mappings( | |
92 | Transaction &t, | |
93 | laddr_t begin, | |
94 | laddr_t end, | |
95 | scan_mappings_func_t &&f) final; | |
96 | ||
97 | scan_mapped_space_ret scan_mapped_space( | |
98 | Transaction &t, | |
99 | scan_mapped_space_func_t &&f) final; | |
100 | ||
101 | rewrite_extent_ret rewrite_extent( | |
102 | Transaction &t, | |
20effc67 TL |
103 | CachedExtentRef extent) final; |
104 | ||
105 | update_le_mapping_ret update_mapping( | |
106 | Transaction& t, | |
107 | laddr_t laddr, | |
108 | paddr_t prev_addr, | |
109 | paddr_t paddr) final; | |
f67539c2 TL |
110 | |
111 | get_physical_extent_if_live_ret get_physical_extent_if_live( | |
112 | Transaction &t, | |
113 | extent_types_t type, | |
114 | paddr_t addr, | |
115 | laddr_t laddr, | |
116 | segment_off_t len) final; | |
117 | ||
118 | void add_pin(LBAPin &pin) final { | |
119 | auto *bpin = reinterpret_cast<BtreeLBAPin*>(&pin); | |
120 | pin_set.add_pin(bpin->pin); | |
121 | bpin->parent = nullptr; | |
122 | } | |
123 | ||
20effc67 | 124 | ~BtreeLBAManager(); |
f67539c2 TL |
125 | private: |
126 | SegmentManager &segment_manager; | |
127 | Cache &cache; | |
128 | ||
129 | btree_pin_set_t pin_set; | |
130 | ||
131 | op_context_t get_context(Transaction &t) { | |
20effc67 | 132 | return op_context_t{cache, t, &pin_set}; |
f67539c2 TL |
133 | } |
134 | ||
135 | static btree_range_pin_t &get_pin(CachedExtent &e); | |
136 | ||
20effc67 TL |
137 | seastar::metrics::metric_group metrics; |
138 | void register_metrics(); | |
139 | template <typename F, typename... Args> | |
140 | auto with_btree( | |
141 | op_context_t c, | |
142 | F &&f) { | |
143 | return cache.get_root( | |
144 | c.trans | |
145 | ).si_then([this, c, f=std::forward<F>(f)](RootBlockRef croot) mutable { | |
146 | return seastar::do_with( | |
147 | LBABtree(croot->get_root().lba_root), | |
148 | [this, c, croot, f=std::move(f)](auto &btree) mutable { | |
149 | return f( | |
150 | btree | |
151 | ).si_then([this, c, croot, &btree] { | |
152 | if (btree.is_root_dirty()) { | |
153 | auto mut_croot = cache.duplicate_for_write( | |
154 | c.trans, croot | |
155 | )->cast<RootBlock>(); | |
156 | mut_croot->get_root().lba_root = btree.get_root_undirty(); | |
157 | } | |
158 | return base_iertr::now(); | |
159 | }); | |
160 | }); | |
161 | }); | |
162 | } | |
f67539c2 | 163 | |
20effc67 TL |
164 | template <typename State, typename F> |
165 | auto with_btree_state( | |
166 | op_context_t c, | |
167 | State &&init, | |
168 | F &&f) { | |
169 | return seastar::do_with( | |
170 | std::forward<State>(init), | |
171 | [this, c, f=std::forward<F>(f)](auto &state) mutable { | |
172 | (void)this; // silence incorrect clang warning about capture | |
173 | return with_btree(c, [&state, f=std::move(f)](auto &btree) mutable { | |
174 | return f(btree, state); | |
175 | }).si_then([&state] { | |
176 | return seastar::make_ready_future<State>(std::move(state)); | |
177 | }); | |
178 | }); | |
179 | } | |
f67539c2 | 180 | |
20effc67 TL |
181 | template <typename State, typename F> |
182 | auto with_btree_state( | |
183 | op_context_t c, | |
184 | F &&f) { | |
185 | return with_btree_state<State, F>(c, State{}, std::forward<F>(f)); | |
186 | } | |
187 | ||
188 | template <typename Ret, typename F> | |
189 | auto with_btree_ret( | |
190 | op_context_t c, | |
191 | F &&f) { | |
192 | return with_btree_state<Ret>( | |
193 | c, | |
194 | [f=std::forward<F>(f)](auto &btree, auto &ret) mutable { | |
195 | return f( | |
196 | btree | |
197 | ).si_then([&ret](auto &&_ret) { | |
198 | ret = std::move(_ret); | |
199 | }); | |
200 | }); | |
201 | } | |
f67539c2 TL |
202 | |
203 | /** | |
204 | * update_refcount | |
205 | * | |
206 | * Updates refcount, returns resulting refcount | |
207 | */ | |
208 | using update_refcount_ret = ref_ret; | |
209 | update_refcount_ret update_refcount( | |
210 | Transaction &t, | |
211 | laddr_t addr, | |
212 | int delta); | |
213 | ||
214 | /** | |
215 | * update_mapping | |
216 | * | |
217 | * Updates mapping, removes if f returns nullopt | |
218 | */ | |
20effc67 TL |
219 | using update_mapping_iertr = ref_iertr; |
220 | using update_mapping_ret = ref_iertr::future<lba_map_val_t>; | |
221 | using update_func_t = std::function< | |
222 | lba_map_val_t(const lba_map_val_t &v) | |
223 | >; | |
f67539c2 TL |
224 | update_mapping_ret update_mapping( |
225 | Transaction &t, | |
226 | laddr_t addr, | |
227 | update_func_t &&f); | |
f67539c2 TL |
228 | }; |
229 | using BtreeLBAManagerRef = std::unique_ptr<BtreeLBAManager>; | |
230 | ||
231 | } |