]> git.proxmox.com Git - ceph.git/blob - ceph/src/os/bluestore/bluefs_types.h
import ceph pacific 16.2.5
[ceph.git] / ceph / src / os / bluestore / bluefs_types.h
1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab
3 #ifndef CEPH_OS_BLUESTORE_BLUEFS_TYPES_H
4 #define CEPH_OS_BLUESTORE_BLUEFS_TYPES_H
5
6 #include <optional>
7
8 #include "bluestore_types.h"
9 #include "include/utime.h"
10 #include "include/encoding.h"
11 #include "include/denc.h"
12
13 class bluefs_extent_t {
14 public:
15 uint64_t offset = 0;
16 uint32_t length = 0;
17 uint8_t bdev;
18
19 bluefs_extent_t(uint8_t b = 0, uint64_t o = 0, uint32_t l = 0)
20 : offset(o), length(l), bdev(b) {}
21
22 uint64_t end() const { return offset + length; }
23 DENC(bluefs_extent_t, v, p) {
24 DENC_START(1, 1, p);
25 denc_lba(v.offset, p);
26 denc_varint_lowz(v.length, p);
27 denc(v.bdev, p);
28 DENC_FINISH(p);
29 }
30
31 void dump(ceph::Formatter *f) const;
32 static void generate_test_instances(std::list<bluefs_extent_t*>&);
33 };
34 WRITE_CLASS_DENC(bluefs_extent_t)
35
36 std::ostream& operator<<(std::ostream& out, const bluefs_extent_t& e);
37
38 struct bluefs_fnode_t {
39 uint64_t ino;
40 uint64_t size;
41 utime_t mtime;
42 uint8_t __unused__; // was prefer_bdev
43 mempool::bluefs::vector<bluefs_extent_t> extents;
44
45 // precalculated logical offsets for extents vector entries
46 // allows fast lookup for extent index by the offset value via upper_bound()
47 mempool::bluefs::vector<uint64_t> extents_index;
48
49 uint64_t allocated;
50
51 bluefs_fnode_t() : ino(0), size(0), __unused__(0), allocated(0) {}
52
53 uint64_t get_allocated() const {
54 return allocated;
55 }
56
57 void recalc_allocated() {
58 allocated = 0;
59 extents_index.reserve(extents.size());
60 for (auto& p : extents) {
61 extents_index.emplace_back(allocated);
62 allocated += p.length;
63 }
64 }
65
66 DENC_HELPERS
67 void bound_encode(size_t& p) const {
68 _denc_friend(*this, p);
69 }
70 void encode(ceph::buffer::list::contiguous_appender& p) const {
71 DENC_DUMP_PRE(bluefs_fnode_t);
72 _denc_friend(*this, p);
73 }
74 void decode(ceph::buffer::ptr::const_iterator& p) {
75 _denc_friend(*this, p);
76 recalc_allocated();
77 }
78 template<typename T, typename P>
79 friend std::enable_if_t<std::is_same_v<bluefs_fnode_t, std::remove_const_t<T>>>
80 _denc_friend(T& v, P& p) {
81 DENC_START(1, 1, p);
82 denc_varint(v.ino, p);
83 denc_varint(v.size, p);
84 denc(v.mtime, p);
85 denc(v.__unused__, p);
86 denc(v.extents, p);
87 DENC_FINISH(p);
88 }
89
90 void append_extent(const bluefs_extent_t& ext) {
91 if (!extents.empty() &&
92 extents.back().end() == ext.offset &&
93 extents.back().bdev == ext.bdev &&
94 (uint64_t)extents.back().length + (uint64_t)ext.length < 0xffffffff) {
95 extents.back().length += ext.length;
96 } else {
97 extents_index.emplace_back(allocated);
98 extents.push_back(ext);
99 }
100 allocated += ext.length;
101 }
102
103 void pop_front_extent() {
104 auto it = extents.begin();
105 allocated -= it->length;
106 extents_index.erase(extents_index.begin());
107 for (auto& i: extents_index) {
108 i -= it->length;
109 }
110 extents.erase(it);
111 }
112
113 void swap_extents(bluefs_fnode_t& other) {
114 other.extents.swap(extents);
115 other.extents_index.swap(extents_index);
116 std::swap(allocated, other.allocated);
117 }
118 void clear_extents() {
119 extents_index.clear();
120 extents.clear();
121 allocated = 0;
122 }
123
124 mempool::bluefs::vector<bluefs_extent_t>::iterator seek(
125 uint64_t off, uint64_t *x_off);
126
127 void dump(ceph::Formatter *f) const;
128 static void generate_test_instances(std::list<bluefs_fnode_t*>& ls);
129
130 };
131 WRITE_CLASS_DENC(bluefs_fnode_t)
132
133 std::ostream& operator<<(std::ostream& out, const bluefs_fnode_t& file);
134
135 struct bluefs_layout_t {
136 unsigned shared_bdev = 0; ///< which bluefs bdev we are sharing
137 bool dedicated_db = false; ///< whether block.db is present
138 bool dedicated_wal = false; ///< whether block.wal is present
139
140 bool single_shared_device() const {
141 return !dedicated_db && !dedicated_wal;
142 }
143
144 bool operator==(const bluefs_layout_t& other) const {
145 return shared_bdev == other.shared_bdev &&
146 dedicated_db == other.dedicated_db &&
147 dedicated_wal == other.dedicated_wal;
148 }
149
150 void encode(ceph::buffer::list& bl) const;
151 void decode(ceph::buffer::list::const_iterator& p);
152 void dump(ceph::Formatter *f) const;
153 };
154 WRITE_CLASS_ENCODER(bluefs_layout_t)
155
156 struct bluefs_super_t {
157 uuid_d uuid; ///< unique to this bluefs instance
158 uuid_d osd_uuid; ///< matches the osd that owns us
159 uint64_t version;
160 uint32_t block_size;
161
162 bluefs_fnode_t log_fnode;
163
164 std::optional<bluefs_layout_t> memorized_layout;
165
166 bluefs_super_t()
167 : version(0),
168 block_size(4096) { }
169
170 uint64_t block_mask() const {
171 return ~((uint64_t)block_size - 1);
172 }
173
174 void encode(ceph::buffer::list& bl) const;
175 void decode(ceph::buffer::list::const_iterator& p);
176 void dump(ceph::Formatter *f) const;
177 static void generate_test_instances(std::list<bluefs_super_t*>& ls);
178 };
179 WRITE_CLASS_ENCODER(bluefs_super_t)
180
181 std::ostream& operator<<(std::ostream&, const bluefs_super_t& s);
182
183
184 struct bluefs_transaction_t {
185 typedef enum {
186 OP_NONE = 0,
187 OP_INIT, ///< initial (empty) file system marker
188 OP_ALLOC_ADD, ///< OBSOLETE: add extent to available block storage (extent)
189 OP_ALLOC_RM, ///< OBSOLETE: remove extent from available block storage (extent)
190 OP_DIR_LINK, ///< (re)set a dir entry (dirname, filename, ino)
191 OP_DIR_UNLINK, ///< remove a dir entry (dirname, filename)
192 OP_DIR_CREATE, ///< create a dir (dirname)
193 OP_DIR_REMOVE, ///< remove a dir (dirname)
194 OP_FILE_UPDATE, ///< set/update file metadata (file)
195 OP_FILE_REMOVE, ///< remove file (ino)
196 OP_JUMP, ///< jump the seq # and offset
197 OP_JUMP_SEQ, ///< jump the seq #
198 } op_t;
199
200 uuid_d uuid; ///< fs uuid
201 uint64_t seq; ///< sequence number
202 ceph::buffer::list op_bl; ///< encoded transaction ops
203
204 bluefs_transaction_t() : seq(0) {}
205
206 void clear() {
207 *this = bluefs_transaction_t();
208 }
209 bool empty() const {
210 return op_bl.length() == 0;
211 }
212
213 void op_init() {
214 using ceph::encode;
215 encode((__u8)OP_INIT, op_bl);
216 }
217 void op_dir_create(std::string_view dir) {
218 using ceph::encode;
219 encode((__u8)OP_DIR_CREATE, op_bl);
220 encode(dir, op_bl);
221 }
222 void op_dir_remove(std::string_view dir) {
223 using ceph::encode;
224 encode((__u8)OP_DIR_REMOVE, op_bl);
225 encode(dir, op_bl);
226 }
227 void op_dir_link(std::string_view dir, std::string_view file, uint64_t ino) {
228 using ceph::encode;
229 encode((__u8)OP_DIR_LINK, op_bl);
230 encode(dir, op_bl);
231 encode(file, op_bl);
232 encode(ino, op_bl);
233 }
234 void op_dir_unlink(std::string_view dir, std::string_view file) {
235 using ceph::encode;
236 encode((__u8)OP_DIR_UNLINK, op_bl);
237 encode(dir, op_bl);
238 encode(file, op_bl);
239 }
240 void op_file_update(const bluefs_fnode_t& file) {
241 using ceph::encode;
242 encode((__u8)OP_FILE_UPDATE, op_bl);
243 encode(file, op_bl);
244 }
245 void op_file_remove(uint64_t ino) {
246 using ceph::encode;
247 encode((__u8)OP_FILE_REMOVE, op_bl);
248 encode(ino, op_bl);
249 }
250 void op_jump(uint64_t next_seq, uint64_t offset) {
251 using ceph::encode;
252 encode((__u8)OP_JUMP, op_bl);
253 encode(next_seq, op_bl);
254 encode(offset, op_bl);
255 }
256 void op_jump_seq(uint64_t next_seq) {
257 using ceph::encode;
258 encode((__u8)OP_JUMP_SEQ, op_bl);
259 encode(next_seq, op_bl);
260 }
261 void claim_ops(bluefs_transaction_t& from) {
262 op_bl.claim_append(from.op_bl);
263 }
264
265 void encode(ceph::buffer::list& bl) const;
266 void decode(ceph::buffer::list::const_iterator& p);
267 void dump(ceph::Formatter *f) const;
268 static void generate_test_instances(std::list<bluefs_transaction_t*>& ls);
269 };
270 WRITE_CLASS_ENCODER(bluefs_transaction_t)
271
272 std::ostream& operator<<(std::ostream& out, const bluefs_transaction_t& t);
273 #endif