]> git.proxmox.com Git - ceph.git/blame - ceph/src/crimson/os/seastore/onode_manager/staged-fltree/node_extent_manager/seastore.h
import quincy beta 17.1.0
[ceph.git] / ceph / src / crimson / os / seastore / onode_manager / staged-fltree / node_extent_manager / seastore.h
CommitLineData
f67539c2
TL
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
20effc67
TL
6#include <random>
7
8#include "crimson/os/seastore/logging.h"
9
f67539c2
TL
10#include "crimson/os/seastore/onode_manager/staged-fltree/node_extent_manager.h"
11#include "crimson/os/seastore/onode_manager/staged-fltree/node_delta_recorder.h"
12
13/**
14 * seastore.h
15 *
16 * Seastore backend implementations.
17 */
18
19namespace crimson::os::seastore::onode {
20
21class SeastoreSuper final: public Super {
22 public:
23 SeastoreSuper(Transaction& t, RootNodeTracker& tracker,
24 laddr_t root_addr, TransactionManager& tm)
25 : Super(t, tracker), root_addr{root_addr}, tm{tm} {}
26 ~SeastoreSuper() override = default;
27 protected:
28 laddr_t get_root_laddr() const override {
29 return root_addr;
30 }
20effc67
TL
31 void write_root_laddr(context_t c, laddr_t addr) override {
32 LOG_PREFIX(OTree::Seastore);
33 SUBDEBUGT(seastore_onode, "update root {:#x} ...", c.t, addr);
34 root_addr = addr;
35 tm.write_onode_root(c.t, addr);
f67539c2 36 }
20effc67 37 private:
f67539c2 38 laddr_t root_addr;
20effc67 39 TransactionManager &tm;
f67539c2
TL
40};
41
42class SeastoreNodeExtent final: public NodeExtent {
43 public:
44 SeastoreNodeExtent(ceph::bufferptr &&ptr)
45 : NodeExtent(std::move(ptr)) {}
46 SeastoreNodeExtent(const SeastoreNodeExtent& other)
47 : NodeExtent(other) {}
48 ~SeastoreNodeExtent() override = default;
20effc67
TL
49
50 constexpr static extent_types_t TYPE = extent_types_t::ONODE_BLOCK_STAGED;
51 extent_types_t get_type() const override {
52 return TYPE;
53 }
54
f67539c2
TL
55 protected:
56 NodeExtentRef mutate(context_t, DeltaRecorderURef&&) override;
57
58 DeltaRecorder* get_recorder() const override {
59 return recorder.get();
60 }
61
62 CachedExtentRef duplicate_for_write() override {
63 return CachedExtentRef(new SeastoreNodeExtent(*this));
64 }
f67539c2
TL
65 ceph::bufferlist get_delta() override {
66 assert(recorder);
67 return recorder->get_delta();
68 }
69 void apply_delta(const ceph::bufferlist&) override;
20effc67 70
f67539c2
TL
71 private:
72 DeltaRecorderURef recorder;
73};
74
20effc67
TL
75class TransactionManagerHandle : public NodeExtentManager {
76 public:
77 TransactionManagerHandle(TransactionManager &tm) : tm{tm} {}
78 TransactionManager &tm;
79};
80
81template <bool INJECT_EAGAIN=false>
82class SeastoreNodeExtentManager final: public TransactionManagerHandle {
f67539c2 83 public:
20effc67
TL
84 SeastoreNodeExtentManager(
85 TransactionManager &tm, laddr_t min, double p_eagain)
86 : TransactionManagerHandle(tm), addr_min{min}, p_eagain{p_eagain} {
87 if constexpr (INJECT_EAGAIN) {
88 assert(p_eagain > 0.0 && p_eagain < 1.0);
89 } else {
90 assert(p_eagain == 0.0);
91 }
92 }
93
f67539c2 94 ~SeastoreNodeExtentManager() override = default;
20effc67
TL
95
96 void set_generate_eagain(bool enable) {
97 generate_eagain = enable;
98 }
99
f67539c2
TL
100 protected:
101 bool is_read_isolated() const override { return true; }
102
20effc67
TL
103 read_iertr::future<NodeExtentRef> read_extent(
104 Transaction& t, laddr_t addr) override {
105 SUBTRACET(seastore_onode, "reading at {:#x} ...", t, addr);
106 if constexpr (INJECT_EAGAIN) {
107 if (trigger_eagain()) {
108 SUBDEBUGT(seastore_onode, "reading at {:#x}: trigger eagain", t, addr);
109 t.test_set_conflict();
110 return read_iertr::make_ready_future<NodeExtentRef>();
111 }
112 }
113 return tm.read_extent<SeastoreNodeExtent>(t, addr
114 ).si_then([addr, &t](auto&& e) -> read_iertr::future<NodeExtentRef> {
115 SUBTRACET(seastore_onode,
116 "read {}B at {:#x} -- {}",
117 t, e->get_length(), e->get_laddr(), *e);
f67539c2 118 assert(e->get_laddr() == addr);
f67539c2 119 std::ignore = addr;
20effc67 120 return read_iertr::make_ready_future<NodeExtentRef>(e);
f67539c2
TL
121 });
122 }
123
20effc67
TL
124 alloc_iertr::future<NodeExtentRef> alloc_extent(
125 Transaction& t, laddr_t hint, extent_len_t len) override {
126 SUBTRACET(seastore_onode, "allocating {}B with hint {:#x} ...", t, len, hint);
127 if constexpr (INJECT_EAGAIN) {
128 if (trigger_eagain()) {
129 SUBDEBUGT(seastore_onode, "allocating {}B: trigger eagain", t, len);
130 t.test_set_conflict();
131 return alloc_iertr::make_ready_future<NodeExtentRef>();
132 }
133 }
134 return tm.alloc_extent<SeastoreNodeExtent>(t, hint, len
135 ).si_then([len, &t](auto extent) {
136 SUBDEBUGT(seastore_onode,
137 "allocated {}B at {:#x} -- {}",
138 t, extent->get_length(), extent->get_laddr(), *extent);
139 if (!extent->is_initial_pending()) {
140 SUBERRORT(seastore_onode,
141 "allocated {}B but got invalid extent: {}",
142 t, len, *extent);
143 ceph_abort("fatal error");
144 }
f67539c2
TL
145 assert(extent->get_length() == len);
146 std::ignore = len;
147 return NodeExtentRef(extent);
148 });
149 }
150
20effc67
TL
151 retire_iertr::future<> retire_extent(
152 Transaction& t, NodeExtentRef _extent) override {
153 LogicalCachedExtentRef extent = _extent;
154 auto addr = extent->get_laddr();
155 auto len = extent->get_length();
156 SUBDEBUGT(seastore_onode,
157 "retiring {}B at {:#x} -- {} ...",
158 t, len, addr, *extent);
159 if constexpr (INJECT_EAGAIN) {
160 if (trigger_eagain()) {
161 SUBDEBUGT(seastore_onode,
162 "retiring {}B at {:#x} -- {} : trigger eagain",
163 t, len, addr, *extent);
164 t.test_set_conflict();
165 return retire_iertr::now();
166 }
167 }
168 return tm.dec_ref(t, extent).si_then([addr, len, &t] (unsigned cnt) {
169 assert(cnt == 0);
170 SUBTRACET(seastore_onode, "retired {}B at {:#x} ...", t, len, addr);
171 });
172 }
173
174 getsuper_iertr::future<Super::URef> get_super(
f67539c2 175 Transaction& t, RootNodeTracker& tracker) override {
20effc67
TL
176 SUBTRACET(seastore_onode, "get root ...", t);
177 if constexpr (INJECT_EAGAIN) {
178 if (trigger_eagain()) {
179 SUBDEBUGT(seastore_onode, "get root: trigger eagain", t);
180 t.test_set_conflict();
181 return getsuper_iertr::make_ready_future<Super::URef>();
182 }
183 }
184 return tm.read_onode_root(t).si_then([this, &t, &tracker](auto root_addr) {
185 SUBTRACET(seastore_onode, "got root {:#x}", t, root_addr);
f67539c2
TL
186 return Super::URef(new SeastoreSuper(t, tracker, root_addr, tm));
187 });
188 }
189
190 std::ostream& print(std::ostream& os) const override {
20effc67
TL
191 os << "SeastoreNodeExtentManager";
192 if constexpr (INJECT_EAGAIN) {
193 os << "(p_eagain=" << p_eagain << ")";
194 }
195 return os;
f67539c2
TL
196 }
197
198 private:
20effc67
TL
199 static LOG_PREFIX(OTree::Seastore);
200
f67539c2 201 const laddr_t addr_min;
20effc67
TL
202
203 // XXX: conditional members by INJECT_EAGAIN
204 bool trigger_eagain() {
205 if (generate_eagain) {
206 double dice = rd();
207 assert(rd.min() == 0);
208 dice /= rd.max();
209 return dice <= p_eagain;
210 } else {
211 return false;
212 }
213 }
214 bool generate_eagain = true;
215 std::random_device rd;
216 double p_eagain;
f67539c2
TL
217};
218
219}