]> git.proxmox.com Git - ceph.git/blame - ceph/src/crimson/os/seastore/seastore_types.h
buildsys: switch source download to quincy
[ceph.git] / ceph / src / crimson / os / seastore / seastore_types.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 <limits>
7#include <iostream>
8
9#include "include/byteorder.h"
10#include "include/denc.h"
11#include "include/buffer.h"
12#include "include/cmp.h"
13#include "include/uuid.h"
14
15namespace crimson::os::seastore {
16
17using depth_t = int32_t;
18using depth_le_t = ceph_les32;
19
20using checksum_t = uint32_t;
21
22// Immutable metadata for seastore to set at mkfs time
23struct seastore_meta_t {
24 uuid_d seastore_id;
25
26 DENC(seastore_meta_t, v, p) {
27 DENC_START(1, 1, p);
28 denc(v.seastore_id, p);
29 DENC_FINISH(p);
30 }
31};
32
33// Identifies segment location on disk, see SegmentManager,
34using segment_id_t = uint32_t;
35constexpr segment_id_t NULL_SEG_ID =
36 std::numeric_limits<segment_id_t>::max() - 1;
37/* Used to denote relative paddr_t */
38constexpr segment_id_t RECORD_REL_SEG_ID =
39 std::numeric_limits<segment_id_t>::max() - 2;
40constexpr segment_id_t BLOCK_REL_SEG_ID =
41 std::numeric_limits<segment_id_t>::max() - 3;
42
43// for tests which generate fake paddrs
44constexpr segment_id_t FAKE_SEG_ID =
45 std::numeric_limits<segment_id_t>::max() - 4;
46
47std::ostream &segment_to_stream(std::ostream &, const segment_id_t &t);
48
49// Offset within a segment on disk, see SegmentManager
50// may be negative for relative offsets
51using segment_off_t = int32_t;
52constexpr segment_off_t NULL_SEG_OFF =
53 std::numeric_limits<segment_id_t>::max();
54
55std::ostream &offset_to_stream(std::ostream &, const segment_off_t &t);
56
57/* Monotonically increasing segment seq, uniquely identifies
58 * the incarnation of a segment */
59using segment_seq_t = uint32_t;
60static constexpr segment_seq_t NULL_SEG_SEQ =
61 std::numeric_limits<segment_seq_t>::max();
62
63// Offset of delta within a record
64using record_delta_idx_t = uint32_t;
65constexpr record_delta_idx_t NULL_DELTA_IDX =
66 std::numeric_limits<record_delta_idx_t>::max();
67
68/**
69 * paddr_t
70 *
71 * <segment, offset> offset on disk, see SegmentManager
72 *
73 * May be absolute, record_relative, or block_relative.
74 *
75 * Blocks get read independently of the surrounding record,
76 * so paddrs embedded directly within a block need to refer
77 * to other blocks within the same record by a block_relative
78 * addr relative to the block's own offset. By contrast,
79 * deltas to existing blocks need to use record_relative
80 * addrs relative to the first block of the record.
81 *
82 * Fresh extents during a transaction are refered to by
83 * record_relative paddrs.
84 */
85struct paddr_t {
86 segment_id_t segment = NULL_SEG_ID;
87 segment_off_t offset = NULL_SEG_OFF;
88
89 bool is_relative() const {
90 return segment == RECORD_REL_SEG_ID ||
91 segment == BLOCK_REL_SEG_ID;
92 }
93
94 bool is_record_relative() const {
95 return segment == RECORD_REL_SEG_ID;
96 }
97
98 bool is_block_relative() const {
99 return segment == BLOCK_REL_SEG_ID;
100 }
101
102 paddr_t add_offset(segment_off_t o) const {
103 return paddr_t{segment, offset + o};
104 }
105
106 paddr_t add_relative(paddr_t o) const {
107 assert(o.is_relative());
108 return paddr_t{segment, offset + o.offset};
109 }
110
111 paddr_t add_block_relative(paddr_t o) const {
112 // special version mainly for documentation purposes
113 assert(o.is_block_relative());
114 return add_relative(o);
115 }
116
117 paddr_t add_record_relative(paddr_t o) const {
118 // special version mainly for documentation purposes
119 assert(o.is_record_relative());
120 return add_relative(o);
121 }
122
123 /**
124 * paddr_t::operator-
125 *
126 * Only defined for record_relative paddr_ts. Yields a
127 * block_relative address.
128 */
129 paddr_t operator-(paddr_t rhs) const {
130 assert(rhs.is_relative() && is_relative());
131 assert(rhs.segment == segment);
132 return paddr_t{
133 BLOCK_REL_SEG_ID,
134 offset - rhs.offset
135 };
136 }
137
138 /**
139 * maybe_relative_to
140 *
141 * Helper for the case where an in-memory paddr_t may be
142 * either block_relative or absolute (not record_relative).
143 *
144 * base must be either absolute or record_relative.
145 */
146 paddr_t maybe_relative_to(paddr_t base) const {
147 assert(!base.is_block_relative());
148 if (is_block_relative())
149 return base.add_block_relative(*this);
150 else
151 return *this;
152 }
153
154 DENC(paddr_t, v, p) {
155 DENC_START(1, 1, p);
156 denc(v.segment, p);
157 denc(v.offset, p);
158 DENC_FINISH(p);
159 }
160};
161WRITE_CMP_OPERATORS_2(paddr_t, segment, offset)
162WRITE_EQ_OPERATORS_2(paddr_t, segment, offset)
163constexpr paddr_t P_ADDR_NULL = paddr_t{};
164constexpr paddr_t P_ADDR_MIN = paddr_t{0, 0};
165constexpr paddr_t make_record_relative_paddr(segment_off_t off) {
166 return paddr_t{RECORD_REL_SEG_ID, off};
167}
168constexpr paddr_t make_block_relative_paddr(segment_off_t off) {
169 return paddr_t{BLOCK_REL_SEG_ID, off};
170}
171constexpr paddr_t make_fake_paddr(segment_off_t off) {
172 return paddr_t{FAKE_SEG_ID, off};
173}
174
175struct paddr_le_t {
176 ceph_le32 segment = init_le32(NULL_SEG_ID);
177 ceph_les32 offset = init_les32(NULL_SEG_OFF);
178
179 paddr_le_t() = default;
180 paddr_le_t(ceph_le32 segment, ceph_les32 offset)
181 : segment(segment), offset(offset) {}
182 paddr_le_t(segment_id_t segment, segment_off_t offset)
183 : segment(init_le32(segment)), offset(init_les32(offset)) {}
184 paddr_le_t(const paddr_t &addr) : paddr_le_t(addr.segment, addr.offset) {}
185
186 operator paddr_t() const {
187 return paddr_t{segment, offset};
188 }
189};
190
191std::ostream &operator<<(std::ostream &out, const paddr_t &rhs);
192
193using objaddr_t = uint32_t;
194constexpr objaddr_t OBJ_ADDR_MIN = std::numeric_limits<objaddr_t>::min();
195
196/* Monotonically increasing identifier for the location of a
197 * journal_record.
198 */
199struct journal_seq_t {
200 segment_seq_t segment_seq = 0;
201 paddr_t offset;
202
203 DENC(journal_seq_t, v, p) {
204 DENC_START(1, 1, p);
205 denc(v.segment_seq, p);
206 denc(v.offset, p);
207 DENC_FINISH(p);
208 }
209};
210WRITE_CMP_OPERATORS_2(journal_seq_t, segment_seq, offset)
211WRITE_EQ_OPERATORS_2(journal_seq_t, segment_seq, offset)
212
213std::ostream &operator<<(std::ostream &out, const journal_seq_t &seq);
214
215static constexpr journal_seq_t NO_DELTAS = journal_seq_t{
216 NULL_SEG_SEQ,
217 P_ADDR_NULL
218};
219
220// logical addr, see LBAManager, TransactionManager
221using laddr_t = uint64_t;
222constexpr laddr_t L_ADDR_MIN = std::numeric_limits<laddr_t>::min();
223constexpr laddr_t L_ADDR_MAX = std::numeric_limits<laddr_t>::max();
224constexpr laddr_t L_ADDR_NULL = std::numeric_limits<laddr_t>::max();
225constexpr laddr_t L_ADDR_ROOT = std::numeric_limits<laddr_t>::max() - 1;
226constexpr laddr_t L_ADDR_LBAT = std::numeric_limits<laddr_t>::max() - 2;
227
228struct laddr_le_t {
229 ceph_le64 laddr = init_le64(L_ADDR_NULL);
230
231 laddr_le_t() = default;
232 laddr_le_t(const laddr_le_t &) = default;
233 explicit laddr_le_t(const laddr_t &addr)
234 : laddr(init_le64(addr)) {}
235
236 operator laddr_t() const {
237 return laddr_t(laddr);
238 }
239 laddr_le_t& operator=(laddr_t addr) {
240 ceph_le64 val;
241 val = addr;
242 laddr = val;
243 return *this;
244 }
245};
246
247// logical offset, see LBAManager, TransactionManager
248using extent_len_t = uint32_t;
249constexpr extent_len_t EXTENT_LEN_MAX =
250 std::numeric_limits<extent_len_t>::max();
251
252using extent_len_le_t = ceph_le32;
253inline extent_len_le_t init_extent_len_le_t(extent_len_t len) {
254 return init_le32(len);
255}
256
257struct laddr_list_t : std::list<std::pair<laddr_t, extent_len_t>> {
258 template <typename... T>
259 laddr_list_t(T&&... args)
260 : std::list<std::pair<laddr_t, extent_len_t>>(std::forward<T>(args)...) {}
261};
262struct paddr_list_t : std::list<std::pair<paddr_t, extent_len_t>> {
263 template <typename... T>
264 paddr_list_t(T&&... args)
265 : std::list<std::pair<paddr_t, extent_len_t>>(std::forward<T>(args)...) {}
266};
267
268std::ostream &operator<<(std::ostream &out, const laddr_list_t &rhs);
269std::ostream &operator<<(std::ostream &out, const paddr_list_t &rhs);
270
271/* identifies type of extent, used for interpretting deltas, managing
272 * writeback.
273 *
274 * Note that any new extent type needs to be added to
275 * Cache::get_extent_by_type in cache.cc
276 */
277enum class extent_types_t : uint8_t {
278 ROOT = 0,
279 LADDR_INTERNAL = 1,
280 LADDR_LEAF = 2,
281 ONODE_BLOCK = 3,
282 EXTMAP_INNER = 4,
283 EXTMAP_LEAF = 5,
284 ONODE_BLOCK_STAGED = 6,
285
286 // Test Block Types
287 TEST_BLOCK = 0xF0,
288 TEST_BLOCK_PHYSICAL = 0xF1,
289
290 // None
291 NONE = 0xFF
292};
293
294inline bool is_logical_type(extent_types_t type) {
295 switch (type) {
296 case extent_types_t::ROOT:
297 case extent_types_t::LADDR_INTERNAL:
298 case extent_types_t::LADDR_LEAF:
299 return false;
300 default:
301 return true;
302 }
303}
304
305std::ostream &operator<<(std::ostream &out, extent_types_t t);
306
307/* description of a new physical extent */
308struct extent_t {
309 extent_types_t type; ///< type of extent
310 laddr_t addr; ///< laddr of extent (L_ADDR_NULL for non-logical)
311 ceph::bufferlist bl; ///< payload, bl.length() == length, aligned
312};
313
314using extent_version_t = uint32_t;
315constexpr extent_version_t EXTENT_VERSION_NULL = 0;
316
317/* description of a mutation to a physical extent */
318struct delta_info_t {
319 extent_types_t type = extent_types_t::NONE; ///< delta type
320 paddr_t paddr; ///< physical address
321 laddr_t laddr = L_ADDR_NULL; ///< logical address
322 uint32_t prev_crc = 0;
323 uint32_t final_crc = 0;
324 segment_off_t length = NULL_SEG_OFF; ///< extent length
325 extent_version_t pversion; ///< prior version
326 ceph::bufferlist bl; ///< payload
327
328 DENC(delta_info_t, v, p) {
329 DENC_START(1, 1, p);
330 denc(v.type, p);
331 denc(v.paddr, p);
332 denc(v.laddr, p);
333 denc(v.prev_crc, p);
334 denc(v.final_crc, p);
335 denc(v.length, p);
336 denc(v.pversion, p);
337 denc(v.bl, p);
338 DENC_FINISH(p);
339 }
340
341 bool operator==(const delta_info_t &rhs) const {
342 return (
343 type == rhs.type &&
344 paddr == rhs.paddr &&
345 laddr == rhs.laddr &&
346 prev_crc == rhs.prev_crc &&
347 final_crc == rhs.final_crc &&
348 length == rhs.length &&
349 pversion == rhs.pversion &&
350 bl == rhs.bl
351 );
352 }
353
354 friend std::ostream &operator<<(std::ostream &lhs, const delta_info_t &rhs);
355};
356
357std::ostream &operator<<(std::ostream &lhs, const delta_info_t &rhs);
358
359struct record_t {
360 std::vector<extent_t> extents;
361 std::vector<delta_info_t> deltas;
362};
363
364}
365
366WRITE_CLASS_DENC_BOUNDED(crimson::os::seastore::seastore_meta_t)
367WRITE_CLASS_DENC_BOUNDED(crimson::os::seastore::paddr_t)
368WRITE_CLASS_DENC_BOUNDED(crimson::os::seastore::journal_seq_t)
369WRITE_CLASS_DENC_BOUNDED(crimson::os::seastore::delta_info_t)