]> git.proxmox.com Git - ceph.git/blame - ceph/src/crimson/os/seastore/lba_manager/btree/lba_btree_node.h
update ceph source to reef 18.1.2
[ceph.git] / ceph / src / crimson / os / seastore / lba_manager / btree / lba_btree_node.h
CommitLineData
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 <sys/mman.h>
7#include <memory>
8#include <string.h>
9
20effc67
TL
10
11#include "include/buffer.h"
12
13#include "crimson/common/fixed_kv_node_layout.h"
14#include "crimson/common/errorator.h"
f67539c2 15#include "crimson/os/seastore/lba_manager.h"
20effc67
TL
16#include "crimson/os/seastore/seastore_types.h"
17#include "crimson/os/seastore/cache.h"
18#include "crimson/os/seastore/cached_extent.h"
1e59de90
TL
19
20#include "crimson/os/seastore/btree/btree_range_pin.h"
21#include "crimson/os/seastore/btree/fixed_kv_btree.h"
22#include "crimson/os/seastore/btree/fixed_kv_node.h"
f67539c2
TL
23
24namespace crimson::os::seastore::lba_manager::btree {
25
20effc67 26using base_iertr = LBAManager::base_iertr;
1e59de90 27using LBANode = FixedKVNode<laddr_t>;
f67539c2
TL
28
29/**
30 * lba_map_val_t
31 *
32 * struct representing a single lba mapping
33 */
34struct lba_map_val_t {
35 extent_len_t len = 0; ///< length of mapping
36 paddr_t paddr; ///< physical addr of mapping
37 uint32_t refcount = 0; ///< refcount
38 uint32_t checksum = 0; ///< checksum of original block written at paddr (TODO)
39
20effc67 40 lba_map_val_t() = default;
f67539c2
TL
41 lba_map_val_t(
42 extent_len_t len,
43 paddr_t paddr,
44 uint32_t refcount,
45 uint32_t checksum)
46 : len(len), paddr(paddr), refcount(refcount), checksum(checksum) {}
1e59de90 47 bool operator==(const lba_map_val_t&) const = default;
f67539c2
TL
48};
49
1e59de90 50std::ostream& operator<<(std::ostream& out, const lba_map_val_t&);
f67539c2 51
20effc67
TL
52constexpr size_t LBA_BLOCK_SIZE = 4096;
53
1e59de90 54using lba_node_meta_t = fixed_kv_node_meta_t<laddr_t>;
f67539c2 55
1e59de90 56using lba_node_meta_le_t = fixed_kv_node_meta_le_t<laddr_le_t>;
f67539c2 57
20effc67
TL
58/**
59 * LBAInternalNode
60 *
61 * Abstracts operations on and layout of internal nodes for the
62 * LBA Tree.
63 *
64 * Layout (4k):
65 * size : uint32_t[1] 4b
66 * (padding) : 4b
67 * meta : lba_node_meta_le_t[3] (1*24)b
68 * keys : laddr_t[255] (254*8)b
69 * values : paddr_t[255] (254*8)b
70 * = 4096
71
72 * TODO: make the above capacity calculation part of FixedKVNodeLayout
73 * TODO: the above alignment probably isn't portable without further work
74 */
75constexpr size_t INTERNAL_NODE_CAPACITY = 254;
76struct LBAInternalNode
1e59de90 77 : FixedKVInternalNode<
20effc67 78 INTERNAL_NODE_CAPACITY,
20effc67 79 laddr_t, laddr_le_t,
1e59de90
TL
80 LBA_BLOCK_SIZE,
81 LBAInternalNode> {
20effc67
TL
82 using Ref = TCachedExtentRef<LBAInternalNode>;
83 using internal_iterator_t = const_iterator;
84 template <typename... T>
85 LBAInternalNode(T&&... t) :
1e59de90 86 FixedKVInternalNode(std::forward<T>(t)...) {}
20effc67
TL
87
88 static constexpr extent_types_t TYPE = extent_types_t::LADDR_INTERNAL;
89
20effc67
TL
90 extent_types_t get_type() const final {
91 return TYPE;
92 }
f67539c2 93};
20effc67 94using LBAInternalNodeRef = LBAInternalNode::Ref;
f67539c2
TL
95
96/**
20effc67
TL
97 * LBALeafNode
98 *
99 * Abstracts operations on and layout of leaf nodes for the
100 * LBA Tree.
101 *
102 * Layout (4k):
103 * size : uint32_t[1] 4b
104 * (padding) : 4b
105 * meta : lba_node_meta_le_t[3] (1*24)b
106 * keys : laddr_t[170] (145*8)b
107 * values : lba_map_val_t[170] (145*20)b
108 * = 4092
f67539c2 109 *
20effc67
TL
110 * TODO: update FixedKVNodeLayout to handle the above calculation
111 * TODO: the above alignment probably isn't portable without further work
f67539c2 112 */
20effc67
TL
113constexpr size_t LEAF_NODE_CAPACITY = 145;
114
115/**
116 * lba_map_val_le_t
117 *
118 * On disk layout for lba_map_val_t.
119 */
120struct lba_map_val_le_t {
121 extent_len_le_t len = init_extent_len_le(0);
122 paddr_le_t paddr;
123 ceph_le32 refcount{0};
124 ceph_le32 checksum{0};
125
126 lba_map_val_le_t() = default;
127 lba_map_val_le_t(const lba_map_val_le_t &) = default;
128 explicit lba_map_val_le_t(const lba_map_val_t &val)
129 : len(init_extent_len_le(val.len)),
130 paddr(paddr_le_t(val.paddr)),
131 refcount(val.refcount),
132 checksum(val.checksum) {}
133
134 operator lba_map_val_t() const {
135 return lba_map_val_t{ len, paddr, refcount, checksum };
136 }
137};
138
139struct LBALeafNode
1e59de90 140 : FixedKVLeafNode<
20effc67 141 LEAF_NODE_CAPACITY,
20effc67 142 laddr_t, laddr_le_t,
1e59de90
TL
143 lba_map_val_t, lba_map_val_le_t,
144 LBA_BLOCK_SIZE,
145 LBALeafNode,
146 true> {
20effc67 147 using Ref = TCachedExtentRef<LBALeafNode>;
1e59de90
TL
148 using parent_type_t = FixedKVLeafNode<
149 LEAF_NODE_CAPACITY,
150 laddr_t, laddr_le_t,
151 lba_map_val_t, lba_map_val_le_t,
152 LBA_BLOCK_SIZE,
153 LBALeafNode,
154 true>;
155 using internal_const_iterator_t =
156 typename parent_type_t::node_layout_t::const_iterator;
157 using internal_iterator_t =
158 typename parent_type_t::node_layout_t::iterator;
20effc67
TL
159 template <typename... T>
160 LBALeafNode(T&&... t) :
1e59de90 161 parent_type_t(std::forward<T>(t)...) {}
20effc67
TL
162
163 static constexpr extent_types_t TYPE = extent_types_t::LADDR_LEAF;
164
1e59de90
TL
165 bool validate_stable_children() final {
166 LOG_PREFIX(LBALeafNode::validate_stable_children);
167 if (this->children.empty()) {
168 return false;
169 }
20effc67 170
1e59de90
TL
171 for (auto i : *this) {
172 auto child = (LogicalCachedExtent*)this->children[i.get_offset()];
173 if (is_valid_child_ptr(child) && child->get_laddr() != i.get_key()) {
174 SUBERROR(seastore_fixedkv_tree,
175 "stable child not valid: child {}, key {}",
176 *child,
177 i.get_key());
178 ceph_abort();
179 return false;
180 }
181 }
182 return true;
20effc67
TL
183 }
184
185 void update(
1e59de90
TL
186 internal_const_iterator_t iter,
187 lba_map_val_t val,
188 LogicalCachedExtent* nextent) final {
189 LOG_PREFIX(LBALeafNode::update);
190 if (nextent) {
191 SUBTRACE(seastore_fixedkv_tree, "trans.{}, pos {}, {}",
192 this->pending_for_transaction,
193 iter.get_offset(),
194 *nextent);
195 // child-ptr may already be correct, see LBAManager::update_mappings()
196 this->update_child_ptr(iter, nextent);
197 }
198 val.paddr = this->maybe_generate_relative(val.paddr);
199 return this->journal_update(
20effc67
TL
200 iter,
201 val,
1e59de90 202 this->maybe_get_delta_buffer());
20effc67
TL
203 }
204
1e59de90
TL
205 internal_const_iterator_t insert(
206 internal_const_iterator_t iter,
20effc67 207 laddr_t addr,
1e59de90
TL
208 lba_map_val_t val,
209 LogicalCachedExtent* nextent) final {
210 LOG_PREFIX(LBALeafNode::insert);
211 SUBTRACE(seastore_fixedkv_tree, "trans.{}, pos {}, key {}, extent {}",
212 this->pending_for_transaction,
213 iter.get_offset(),
214 addr,
215 (void*)nextent);
216 this->insert_child_ptr(iter, nextent);
217 val.paddr = this->maybe_generate_relative(val.paddr);
218 this->journal_insert(
20effc67
TL
219 iter,
220 addr,
221 val,
1e59de90 222 this->maybe_get_delta_buffer());
20effc67
TL
223 return iter;
224 }
225
1e59de90
TL
226 void remove(internal_const_iterator_t iter) final {
227 LOG_PREFIX(LBALeafNode::remove);
228 SUBTRACE(seastore_fixedkv_tree, "trans.{}, pos {}, key {}",
229 this->pending_for_transaction,
230 iter.get_offset(),
231 iter.get_key());
232 assert(iter != this->end());
233 this->remove_child_ptr(iter);
234 return this->journal_remove(
20effc67 235 iter,
1e59de90 236 this->maybe_get_delta_buffer());
20effc67
TL
237 }
238
239 // See LBAInternalNode, same concept
240 void resolve_relative_addrs(paddr_t base);
1e59de90
TL
241 void node_resolve_vals(
242 internal_iterator_t from,
243 internal_iterator_t to) const final
244 {
245 if (this->is_initial_pending()) {
20effc67
TL
246 for (auto i = from; i != to; ++i) {
247 auto val = i->get_val();
248 if (val.paddr.is_relative()) {
249 assert(val.paddr.is_block_relative());
1e59de90 250 val.paddr = this->get_paddr().add_relative(val.paddr);
20effc67
TL
251 i->set_val(val);
252 }
253 }
254 }
255 }
1e59de90
TL
256 void node_unresolve_vals(
257 internal_iterator_t from,
258 internal_iterator_t to) const final
259 {
260 if (this->is_initial_pending()) {
20effc67
TL
261 for (auto i = from; i != to; ++i) {
262 auto val = i->get_val();
263 if (val.paddr.is_relative()) {
264 auto val = i->get_val();
265 assert(val.paddr.is_record_relative());
1e59de90 266 val.paddr = val.paddr.block_relative_to(this->get_paddr());
20effc67
TL
267 i->set_val(val);
268 }
269 }
270 }
271 }
272
20effc67
TL
273 extent_types_t get_type() const final {
274 return TYPE;
275 }
276
1e59de90 277 std::ostream &_print_detail(std::ostream &out) const final;
20effc67
TL
278};
279using LBALeafNodeRef = TCachedExtentRef<LBALeafNode>;
f67539c2
TL
280
281}
1e59de90
TL
282
283#if FMT_VERSION >= 90000
284template <> struct fmt::formatter<crimson::os::seastore::lba_manager::btree::lba_node_meta_t> : fmt::ostream_formatter {};
285template <> struct fmt::formatter<crimson::os::seastore::lba_manager::btree::lba_map_val_t> : fmt::ostream_formatter {};
286template <> struct fmt::formatter<crimson::os::seastore::lba_manager::btree::LBAInternalNode> : fmt::ostream_formatter {};
287template <> struct fmt::formatter<crimson::os::seastore::lba_manager::btree::LBALeafNode> : fmt::ostream_formatter {};
288#endif