]>
git.proxmox.com Git - ceph.git/blob - ceph/src/crimson/osd/object_context_loader.cc
0a4d74c0d70c7e51e9c4185975b4dd208313ced1
1 #include "crimson/osd/object_context_loader.h"
2 #include "osd/osd_types_fmt.h"
6 namespace crimson::osd
{
8 using crimson::common::local_conf
;
10 template<RWState::State State
>
11 ObjectContextLoader::load_obc_iertr::future
<>
12 ObjectContextLoader::with_head_obc(ObjectContextRef obc
,
14 with_obc_func_t
&& func
)
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
));
27 }).finally([FNAME
, this, obc
=std::move(obc
)] {
28 DEBUGDPP("released object {}", dpp
, obc
->get_oid());
29 obc
->remove_from(obc_set_accessing
);
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
)
38 LOG_PREFIX(ObjectContextLoader::with_clone_obc
);
39 assert(!oid
.is_head());
40 return with_obc
<RWState::RWREAD
>(
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()
50 return this->with_clone_obc_only
<State
>(std::move(head
),
56 template<RWState::State State
>
57 ObjectContextLoader::load_obc_iertr::future
<>
58 ObjectContextLoader::with_clone_obc_only(ObjectContextRef head
,
60 with_obc_func_t
&& func
)
62 LOG_PREFIX(ObjectContextLoader::with_clone_obc_only
);
63 auto coid
= resolve_oid(head
->get_head_ss(), oid
);
65 ERRORDPP("clone {} not found", dpp
, oid
);
66 return load_obc_iertr::future
<>{
67 crimson::ct_error::enoent::make()
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
));
83 template<RWState::State State
>
84 ObjectContextLoader::load_obc_iertr::future
<>
85 ObjectContextLoader::with_clone_obc_direct(
87 with_both_obc_func_t
&& func
)
89 LOG_PREFIX(ObjectContextLoader::with_clone_obc_direct
);
90 assert(!oid
.is_head());
91 return with_obc
<RWState::RWREAD
>(
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()
102 auto &ss
= head
->get_head_ss();
103 auto cit
= std::find(
104 std::begin(ss
.clones
), std::end(ss
.clones
), oid
.snap
);
105 assert(cit
!= std::end(ss
.clones
));
107 auto [clone
, existed
] = obc_registry
.get_cached_obc(oid
);
108 return clone
->template with_lock
<State
, IOInterruptCondition
>(
109 [existed
=existed
, clone
=std::move(clone
),
110 func
=std::move(func
), head
=std::move(head
), this]()
111 -> load_obc_iertr::future
<> {
112 auto loaded
= get_or_load_obc
<State
>(clone
, existed
);
113 return loaded
.safe_then_interruptible(
114 [func
= std::move(func
), head
=std::move(head
)](auto clone
) {
115 return std::move(func
)(std::move(head
), std::move(clone
));
121 template<RWState::State State
>
122 ObjectContextLoader::load_obc_iertr::future
<>
123 ObjectContextLoader::with_obc(hobject_t oid
,
124 with_obc_func_t
&& func
)
127 auto [obc
, existed
] =
128 obc_registry
.get_cached_obc(std::move(oid
));
129 return with_head_obc
<State
>(std::move(obc
),
133 return with_clone_obc
<State
>(oid
, std::move(func
));
137 ObjectContextLoader::load_obc_iertr::future
<ObjectContextRef
>
138 ObjectContextLoader::load_obc(ObjectContextRef obc
)
140 LOG_PREFIX(ObjectContextLoader::load_obc
);
141 return backend
.load_metadata(obc
->get_oid())
142 .safe_then_interruptible(
143 [FNAME
, this, obc
=std::move(obc
)](auto md
)
144 -> load_obc_ertr::future
<ObjectContextRef
> {
145 const hobject_t
& oid
= md
->os
.oi
.soid
;
146 DEBUGDPP("loaded obs {} for {}", dpp
, md
->os
.oi
, oid
);
149 ERRORDPP("oid {} missing snapsetcontext", dpp
, oid
);
150 return crimson::ct_error::object_corrupted::make();
152 obc
->set_head_state(std::move(md
->os
),
155 obc
->set_clone_state(std::move(md
->os
));
157 DEBUGDPP("returning obc {} for {}", dpp
, obc
->obs
.oi
, obc
->obs
.oi
.soid
);
158 return load_obc_ertr::make_ready_future
<ObjectContextRef
>(obc
);
162 template<RWState::State State
>
163 ObjectContextLoader::load_obc_iertr::future
<ObjectContextRef
>
164 ObjectContextLoader::get_or_load_obc(ObjectContextRef obc
,
167 LOG_PREFIX(ObjectContextLoader::get_or_load_obc
);
169 load_obc_iertr::make_ready_future
<ObjectContextRef
>(obc
);
171 DEBUGDPP("cache hit on {}", dpp
, obc
->get_oid());
173 DEBUGDPP("cache miss on {}", dpp
, obc
->get_oid());
175 obc
->template with_promoted_lock
<State
, IOInterruptCondition
>(
177 return load_obc(obc
);
183 ObjectContextLoader::load_obc_iertr::future
<>
184 ObjectContextLoader::reload_obc(ObjectContext
& obc
) const
186 LOG_PREFIX(ObjectContextLoader::reload_obc
);
187 assert(obc
.is_head());
188 return backend
.load_metadata(obc
.get_oid())
189 .safe_then_interruptible
<false>(
190 [FNAME
, this, &obc
](auto md
)-> load_obc_ertr::future
<> {
191 DEBUGDPP("reloaded obs {} for {}", dpp
, md
->os
.oi
, obc
.get_oid());
193 ERRORDPP("oid {} missing snapsetcontext", dpp
, obc
.get_oid());
194 return crimson::ct_error::object_corrupted::make();
196 obc
.set_head_state(std::move(md
->os
), std::move(md
->ssc
));
197 return load_obc_ertr::now();
201 void ObjectContextLoader::notify_on_change(bool is_primary
)
203 LOG_PREFIX(ObjectContextLoader::notify_on_change
);
204 DEBUGDPP("is_primary: {}", dpp
, is_primary
);
205 for (auto& obc
: obc_set_accessing
) {
206 DEBUGDPP("interrupting obc: {}", dpp
, obc
.get_oid());
207 obc
.interrupt(::crimson::common::actingset_changed(is_primary
));
211 // explicitly instantiate the used instantiations
212 template ObjectContextLoader::load_obc_iertr::future
<>
213 ObjectContextLoader::with_obc
<RWState::RWNONE
>(hobject_t
,
216 template ObjectContextLoader::load_obc_iertr::future
<>
217 ObjectContextLoader::with_obc
<RWState::RWREAD
>(hobject_t
,
220 template ObjectContextLoader::load_obc_iertr::future
<>
221 ObjectContextLoader::with_obc
<RWState::RWWRITE
>(hobject_t
,
224 template ObjectContextLoader::load_obc_iertr::future
<>
225 ObjectContextLoader::with_obc
<RWState::RWEXCL
>(hobject_t
,
228 template ObjectContextLoader::load_obc_iertr::future
<>
229 ObjectContextLoader::with_clone_obc_direct
<RWState::RWWRITE
>(
231 with_both_obc_func_t
&&);