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
8 #include "bluestore_types.h"
9 #include "include/utime.h"
10 #include "include/encoding.h"
11 #include "include/denc.h"
13 class bluefs_extent_t
{
19 bluefs_extent_t(uint8_t b
= 0, uint64_t o
= 0, uint32_t l
= 0)
20 : offset(o
), length(l
), bdev(b
) {}
22 uint64_t end() const { return offset
+ length
; }
23 DENC(bluefs_extent_t
, v
, p
) {
25 denc_lba(v
.offset
, p
);
26 denc_varint_lowz(v
.length
, p
);
31 void dump(ceph::Formatter
*f
) const;
32 static void generate_test_instances(std::list
<bluefs_extent_t
*>&);
34 WRITE_CLASS_DENC(bluefs_extent_t
)
36 std::ostream
& operator<<(std::ostream
& out
, const bluefs_extent_t
& e
);
38 struct bluefs_fnode_delta_t
{
42 uint64_t offset
; // Contains offset in file of extents.
43 // Equal to 'allocated' when created.
44 // Used for consistency checking.
45 mempool::bluefs::vector
<bluefs_extent_t
> extents
;
47 DENC(bluefs_fnode_delta_t
, v
, p
) {
49 denc_varint(v
.ino
, p
);
50 denc_varint(v
.size
, p
);
57 WRITE_CLASS_DENC(bluefs_fnode_delta_t
)
59 std::ostream
& operator<<(std::ostream
& out
, const bluefs_fnode_delta_t
& delta
);
61 struct bluefs_fnode_t
{
65 uint8_t __unused__
= 0; // was prefer_bdev
66 mempool::bluefs::vector
<bluefs_extent_t
> extents
;
68 // precalculated logical offsets for extents vector entries
69 // allows fast lookup for extent index by the offset value via upper_bound()
70 mempool::bluefs::vector
<uint64_t> extents_index
;
73 uint64_t allocated_commited
;
75 bluefs_fnode_t() : ino(0), size(0), allocated(0), allocated_commited(0) {}
76 bluefs_fnode_t(uint64_t _ino
, uint64_t _size
, utime_t _mtime
) :
77 ino(_ino
), size(_size
), mtime(_mtime
), allocated(0), allocated_commited(0) {}
78 bluefs_fnode_t(const bluefs_fnode_t
& other
) :
79 ino(other
.ino
), size(other
.size
), mtime(other
.mtime
),
80 allocated(other
.allocated
),
81 allocated_commited(other
.allocated_commited
) {
85 uint64_t get_allocated() const {
89 void recalc_allocated() {
91 extents_index
.reserve(extents
.size());
92 for (auto& p
: extents
) {
93 extents_index
.emplace_back(allocated
);
94 allocated
+= p
.length
;
96 allocated_commited
= allocated
;
100 void bound_encode(size_t& p
) const {
101 _denc_friend(*this, p
);
103 void encode(ceph::buffer::list::contiguous_appender
& p
) const {
104 DENC_DUMP_PRE(bluefs_fnode_t
);
105 _denc_friend(*this, p
);
107 void decode(ceph::buffer::ptr::const_iterator
& p
) {
108 _denc_friend(*this, p
);
111 template<typename T
, typename P
>
112 friend std::enable_if_t
<std::is_same_v
<bluefs_fnode_t
, std::remove_const_t
<T
>>>
113 _denc_friend(T
& v
, P
& p
) {
115 denc_varint(v
.ino
, p
);
116 denc_varint(v
.size
, p
);
118 denc(v
.__unused__
, p
);
123 allocated_commited
= allocated
;
125 void clone_extents(const bluefs_fnode_t
& fnode
) {
126 for (const auto& p
: fnode
.extents
) {
130 void claim_extents(mempool::bluefs::vector
<bluefs_extent_t
>& extents
) {
131 for (const auto& p
: extents
) {
136 void append_extent(const bluefs_extent_t
& ext
) {
137 if (!extents
.empty() &&
138 extents
.back().end() == ext
.offset
&&
139 extents
.back().bdev
== ext
.bdev
&&
140 (uint64_t)extents
.back().length
+ (uint64_t)ext
.length
< 0xffffffff) {
141 extents
.back().length
+= ext
.length
;
143 extents_index
.emplace_back(allocated
);
144 extents
.push_back(ext
);
146 allocated
+= ext
.length
;
149 void pop_front_extent() {
150 auto it
= extents
.begin();
151 allocated
-= it
->length
;
152 extents_index
.erase(extents_index
.begin());
153 for (auto& i
: extents_index
) {
159 void swap(bluefs_fnode_t
& other
) {
160 std::swap(ino
, other
.ino
);
161 std::swap(size
, other
.size
);
162 std::swap(mtime
, other
.mtime
);
165 void swap_extents(bluefs_fnode_t
& other
) {
166 other
.extents
.swap(extents
);
167 other
.extents_index
.swap(extents_index
);
168 std::swap(allocated
, other
.allocated
);
169 std::swap(allocated_commited
, other
.allocated_commited
);
171 void clear_extents() {
172 extents_index
.clear();
175 allocated_commited
= 0;
178 mempool::bluefs::vector
<bluefs_extent_t
>::iterator
seek(
179 uint64_t off
, uint64_t *x_off
);
180 bluefs_fnode_delta_t
* make_delta(bluefs_fnode_delta_t
* delta
);
182 void dump(ceph::Formatter
*f
) const;
183 static void generate_test_instances(std::list
<bluefs_fnode_t
*>& ls
);
186 WRITE_CLASS_DENC(bluefs_fnode_t
)
188 std::ostream
& operator<<(std::ostream
& out
, const bluefs_fnode_t
& file
);
190 struct bluefs_layout_t
{
191 unsigned shared_bdev
= 0; ///< which bluefs bdev we are sharing
192 bool dedicated_db
= false; ///< whether block.db is present
193 bool dedicated_wal
= false; ///< whether block.wal is present
195 bool single_shared_device() const {
196 return !dedicated_db
&& !dedicated_wal
;
199 bool operator==(const bluefs_layout_t
& other
) const {
200 return shared_bdev
== other
.shared_bdev
&&
201 dedicated_db
== other
.dedicated_db
&&
202 dedicated_wal
== other
.dedicated_wal
;
205 void encode(ceph::buffer::list
& bl
) const;
206 void decode(ceph::buffer::list::const_iterator
& p
);
207 void dump(ceph::Formatter
*f
) const;
209 WRITE_CLASS_ENCODER(bluefs_layout_t
)
211 struct bluefs_super_t
{
212 uuid_d uuid
; ///< unique to this bluefs instance
213 uuid_d osd_uuid
; ///< matches the osd that owns us
217 bluefs_fnode_t log_fnode
;
219 std::optional
<bluefs_layout_t
> memorized_layout
;
225 uint64_t block_mask() const {
226 return ~((uint64_t)block_size
- 1);
229 void encode(ceph::buffer::list
& bl
) const;
230 void decode(ceph::buffer::list::const_iterator
& p
);
231 void dump(ceph::Formatter
*f
) const;
232 static void generate_test_instances(std::list
<bluefs_super_t
*>& ls
);
234 WRITE_CLASS_ENCODER(bluefs_super_t
)
236 std::ostream
& operator<<(std::ostream
&, const bluefs_super_t
& s
);
239 struct bluefs_transaction_t
{
242 OP_INIT
, ///< initial (empty) file system marker
243 OP_ALLOC_ADD
, ///< OBSOLETE: add extent to available block storage (extent)
244 OP_ALLOC_RM
, ///< OBSOLETE: remove extent from available block storage (extent)
245 OP_DIR_LINK
, ///< (re)set a dir entry (dirname, filename, ino)
246 OP_DIR_UNLINK
, ///< remove a dir entry (dirname, filename)
247 OP_DIR_CREATE
, ///< create a dir (dirname)
248 OP_DIR_REMOVE
, ///< remove a dir (dirname)
249 OP_FILE_UPDATE
, ///< set/update file metadata (file)
250 OP_FILE_REMOVE
, ///< remove file (ino)
251 OP_JUMP
, ///< jump the seq # and offset
252 OP_JUMP_SEQ
, ///< jump the seq #
253 OP_FILE_UPDATE_INC
, ///< incremental update file metadata (file)
256 uuid_d uuid
; ///< fs uuid
257 uint64_t seq
; ///< sequence number
258 ceph::buffer::list op_bl
; ///< encoded transaction ops
260 bluefs_transaction_t() : seq(0) {}
263 *this = bluefs_transaction_t();
266 return op_bl
.length() == 0;
271 encode((__u8
)OP_INIT
, op_bl
);
273 void op_dir_create(std::string_view dir
) {
275 encode((__u8
)OP_DIR_CREATE
, op_bl
);
278 void op_dir_remove(std::string_view dir
) {
280 encode((__u8
)OP_DIR_REMOVE
, op_bl
);
283 void op_dir_link(std::string_view dir
, std::string_view file
, uint64_t ino
) {
285 encode((__u8
)OP_DIR_LINK
, op_bl
);
290 void op_dir_unlink(std::string_view dir
, std::string_view file
) {
292 encode((__u8
)OP_DIR_UNLINK
, op_bl
);
296 void op_file_update(bluefs_fnode_t
& file
) {
298 encode((__u8
)OP_FILE_UPDATE
, op_bl
);
302 /* streams update to bufferlist and clears update state */
303 void op_file_update_inc(bluefs_fnode_t
& file
) {
305 bluefs_fnode_delta_t delta
;
306 file
.make_delta(&delta
);
307 encode((__u8
)OP_FILE_UPDATE_INC
, op_bl
);
308 encode(delta
, op_bl
);
311 void op_file_remove(uint64_t ino
) {
313 encode((__u8
)OP_FILE_REMOVE
, op_bl
);
316 void op_jump(uint64_t next_seq
, uint64_t offset
) {
318 encode((__u8
)OP_JUMP
, op_bl
);
319 encode(next_seq
, op_bl
);
320 encode(offset
, op_bl
);
322 void op_jump_seq(uint64_t next_seq
) {
324 encode((__u8
)OP_JUMP_SEQ
, op_bl
);
325 encode(next_seq
, op_bl
);
327 void claim_ops(bluefs_transaction_t
& from
) {
328 op_bl
.claim_append(from
.op_bl
);
331 void encode(ceph::buffer::list
& bl
) const;
332 void decode(ceph::buffer::list::const_iterator
& p
);
333 void dump(ceph::Formatter
*f
) const;
334 static void generate_test_instances(std::list
<bluefs_transaction_t
*>& ls
);
336 WRITE_CLASS_ENCODER(bluefs_transaction_t
)
338 std::ostream
& operator<<(std::ostream
& out
, const bluefs_transaction_t
& t
);