]> git.proxmox.com Git - ceph.git/blob - ceph/src/crimson/tools/store_nbd/tm_driver.cc
update ceph source to reef 18.1.2
[ceph.git] / ceph / src / crimson / tools / store_nbd / tm_driver.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 "tm_driver.h"
5
6 using namespace crimson;
7 using namespace crimson::os;
8 using namespace crimson::os::seastore;
9
10 namespace {
11 seastar::logger& logger() {
12 return crimson::get_logger(ceph_subsys_test);
13 }
14 }
15
16 seastar::future<> TMDriver::write(
17 off_t offset,
18 bufferptr ptr)
19 {
20 logger().debug("Writing offset {}", offset);
21 assert(offset % device->get_block_size() == 0);
22 assert((ptr.length() % device->get_block_size()) == 0);
23 return seastar::do_with(ptr, [this, offset](auto& ptr) {
24 return repeat_eagain([this, offset, &ptr] {
25 return tm->with_transaction_intr(
26 Transaction::src_t::MUTATE,
27 "write",
28 [this, offset, &ptr](auto& t)
29 {
30 return tm->dec_ref(t, offset
31 ).si_then([](auto){}).handle_error_interruptible(
32 crimson::ct_error::enoent::handle([](auto) { return seastar::now(); }),
33 crimson::ct_error::pass_further_all{}
34 ).si_then([this, offset, &t, &ptr] {
35 logger().debug("dec_ref complete");
36 return tm->alloc_extent<TestBlock>(t, offset, ptr.length());
37 }).si_then([this, offset, &t, &ptr](auto ext) {
38 boost::ignore_unused(offset); // avoid clang warning;
39 assert(ext->get_laddr() == (size_t)offset);
40 assert(ext->get_bptr().length() == ptr.length());
41 ext->get_bptr().swap(ptr);
42 logger().debug("submitting transaction");
43 return tm->submit_transaction(t);
44 });
45 });
46 });
47 }).handle_error(
48 crimson::ct_error::assert_all{"store-nbd write"}
49 );
50 }
51
52 TMDriver::read_extents_ret TMDriver::read_extents(
53 Transaction &t,
54 laddr_t offset,
55 extent_len_t length)
56 {
57 return seastar::do_with(
58 lba_pin_list_t(),
59 lextent_list_t<TestBlock>(),
60 [this, &t, offset, length](auto &pins, auto &ret) {
61 return tm->get_pins(
62 t, offset, length
63 ).si_then([this, &t, &pins, &ret](auto _pins) {
64 _pins.swap(pins);
65 logger().debug("read_extents: mappings {}", pins);
66 return trans_intr::do_for_each(
67 pins.begin(),
68 pins.end(),
69 [this, &t, &ret](auto &&pin) {
70 logger().debug(
71 "read_extents: get_extent {}~{}",
72 pin->get_val(),
73 pin->get_length());
74 return tm->read_pin<TestBlock>(
75 t,
76 std::move(pin)
77 ).si_then([&ret](auto ref) mutable {
78 ret.push_back(std::make_pair(ref->get_laddr(), ref));
79 logger().debug(
80 "read_extents: got extent {}",
81 *ref);
82 return seastar::now();
83 });
84 }).si_then([&ret] {
85 return std::move(ret);
86 });
87 });
88 });
89 }
90
91 seastar::future<bufferlist> TMDriver::read(
92 off_t offset,
93 size_t size)
94 {
95 logger().debug("Reading offset {}", offset);
96 assert(offset % device->get_block_size() == 0);
97 assert(size % device->get_block_size() == 0);
98 auto blptrret = std::make_unique<bufferlist>();
99 auto &blret = *blptrret;
100 return repeat_eagain([=, &blret, this] {
101 return tm->with_transaction_intr(
102 Transaction::src_t::READ,
103 "read",
104 [=, &blret, this](auto& t)
105 {
106 return read_extents(t, offset, size
107 ).si_then([=, &blret](auto ext_list) {
108 size_t cur = offset;
109 for (auto &i: ext_list) {
110 if (cur != i.first) {
111 assert(cur < i.first);
112 blret.append_zero(i.first - cur);
113 cur = i.first;
114 }
115 blret.append(i.second->get_bptr());
116 cur += i.second->get_bptr().length();
117 }
118 if (blret.length() != size) {
119 assert(blret.length() < size);
120 blret.append_zero(size - blret.length());
121 }
122 });
123 });
124 }).handle_error(
125 crimson::ct_error::assert_all{"store-nbd read"}
126 ).then([blptrret=std::move(blptrret)]() mutable {
127 logger().debug("read complete");
128 return std::move(*blptrret);
129 });
130 }
131
132 void TMDriver::init()
133 {
134 std::vector<Device*> sec_devices;
135 #ifndef NDEBUG
136 tm = make_transaction_manager(device.get(), sec_devices, true);
137 #else
138 tm = make_transaction_manager(device.get(), sec_devices, false);
139 #endif
140 }
141
142 void TMDriver::clear()
143 {
144 tm.reset();
145 }
146
147 size_t TMDriver::get_size() const
148 {
149 return device->get_available_size() * .5;
150 }
151
152 seastar::future<> TMDriver::mkfs()
153 {
154 assert(config.path);
155 logger().debug("mkfs");
156 return Device::make_device(*config.path, device_type_t::SSD
157 ).then([this](DeviceRef dev) {
158 device = std::move(dev);
159 seastore_meta_t meta;
160 meta.seastore_id.generate_random();
161 return device->mkfs(
162 device_config_t{
163 true,
164 (magic_t)std::rand(),
165 device_type_t::SSD,
166 0,
167 meta,
168 secondary_device_set_t()});
169 }).safe_then([this] {
170 logger().debug("device mkfs done");
171 return device->mount();
172 }).safe_then([this] {
173 init();
174 logger().debug("tm mkfs");
175 return tm->mkfs();
176 }).safe_then([this] {
177 logger().debug("tm close");
178 return tm->close();
179 }).safe_then([this] {
180 logger().debug("sm close");
181 return device->close();
182 }).safe_then([this] {
183 clear();
184 device.reset();
185 logger().debug("mkfs complete");
186 return TransactionManager::mkfs_ertr::now();
187 }).handle_error(
188 crimson::ct_error::assert_all{
189 "Invalid errror during TMDriver::mkfs"
190 }
191 );
192 }
193
194 seastar::future<> TMDriver::mount()
195 {
196 return (config.mkfs ? mkfs() : seastar::now()
197 ).then([this] {
198 return Device::make_device(*config.path, device_type_t::SSD);
199 }).then([this](DeviceRef dev) {
200 device = std::move(dev);
201 return device->mount();
202 }).safe_then([this] {
203 init();
204 return tm->mount();
205 }).handle_error(
206 crimson::ct_error::assert_all{
207 "Invalid errror during TMDriver::mount"
208 }
209 );
210 };
211
212 seastar::future<> TMDriver::close()
213 {
214 return tm->close().safe_then([this] {
215 clear();
216 return device->close();
217 }).handle_error(
218 crimson::ct_error::assert_all{
219 "Invalid errror during TMDriver::close"
220 }
221 );
222 }