]> git.proxmox.com Git - ceph.git/blob - ceph/src/crimson/os/seastore/random_block_manager.h
update ceph source to reef 18.2.1
[ceph.git] / ceph / src / crimson / os / seastore / random_block_manager.h
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 <iosfwd>
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 "crimson/os/seastore/seastore_types.h"
14 #include "include/buffer_fwd.h"
15 #include "crimson/osd/exceptions.h"
16
17 #include "crimson/os/seastore/transaction.h"
18
19 #include "crimson/common/layout.h"
20 #include "include/buffer.h"
21 #include "crimson/os/seastore/device.h"
22
23 namespace crimson::os::seastore {
24
25 struct rbm_shard_info_t {
26 std::size_t size = 0;
27 uint64_t start_offset = 0;
28
29 DENC(rbm_shard_info_t, v, p) {
30 DENC_START(1, 1, p);
31 denc(v.size, p);
32 denc(v.start_offset, p);
33 DENC_FINISH(p);
34 }
35 };
36
37 struct rbm_metadata_header_t {
38 size_t size = 0;
39 size_t block_size = 0;
40 uint64_t feature = 0;
41 uint64_t journal_size = 0;
42 checksum_t crc = 0;
43 device_config_t config;
44 unsigned int shard_num = 0;
45 std::vector<rbm_shard_info_t> shard_infos;
46
47 DENC(rbm_metadata_header_t, v, p) {
48 DENC_START(1, 1, p);
49 denc(v.size, p);
50 denc(v.block_size, p);
51 denc(v.feature, p);
52
53 denc(v.journal_size, p);
54 denc(v.crc, p);
55 denc(v.config, p);
56 denc(v.shard_num, p);
57 denc(v.shard_infos, p);
58 DENC_FINISH(p);
59 }
60
61 void validate() const {
62 ceph_assert(shard_num == seastar::smp::count);
63 ceph_assert(block_size > 0);
64 for (unsigned int i = 0; i < seastar::smp::count; i ++) {
65 ceph_assert(shard_infos[i].size > block_size &&
66 shard_infos[i].size % block_size == 0);
67 ceph_assert_always(shard_infos[i].size <= DEVICE_OFF_MAX);
68 ceph_assert(journal_size > 0 &&
69 journal_size % block_size == 0);
70 ceph_assert(shard_infos[i].start_offset < size &&
71 shard_infos[i].start_offset % block_size == 0);
72 }
73 ceph_assert(config.spec.magic != 0);
74 ceph_assert(get_default_backend_of_device(config.spec.dtype) ==
75 backend_type_t::RANDOM_BLOCK);
76 ceph_assert(config.spec.id <= DEVICE_ID_MAX_VALID);
77 }
78 };
79
80 enum class rbm_extent_state_t {
81 FREE, // not allocated
82 RESERVED, // extent is reserved by alloc_new_extent, but is not persistent
83 ALLOCATED, // extent is persistent
84 };
85
86 class Device;
87 using rbm_abs_addr = uint64_t;
88 constexpr rbm_abs_addr RBM_START_ADDRESS = 0;
89 class RandomBlockManager {
90 public:
91
92 using read_ertr = crimson::errorator<
93 crimson::ct_error::input_output_error,
94 crimson::ct_error::invarg,
95 crimson::ct_error::enoent,
96 crimson::ct_error::erange>;
97 virtual read_ertr::future<> read(paddr_t addr, bufferptr &buffer) = 0;
98
99 using write_ertr = crimson::errorator<
100 crimson::ct_error::input_output_error,
101 crimson::ct_error::invarg,
102 crimson::ct_error::ebadf,
103 crimson::ct_error::enospc,
104 crimson::ct_error::erange
105 >;
106 virtual write_ertr::future<> write(paddr_t addr, bufferptr &buf) = 0;
107
108 using open_ertr = crimson::errorator<
109 crimson::ct_error::input_output_error,
110 crimson::ct_error::invarg,
111 crimson::ct_error::enoent>;
112 virtual open_ertr::future<> open() = 0;
113
114 using close_ertr = crimson::errorator<
115 crimson::ct_error::input_output_error,
116 crimson::ct_error::invarg>;
117 virtual close_ertr::future<> close() = 0;
118
119 using allocate_ertr = crimson::errorator<
120 crimson::ct_error::input_output_error,
121 crimson::ct_error::invarg,
122 crimson::ct_error::enospc
123 >;
124 using allocate_ret = allocate_ertr::future<paddr_t>;
125 // allocator, return start addr of allocated blocks
126 virtual paddr_t alloc_extent(size_t size) = 0;
127
128 virtual void mark_space_used(paddr_t paddr, size_t len) = 0;
129 virtual void mark_space_free(paddr_t paddr, size_t len) = 0;
130
131 virtual void complete_allocation(paddr_t addr, size_t size) = 0;
132
133 virtual size_t get_size() const = 0;
134 virtual extent_len_t get_block_size() const = 0;
135 virtual uint64_t get_free_blocks() const = 0;
136 virtual device_id_t get_device_id() const = 0;
137 virtual const seastore_meta_t &get_meta() const = 0;
138 virtual Device* get_device() = 0;
139 virtual paddr_t get_start() = 0;
140 virtual rbm_extent_state_t get_extent_state(paddr_t addr, size_t size) = 0;
141 virtual size_t get_journal_size() const = 0;
142 virtual ~RandomBlockManager() {}
143 };
144 using RandomBlockManagerRef = std::unique_ptr<RandomBlockManager>;
145
146 inline rbm_abs_addr convert_paddr_to_abs_addr(const paddr_t& paddr) {
147 const blk_paddr_t& blk_addr = paddr.as_blk_paddr();
148 return blk_addr.get_device_off();
149 }
150
151 inline paddr_t convert_abs_addr_to_paddr(rbm_abs_addr addr, device_id_t d_id) {
152 return paddr_t::make_blk_paddr(d_id, addr);
153 }
154
155 namespace random_block_device {
156 class RBMDevice;
157 }
158
159 seastar::future<std::unique_ptr<random_block_device::RBMDevice>>
160 get_rb_device(const std::string &device);
161
162 std::ostream &operator<<(std::ostream &out, const rbm_metadata_header_t &header);
163 std::ostream &operator<<(std::ostream &out, const rbm_shard_info_t &shard);
164 }
165
166 WRITE_CLASS_DENC_BOUNDED(
167 crimson::os::seastore::rbm_shard_info_t
168 )
169 WRITE_CLASS_DENC_BOUNDED(
170 crimson::os::seastore::rbm_metadata_header_t
171 )
172
173 #if FMT_VERSION >= 90000
174 template<> struct fmt::formatter<crimson::os::seastore::rbm_metadata_header_t> : fmt::ostream_formatter {};
175 template<> struct fmt::formatter<crimson::os::seastore::rbm_shard_info_t> : fmt::ostream_formatter {};
176 #endif