]> git.proxmox.com Git - ceph.git/blob - ceph/src/crimson/os/seastore/segment_manager/zns.h
add stop-gap to fix compat with CPUs not supporting SSE 4.1
[ceph.git] / ceph / src / crimson / os / seastore / segment_manager / zns.h
1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab
3 #pragma once
4
5 #include <linux/blkzoned.h>
6
7 #include <boost/intrusive_ptr.hpp>
8 #include <boost/smart_ptr/intrusive_ref_counter.hpp>
9
10 #include <seastar/core/file.hh>
11 #include <seastar/core/future.hh>
12 #include <seastar/core/reactor.hh>
13
14 #include "crimson/common/layout.h"
15
16 #include "crimson/os/seastore/segment_manager.h"
17
18 #include "include/uuid.h"
19
20 namespace crimson::os::seastore::segment_manager::zns {
21
22 struct zns_shard_info_t {
23 size_t size = 0;
24 size_t segments = 0;
25 size_t first_segment_offset = 0;
26
27 DENC(zns_shard_info_t, v, p) {
28 DENC_START(1, 1, p);
29 denc(v.size, p);
30 denc(v.segments, p);
31 denc(v.first_segment_offset, p);
32 DENC_FINISH(p);
33 }
34 };
35
36 struct zns_sm_metadata_t {
37 unsigned int shard_num = 0;
38 size_t segment_size = 0;
39 size_t segment_capacity = 0;
40 size_t zones_per_segment = 0;
41 size_t zone_capacity = 0;
42 size_t block_size = 0;
43 size_t zone_size = 0;
44
45 std::vector<zns_shard_info_t> shard_infos;
46
47 seastore_meta_t meta;
48
49 bool major_dev = false;
50 magic_t magic = 0;
51 device_type_t dtype = device_type_t::NONE;
52 device_id_t device_id = 0;
53 secondary_device_set_t secondary_devices;
54
55 DENC(zns_sm_metadata_t, v, p) {
56 DENC_START(1, 1, p);
57 denc(v.shard_num, p);
58 denc(v.segment_size, p);
59 denc(v.segment_capacity, p);
60 denc(v.zones_per_segment, p);
61 denc(v.zone_capacity, p);
62 denc(v.block_size, p);
63 denc(v.zone_size, p);
64 denc(v.shard_infos, p);
65 denc(v.meta, p);
66 denc(v.magic, p);
67 denc(v.dtype, p);
68 denc(v.device_id, p);
69 if (v.major_dev) {
70 denc(v.secondary_devices, p);
71 }
72 DENC_FINISH(p);
73 }
74
75 void validate() const {
76 ceph_assert_always(shard_num == seastar::smp::count);
77 for (unsigned int i = 0; i < seastar::smp::count; i++) {
78 ceph_assert_always(shard_infos[i].size > 0);
79 ceph_assert_always(shard_infos[i].size <= DEVICE_OFF_MAX);
80 ceph_assert_always(shard_infos[i].segments > 0);
81 ceph_assert_always(shard_infos[i].segments <= DEVICE_SEGMENT_ID_MAX);
82 }
83 ceph_assert_always(segment_capacity > 0);
84 ceph_assert_always(segment_capacity <= SEGMENT_OFF_MAX);
85 }
86 };
87
88 using write_ertr = crimson::errorator<crimson::ct_error::input_output_error>;
89 using read_ertr = crimson::errorator<crimson::ct_error::input_output_error>;
90
91 enum class zone_op {
92 OPEN,
93 FINISH,
94 CLOSE,
95 RESET,
96 };
97
98 class ZNSSegmentManager;
99
100 class ZNSSegment final : public Segment {
101 public:
102 ZNSSegment(ZNSSegmentManager &man, segment_id_t i) : manager(man), id(i){};
103
104 segment_id_t get_segment_id() const final { return id; }
105 segment_off_t get_write_capacity() const final;
106 segment_off_t get_write_ptr() const final { return write_pointer; }
107 close_ertr::future<> close() final;
108 write_ertr::future<> write(segment_off_t offset, ceph::bufferlist bl) final;
109 write_ertr::future<> advance_wp(segment_off_t offset) final;
110
111 ~ZNSSegment() {}
112 private:
113 friend class ZNSSegmentManager;
114 ZNSSegmentManager &manager;
115 const segment_id_t id;
116 segment_off_t write_pointer = 0;
117 write_ertr::future<> write_padding_bytes(size_t padding_bytes);
118 };
119
120 class ZNSSegmentManager final : public SegmentManager{
121 // interfaces used by Device
122 public:
123 seastar::future<> start() {
124 return shard_devices.start(device_path);
125 }
126
127 seastar::future<> stop() {
128 return shard_devices.stop();
129 }
130
131 Device& get_sharded_device() final {
132 return shard_devices.local();
133 }
134
135 mount_ret mount() final;
136 mkfs_ret mkfs(device_config_t meta) final;
137
138 ZNSSegmentManager(const std::string &path) : device_path(path) {}
139
140 ~ZNSSegmentManager() final = default;
141
142 //interfaces used by each shard device
143 public:
144 open_ertr::future<SegmentRef> open(segment_id_t id) final;
145 close_ertr::future<> close() final;
146
147 release_ertr::future<> release(segment_id_t id) final;
148
149 read_ertr::future<> read(
150 paddr_t addr,
151 size_t len,
152 ceph::bufferptr &out) final;
153
154 device_type_t get_device_type() const final {
155 return device_type_t::ZNS;
156 }
157
158 size_t get_available_size() const final {
159 return shard_info.size;
160 };
161
162 extent_len_t get_block_size() const final {
163 return metadata.block_size;
164 };
165
166 segment_off_t get_segment_size() const final {
167 return metadata.segment_capacity;
168 };
169
170 const seastore_meta_t &get_meta() const {
171 return metadata.meta;
172 };
173
174 device_id_t get_device_id() const final;
175
176 secondary_device_set_t& get_secondary_devices() final;
177
178 magic_t get_magic() const final;
179
180 Segment::write_ertr::future<> segment_write(
181 paddr_t addr,
182 ceph::bufferlist bl,
183 bool ignore_check=false);
184
185 private:
186 friend class ZNSSegment;
187 std::string device_path;
188 zns_shard_info_t shard_info;
189 zns_sm_metadata_t metadata;
190 seastar::file device;
191 uint32_t nr_zones;
192 struct effort_t {
193 uint64_t num = 0;
194 uint64_t bytes = 0;
195
196 void increment(uint64_t read_bytes) {
197 ++num;
198 bytes += read_bytes;
199 }
200 };
201
202 struct zns_sm_stats {
203 effort_t data_read = {};
204 effort_t data_write = {};
205 effort_t metadata_write = {};
206 uint64_t opened_segments = 0;
207 uint64_t closed_segments = 0;
208 uint64_t closed_segments_unused_bytes = 0;
209 uint64_t released_segments = 0;
210
211 void reset() {
212 *this = zns_sm_stats{};
213 }
214 } stats;
215
216 void register_metrics();
217 seastar::metrics::metric_group metrics;
218
219 Segment::close_ertr::future<> segment_close(
220 segment_id_t id, segment_off_t write_pointer);
221
222 uint64_t get_offset(paddr_t addr) {
223 auto& seg_addr = addr.as_seg_paddr();
224 return (shard_info.first_segment_offset +
225 (seg_addr.get_segment_id().device_segment_id() *
226 metadata.segment_size)) + seg_addr.get_segment_off();
227 }
228 private:
229 // shard 0 mkfs
230 mkfs_ret primary_mkfs(device_config_t meta);
231 // all shards mkfs
232 mkfs_ret shard_mkfs();
233
234 mount_ret shard_mount();
235
236 seastar::sharded<ZNSSegmentManager> shard_devices;
237 };
238
239 }
240
241 WRITE_CLASS_DENC_BOUNDED(
242 crimson::os::seastore::segment_manager::zns::zns_shard_info_t
243 )
244 WRITE_CLASS_DENC_BOUNDED(
245 crimson::os::seastore::segment_manager::zns::zns_sm_metadata_t
246 )