]> git.proxmox.com Git - ceph.git/blame - ceph/src/crimson/osd/object_context_loader.cc
update ceph source to reef 18.1.2
[ceph.git] / ceph / src / crimson / osd / object_context_loader.cc
CommitLineData
1e59de90
TL
1#include "crimson/osd/object_context_loader.h"
2#include "osd/osd_types_fmt.h"
3
4SET_SUBSYS(osd);
5
6namespace crimson::osd {
7
8using crimson::common::local_conf;
9
10 template<RWState::State State>
11 ObjectContextLoader::load_obc_iertr::future<>
12 ObjectContextLoader::with_head_obc(ObjectContextRef obc,
13 bool existed,
14 with_obc_func_t&& func)
15 {
16 LOG_PREFIX(ObjectContextLoader::with_head_obc);
17 DEBUGDPP("object {}", dpp, obc->get_oid());
18 assert(obc->is_head());
19 obc->append_to(obc_set_accessing);
20 return obc->with_lock<State, IOInterruptCondition>(
21 [existed=existed, obc=obc, func=std::move(func), this] {
22 return get_or_load_obc<State>(obc, existed)
23 .safe_then_interruptible(
24 [func = std::move(func)](auto obc) {
25 return std::move(func)(std::move(obc));
26 });
27 }).finally([FNAME, this, obc=std::move(obc)] {
28 DEBUGDPP("released object {}", dpp, obc->get_oid());
29 obc->remove_from(obc_set_accessing);
30 });
31 }
32
33 template<RWState::State State>
34 ObjectContextLoader::load_obc_iertr::future<>
35 ObjectContextLoader::with_clone_obc(hobject_t oid,
36 with_obc_func_t&& func)
37 {
38 LOG_PREFIX(ObjectContextLoader::with_clone_obc);
39 assert(!oid.is_head());
40 return with_obc<RWState::RWREAD>(
41 oid.get_head(),
42 [FNAME, oid, func=std::move(func), this](auto head) mutable
43 -> load_obc_iertr::future<> {
44 if (!head->obs.exists) {
45 ERRORDPP("head doesn't exist for object {}", dpp, head->obs.oi.soid);
46 return load_obc_iertr::future<>{
47 crimson::ct_error::enoent::make()
48 };
49 }
50 return this->with_clone_obc_only<State>(std::move(head),
51 oid,
52 std::move(func));
53 });
54 }
55
56 template<RWState::State State>
57 ObjectContextLoader::load_obc_iertr::future<>
58 ObjectContextLoader::with_clone_obc_only(ObjectContextRef head,
59 hobject_t oid,
60 with_obc_func_t&& func)
61 {
62 LOG_PREFIX(ObjectContextLoader::with_clone_obc_only);
63 auto coid = resolve_oid(head->get_head_ss(), oid);
64 if (!coid) {
65 ERRORDPP("clone {} not found", dpp, oid);
66 return load_obc_iertr::future<>{
67 crimson::ct_error::enoent::make()
68 };
69 }
70 auto [clone, existed] = obc_registry.get_cached_obc(*coid);
71 return clone->template with_lock<State, IOInterruptCondition>(
72 [existed=existed, clone=std::move(clone),
73 func=std::move(func), head=std::move(head), this]()
74 -> load_obc_iertr::future<> {
75 auto loaded = get_or_load_obc<State>(clone, existed);
76 return loaded.safe_then_interruptible(
77 [func = std::move(func)](auto clone) {
78 return std::move(func)(std::move(clone));
79 });
80 });
81 }
82
83 template<RWState::State State>
84 ObjectContextLoader::load_obc_iertr::future<>
85 ObjectContextLoader::with_head_and_clone_obc(
86 hobject_t oid,
87 with_both_obc_func_t&& func)
88 {
89 LOG_PREFIX(ObjectContextLoader::with_head_and_clone_obc);
90 assert(!oid.is_head());
91 return with_obc<RWState::RWREAD>(
92 oid.get_head(),
93 [FNAME, oid, func=std::move(func), this](auto head) mutable
94 -> load_obc_iertr::future<> {
95 if (!head->obs.exists) {
96 ERRORDPP("head doesn't exist for object {}", dpp, head->obs.oi.soid);
97 return load_obc_iertr::future<>{
98 crimson::ct_error::enoent::make()
99 };
100 }
101 auto coid = resolve_oid(head->get_head_ss(), oid);
102 if (!coid) {
103 ERRORDPP("clone {} not found", dpp, oid);
104 return load_obc_iertr::future<>{
105 crimson::ct_error::enoent::make()
106 };
107 }
108 auto [clone, existed] = obc_registry.get_cached_obc(*coid);
109 return clone->template with_lock<State, IOInterruptCondition>(
110 [existed=existed, clone=std::move(clone),
111 func=std::move(func), head=std::move(head), this]()
112 -> load_obc_iertr::future<> {
113 auto loaded = get_or_load_obc<State>(clone, existed);
114 return loaded.safe_then_interruptible(
115 [func = std::move(func), head=std::move(head)](auto clone) {
116 return std::move(func)(std::move(head), std::move(clone));
117 });
118 });
119 });
120 }
121
122 template<RWState::State State>
123 ObjectContextLoader::load_obc_iertr::future<>
124 ObjectContextLoader::with_obc(hobject_t oid,
125 with_obc_func_t&& func)
126 {
127 if (oid.is_head()) {
128 auto [obc, existed] =
129 obc_registry.get_cached_obc(std::move(oid));
130 return with_head_obc<State>(std::move(obc),
131 existed,
132 std::move(func));
133 } else {
134 return with_clone_obc<State>(oid, std::move(func));
135 }
136 }
137
138 ObjectContextLoader::load_obc_iertr::future<ObjectContextRef>
139 ObjectContextLoader::load_obc(ObjectContextRef obc)
140 {
141 LOG_PREFIX(ObjectContextLoader::load_obc);
142 return backend.load_metadata(obc->get_oid())
143 .safe_then_interruptible(
144 [FNAME, this, obc=std::move(obc)](auto md)
145 -> load_obc_ertr::future<ObjectContextRef> {
146 const hobject_t& oid = md->os.oi.soid;
147 DEBUGDPP("loaded obs {} for {}", dpp, md->os.oi, oid);
148 if (oid.is_head()) {
149 if (!md->ssc) {
150 ERRORDPP("oid {} missing snapsetcontext", dpp, oid);
151 return crimson::ct_error::object_corrupted::make();
152 }
153 obc->set_head_state(std::move(md->os),
154 std::move(md->ssc));
155 } else {
156 obc->set_clone_state(std::move(md->os));
157 }
158 DEBUGDPP("returning obc {} for {}", dpp, obc->obs.oi, obc->obs.oi.soid);
159 return load_obc_ertr::make_ready_future<ObjectContextRef>(obc);
160 });
161 }
162
163 template<RWState::State State>
164 ObjectContextLoader::load_obc_iertr::future<ObjectContextRef>
165 ObjectContextLoader::get_or_load_obc(ObjectContextRef obc,
166 bool existed)
167 {
168 LOG_PREFIX(ObjectContextLoader::get_or_load_obc);
169 auto loaded =
170 load_obc_iertr::make_ready_future<ObjectContextRef>(obc);
171 if (existed) {
172 DEBUGDPP("cache hit on {}", dpp, obc->get_oid());
173 } else {
174 DEBUGDPP("cache miss on {}", dpp, obc->get_oid());
175 loaded =
176 obc->template with_promoted_lock<State, IOInterruptCondition>(
177 [obc, this] {
178 return load_obc(obc);
179 });
180 }
181 return loaded;
182 }
183
184 ObjectContextLoader::load_obc_iertr::future<>
185 ObjectContextLoader::reload_obc(ObjectContext& obc) const
186 {
187 LOG_PREFIX(ObjectContextLoader::reload_obc);
188 assert(obc.is_head());
189 return backend.load_metadata(obc.get_oid())
190 .safe_then_interruptible<false>(
191 [FNAME, this, &obc](auto md)-> load_obc_ertr::future<> {
192 DEBUGDPP("reloaded obs {} for {}", dpp, md->os.oi, obc.get_oid());
193 if (!md->ssc) {
194 ERRORDPP("oid {} missing snapsetcontext", dpp, obc.get_oid());
195 return crimson::ct_error::object_corrupted::make();
196 }
197 obc.set_head_state(std::move(md->os), std::move(md->ssc));
198 return load_obc_ertr::now();
199 });
200 }
201
202 void ObjectContextLoader::notify_on_change(bool is_primary)
203 {
204 LOG_PREFIX(ObjectContextLoader::notify_on_change);
205 DEBUGDPP("is_primary: {}", dpp, is_primary);
206 for (auto& obc : obc_set_accessing) {
207 DEBUGDPP("interrupting obc: {}", dpp, obc.get_oid());
208 obc.interrupt(::crimson::common::actingset_changed(is_primary));
209 }
210 }
211
212 // explicitly instantiate the used instantiations
213 template ObjectContextLoader::load_obc_iertr::future<>
214 ObjectContextLoader::with_obc<RWState::RWNONE>(hobject_t,
215 with_obc_func_t&&);
216
217 template ObjectContextLoader::load_obc_iertr::future<>
218 ObjectContextLoader::with_obc<RWState::RWREAD>(hobject_t,
219 with_obc_func_t&&);
220
221 template ObjectContextLoader::load_obc_iertr::future<>
222 ObjectContextLoader::with_obc<RWState::RWWRITE>(hobject_t,
223 with_obc_func_t&&);
224
225 template ObjectContextLoader::load_obc_iertr::future<>
226 ObjectContextLoader::with_obc<RWState::RWEXCL>(hobject_t,
227 with_obc_func_t&&);
228
229 template ObjectContextLoader::load_obc_iertr::future<>
230 ObjectContextLoader::with_head_and_clone_obc<RWState::RWWRITE>(
231 hobject_t,
232 with_both_obc_func_t&&);
233}