}
}
+template<RWState::State State>
+seastar::future<>
+PG::with_head_obc(hobject_t oid, with_obc_func_t&& func)
+{
+ assert(oid.is_head());
+ auto [obc, existed] = shard_services.obc_registry.get_cached_obc(oid);
+ return obc->with_lock<State>(
+ [oid=std::move(oid), existed=existed, obc=std::move(obc),
+ func=std::move(func), this] {
+ auto loaded = seastar::make_ready_future<ObjectContextRef>(obc);
+ if (existed) {
+ logger().debug("with_head_obc: found {} in cache", oid);
+ } else {
+ logger().debug("with_head_obc: cache miss on {}", oid);
+ loaded = obc->with_promoted_lock<RWState::RWEXCL>([this, obc] {
+ return load_head_obc(obc);
+ });
+ }
+ return loaded.then([func = std::move(func)](auto obc) {
+ return func(std::move(obc));
+ });
+ });
+}
+
+// explicitly instantiate the used instantiations
+template seastar::future<>
+PG::with_head_obc<RWState::RWREAD>(hobject_t, with_obc_func_t&&);
+
PG::load_obc_ertr::future<
std::pair<crimson::osd::ObjectContextRef, bool>>
PG::get_or_load_head_obc(hobject_t oid)
public:
using with_obc_func_t = std::function<seastar::future<> (ObjectContextRef)>;
+
+ template<RWState::State State>
+ seastar::future<> with_head_obc(hobject_t oid, with_obc_func_t&& func);
+
load_obc_ertr::future<> with_locked_obc(
Ref<MOSDOp> &m,
const OpInfo &op_info,
if (recovery_waiter.obc) {
return seastar::now();
}
- return pg.get_or_load_head_obc(soid).safe_then(
- [&recovery_waiter](auto p) {
- auto& [obc, existed] = p;
+ return pg.with_head_obc<RWState::RWREAD>(soid, [&recovery_waiter](auto obc) {
logger().debug("load_obc_for_recovery: loaded obc: {}", obc->obs.oi.soid);
recovery_waiter.obc = obc;
- if (!existed) {
- // obc is loaded with excl lock
- recovery_waiter.obc->put_lock_type(RWState::RWEXCL);
- }
return recovery_waiter.obc->wait_recovery_read();
- }, crimson::osd::PG::load_obc_ertr::all_same_way(
- [this, &recovery_waiter, soid](const std::error_code& e) {
- logger().error("load_obc_for_recovery: load failure of obc: {}", soid);
- return seastar::make_exception_future<>(e);
- })
- );
+ });
}
seastar::future<> ReplicatedRecoveryBackend::push_delete(