]> git.proxmox.com Git - ceph.git/blob - ceph/src/test/crimson/seastore/test_extmap_manager.cc
buildsys: switch source download to quincy
[ceph.git] / ceph / src / test / crimson / seastore / test_extmap_manager.cc
1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab
3
4 #include "test/crimson/gtest_seastar.h"
5 #include "test/crimson/seastore/transaction_manager_test_state.h"
6
7 #include "crimson/os/seastore/cache.h"
8 #include "crimson/os/seastore/transaction_manager.h"
9 #include "crimson/os/seastore/segment_manager.h"
10 #include "crimson/os/seastore/extentmap_manager.h"
11
12 #include "test/crimson/seastore/test_block.h"
13
14 using namespace crimson;
15 using namespace crimson::os;
16 using namespace crimson::os::seastore;
17
18 namespace {
19 [[maybe_unused]] seastar::logger& logger() {
20 return crimson::get_logger(ceph_subsys_test);
21 }
22 }
23
24
25 struct extentmap_manager_test_t :
26 public seastar_test_suite_t,
27 TMTestState {
28
29 ExtentMapManagerRef extmap_manager;
30
31 extentmap_manager_test_t() {}
32
33 seastar::future<> set_up_fut() final {
34 return tm_setup().then([this] {
35 extmap_manager = extentmap_manager::create_extentmap_manager(*tm);
36 return seastar::now();
37 });
38 }
39
40 seastar::future<> tear_down_fut() final {
41 return tm_teardown().then([this] {
42 extmap_manager.reset();
43 return seastar::now();
44 });
45 }
46
47 using test_extmap_t = std::map<uint32_t, lext_map_val_t>;
48 test_extmap_t test_ext_mappings;
49
50 extent_mapping_t insert_extent(
51 extmap_root_t &extmap_root,
52 Transaction &t,
53 uint32_t lo,
54 lext_map_val_t val) {
55 auto extent = extmap_manager->add_lextent(extmap_root, t, lo, val).unsafe_get0();
56 EXPECT_EQ(lo, extent.logical_offset);
57 EXPECT_EQ(val.laddr, extent.laddr);
58 EXPECT_EQ(val.length, extent.length);
59 test_ext_mappings.emplace(extent.logical_offset,
60 lext_map_val_t{extent.laddr, extent.length});
61 return extent;
62 }
63
64 extent_map_list_t find_extent(
65 extmap_root_t &extmap_root,
66 Transaction &t,
67 uint32_t lo,
68 uint32_t len) {
69 auto extent = extmap_manager->find_lextent(extmap_root, t, lo, len).unsafe_get0();
70 EXPECT_EQ(lo, extent.front().logical_offset);
71 EXPECT_EQ(len, extent.front().length);
72 return extent;
73 }
74
75 extent_map_list_t findno_extent(
76 extmap_root_t &extmap_root,
77 Transaction &t,
78 uint32_t lo,
79 uint32_t len) {
80 auto extent = extmap_manager->find_lextent(extmap_root, t, lo, len).unsafe_get0();
81 EXPECT_EQ(extent.empty(), true);
82 return extent;
83 }
84
85 void rm_extent(
86 extmap_root_t &extmap_root,
87 Transaction &t,
88 uint32_t lo,
89 lext_map_val_t val ) {
90 auto ret = extmap_manager->rm_lextent(extmap_root, t, lo, val).unsafe_get0();
91 EXPECT_TRUE(ret);
92 test_ext_mappings.erase(lo);
93 }
94
95 void check_mappings(extmap_root_t &extmap_root, Transaction &t) {
96 for (const auto& [lo, ext]: test_ext_mappings){
97 const auto ext_list = find_extent(extmap_root, t, lo, ext.length);
98 ASSERT_EQ(ext_list.size(), 1);
99 const auto& ext_map = ext_list.front();
100 EXPECT_EQ(ext.laddr, ext_map.laddr);
101 EXPECT_EQ(ext.length, ext_map.length);
102 }
103 }
104
105 void check_mappings(extmap_root_t &extmap_root) {
106 auto t = tm->create_transaction();
107 check_mappings(extmap_root, *t);
108 }
109
110 void replay() {
111 logger().debug("{}: begin", __func__);
112 restart();
113 extmap_manager = extentmap_manager::create_extentmap_manager(*tm);
114 logger().debug("{}: end", __func__);
115 }
116
117
118 };
119
120 TEST_F(extentmap_manager_test_t, basic)
121 {
122 run_async([this] {
123 extmap_root_t extmap_root(0, L_ADDR_NULL);
124 {
125 auto t = tm->create_transaction();
126 extmap_root = extmap_manager->initialize_extmap(*t).unsafe_get0();
127 tm->submit_transaction(std::move(t)).unsafe_get();
128 }
129
130 uint32_t len = 4096;
131 uint32_t lo = 0x1 * len;
132 {
133 auto t = tm->create_transaction();
134 logger().debug("first transaction");
135 [[maybe_unused]] auto addref = insert_extent(extmap_root, *t, lo, {lo, len});
136 [[maybe_unused]] auto seekref = find_extent(extmap_root, *t, lo, len);
137 tm->submit_transaction(std::move(t)).unsafe_get();
138 }
139 {
140 auto t = tm->create_transaction();
141 logger().debug("second transaction");
142 auto seekref = find_extent(extmap_root, *t, lo, len);
143 rm_extent(extmap_root, *t, lo, {seekref.front().laddr, len});
144 [[maybe_unused]] auto seekref2 = findno_extent(extmap_root, *t, lo, len);
145 tm->submit_transaction(std::move(t)).unsafe_get();
146 }
147 {
148 auto t = tm->create_transaction();
149 logger().debug("third transaction");
150 [[maybe_unused]] auto seekref = findno_extent(extmap_root, *t, lo, len);
151 tm->submit_transaction(std::move(t)).unsafe_get();
152 }
153 });
154 }
155
156 TEST_F(extentmap_manager_test_t, force_leafnode_split)
157 {
158 run_async([this] {
159 extmap_root_t extmap_root(0, L_ADDR_NULL);
160 {
161 auto t = tm->create_transaction();
162 extmap_root = extmap_manager->initialize_extmap(*t).unsafe_get0();
163 tm->submit_transaction(std::move(t)).unsafe_get();
164 }
165 uint32_t len = 4096;
166 uint32_t lo = 0;
167 for (unsigned i = 0; i < 40; i++) {
168 auto t = tm->create_transaction();
169 logger().debug("opened transaction");
170 for (unsigned j = 0; j < 10; ++j) {
171 [[maybe_unused]] auto addref = insert_extent(extmap_root, *t, lo, {lo, len});
172 lo += len;
173 if ((i % 20 == 0) && (j == 5)) {
174 check_mappings(extmap_root, *t);
175 }
176 }
177 logger().debug("force split submit transaction i = {}", i);
178 tm->submit_transaction(std::move(t)).unsafe_get();
179 check_mappings(extmap_root);
180 }
181 });
182
183 }
184
185 TEST_F(extentmap_manager_test_t, force_leafnode_split_merge)
186 {
187 run_async([this] {
188 extmap_root_t extmap_root(0, L_ADDR_NULL);
189 {
190 auto t = tm->create_transaction();
191 extmap_root = extmap_manager->initialize_extmap(*t).unsafe_get0();
192 tm->submit_transaction(std::move(t)).unsafe_get();
193 }
194 uint32_t len = 4096;
195 uint32_t lo = 0;
196 for (unsigned i = 0; i < 80; i++) {
197 auto t = tm->create_transaction();
198 logger().debug("opened split_merge transaction");
199 for (unsigned j = 0; j < 5; ++j) {
200 [[maybe_unused]] auto addref = insert_extent(extmap_root, *t, lo, {lo, len});
201 lo += len;
202 if ((i % 10 == 0) && (j == 3)) {
203 check_mappings(extmap_root, *t);
204 }
205 }
206 logger().debug("submitting transaction");
207 tm->submit_transaction(std::move(t)).unsafe_get();
208 if (i % 50 == 0) {
209 check_mappings(extmap_root);
210 }
211 }
212 auto t = tm->create_transaction();
213 int i = 0;
214 for (auto iter = test_ext_mappings.begin(); iter != test_ext_mappings.end();) {
215 auto [lo, ext] = *iter;
216 ++iter;
217 if (i % 3 != 0) {
218 rm_extent(extmap_root, *t, lo, ext);
219 }
220 i++;
221
222 if (i % 10 == 0) {
223 logger().debug("submitting transaction i= {}", i);
224 tm->submit_transaction(std::move(t)).unsafe_get();
225 t = tm->create_transaction();
226 }
227 if (i % 100 == 0) {
228 logger().debug("check_mappings i= {}", i);
229 check_mappings(extmap_root, *t);
230 check_mappings(extmap_root);
231 }
232 }
233 logger().debug("finally submitting transaction ");
234 tm->submit_transaction(std::move(t)).unsafe_get();
235 });
236 }
237
238 TEST_F(extentmap_manager_test_t, force_leafnode_split_merge_replay)
239 {
240 run_async([this] {
241 extmap_root_t extmap_root(0, L_ADDR_NULL);
242 {
243 auto t = tm->create_transaction();
244 extmap_root = extmap_manager->initialize_extmap(*t).unsafe_get0();
245 tm->submit_transaction(std::move(t)).unsafe_get();
246 replay();
247 }
248 uint32_t len = 4096;
249 uint32_t lo = 0;
250 for (unsigned i = 0; i < 50; i++) {
251 auto t = tm->create_transaction();
252 logger().debug("opened split_merge transaction");
253 for (unsigned j = 0; j < 5; ++j) {
254 [[maybe_unused]] auto addref = insert_extent(extmap_root, *t, lo, {lo, len});
255 lo += len;
256 }
257 logger().debug("submitting transaction");
258 tm->submit_transaction(std::move(t)).unsafe_get();
259 }
260 replay();
261 auto t = tm->create_transaction();
262 int i = 0;
263 for (auto iter = test_ext_mappings.begin(); iter != test_ext_mappings.end();) {
264 auto [lo, ext] = *iter;
265 ++iter;
266 rm_extent(extmap_root, *t, lo, ext);
267 i++;
268
269 if (i % 10 == 0) {
270 logger().debug("submitting transaction i= {}", i);
271 tm->submit_transaction(std::move(t)).unsafe_get();
272 t = tm->create_transaction();
273 }
274 if (i% 100 == 0){
275 check_mappings(extmap_root);
276 }
277 }
278 logger().debug("finally submitting transaction ");
279 tm->submit_transaction(std::move(t)).unsafe_get();
280 replay();
281 check_mappings(extmap_root);
282 });
283 }