From: Radoslaw Zarzynski Date: Thu, 27 Nov 2025 15:28:58 +0000 (+0000) Subject: crimson/osd: implement handling of RADOS' extended attirbutes in FastEC X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=5a48d44232da4dcda23309e779e3349e40df9e31;p=ceph-ci.git crimson/osd: implement handling of RADOS' extended attirbutes in FastEC Signed-off-by: Radoslaw Zarzynski --- diff --git a/src/crimson/osd/ec_backend.cc b/src/crimson/osd/ec_backend.cc index 0e1ff729005..4517df37f18 100644 --- a/src/crimson/osd/ec_backend.cc +++ b/src/crimson/osd/ec_backend.cc @@ -789,4 +789,13 @@ ECBackend::handle_rep_read_reply(ECSubReadReply& mop) return ll_read_ierrorator::now(); } +PGBackend::get_attr_ierrorator::future +ECBackend::getxattr( + const hobject_t& soid, + std::string&& key) const +{ + // ENOSUPP! ECBackend reads xattr solely from the ObjectContext::attr_cache + return crimson::ct_error::enodata::make(); +} + } // namespace crimson::osd diff --git a/src/crimson/osd/ec_backend.h b/src/crimson/osd/ec_backend.h index 7a60e276400..996c366c06c 100644 --- a/src/crimson/osd/ec_backend.h +++ b/src/crimson/osd/ec_backend.h @@ -51,6 +51,10 @@ public: ll_read_ierrorator::future<> handle_rep_read_reply(ECSubReadReply& mop); ll_read_ierrorator::future<> handle_rep_read_reply(Ref); + PGBackend::get_attr_ierrorator::future getxattr( + const hobject_t& soid, + std::string&& key) const final; + private: friend class ECRecoveryBackend; diff --git a/src/crimson/osd/object_context.h b/src/crimson/osd/object_context.h index 3714913a725..1845cb179b3 100644 --- a/src/crimson/osd/object_context.h +++ b/src/crimson/osd/object_context.h @@ -76,7 +76,8 @@ public: std::map> watchers; // attr cache. ECTransaction is the initial user - std::map> attr_cache; + using attr_cache_t = std::map>; + attr_cache_t attr_cache; CommonOBCPipeline obc_pipeline; diff --git a/src/crimson/osd/ops_executer.cc b/src/crimson/osd/ops_executer.cc index 3b6819278af..3a76a88ca31 100644 --- a/src/crimson/osd/ops_executer.cc +++ b/src/crimson/osd/ops_executer.cc @@ -472,6 +472,17 @@ auto OpsExecuter::do_const_op(Func&& f) { return std::forward(f)(pg->get_backend(), std::as_const(obc->obs)); } +template +auto OpsExecuter::do_read_attr_cache(Func&& f) { + ++num_read; + // TODO: pass backend as read-only + return std::invoke( + std::forward(f), + pg->get_backend(), + std::as_const(obc->attr_cache), + std::as_const(obc->obs)); +} + // Defined here because there is a circular dependency between OpsExecuter and PG template auto OpsExecuter::do_write_op(Func&& f, OpsExecuter::modified_by m) { @@ -617,12 +628,16 @@ OpsExecuter::do_execute_op(OSDOp& osd_op) return backend.cmp_ext(os, osd_op); }); case CEPH_OSD_OP_GETXATTR: - return do_read_op([this, &osd_op](auto& backend, const auto& os) { - return backend.getxattr(os, osd_op, delta_stats); + return do_read_attr_cache([this, &osd_op](auto& backend, + const auto& attr_cache, + const auto& os) { + return backend.getxattr(os, attr_cache, osd_op, delta_stats); }); case CEPH_OSD_OP_GETXATTRS: - return do_read_op([this, &osd_op](auto& backend, const auto& os) { - return backend.get_xattrs(os, osd_op, delta_stats); + return do_read_attr_cache([this, &osd_op](auto& backend, + const auto& attr_cache, + const auto& os) { + return backend.get_xattrs(os, attr_cache, osd_op, delta_stats); }); case CEPH_OSD_OP_CMPXATTR: return do_read_op([this, &osd_op](auto& backend, const auto& os) { diff --git a/src/crimson/osd/ops_executer.h b/src/crimson/osd/ops_executer.h index 00d9b1883da..f78b29cef0e 100644 --- a/src/crimson/osd/ops_executer.h +++ b/src/crimson/osd/ops_executer.h @@ -336,6 +336,9 @@ private: return do_const_op(std::forward(f)); } + template + auto do_read_attr_cache(Func&& f); + template auto do_snapset_op(Func&& f) { ++num_read; diff --git a/src/crimson/osd/pg_backend.cc b/src/crimson/osd/pg_backend.cc index 1162f95ccb3..0e5d36648af 100644 --- a/src/crimson/osd/pg_backend.cc +++ b/src/crimson/osd/pg_backend.cc @@ -1142,8 +1142,16 @@ PGBackend::get_attr_ierrorator::future<> PGBackend::getxattr( bp.copy(osd_op.op.xattr.name_len, aname); name = "_" + aname; } - logger().debug("getxattr on obj={} for attr={}", os.oi.soid, name); - return getxattr(os.oi.soid, std::move(name)).safe_then_interruptible( + auto get_attr_maybe_from_cache = + [&] () mutable -> get_attr_ierrorator::future { + if (auto cache_it = attr_cache.find(name); cache_it != std::end(attr_cache)) { + return get_attr_ierrorator::make_ready_future( + cache_it->second); + } + logger().debug("getxattr on obj={} for attr={}", os.oi.soid, name); + return getxattr(os.oi.soid, std::move(name)); + }; + return get_attr_maybe_from_cache().safe_then_interruptible( [&delta_stats, &osd_op] (ceph::bufferlist&& val) { osd_op.outdata = std::move(val); osd_op.op.xattr.value_len = osd_op.outdata.length(); @@ -1153,22 +1161,21 @@ PGBackend::get_attr_ierrorator::future<> PGBackend::getxattr( }); } -PGBackend::get_attr_ierrorator::future -PGBackend::getxattr( - const hobject_t& soid, - std::string&& key) const -{ - return seastar::do_with(key, [this, &soid](auto &key) { - return store->get_attr(coll, ghobject_t{soid}, key); - }); -} - PGBackend::get_attr_ierrorator::future<> PGBackend::get_xattrs( const ObjectState& os, + const ObjectContext::attr_cache_t& attr_cache, OSDOp& osd_op, object_stat_sum_t& delta_stats) const { - return store->get_attrs(coll, ghobject_t{os.oi.soid}).safe_then( + auto get_attrs_maybe_from_cache = + [&] () { + if (!std::empty(attr_cache)) { + return crimson::os::FuturizedStore::Shard::get_attrs_ertr::make_ready_future< + crimson::os::FuturizedStore::Shard::attrs_t>(attr_cache); + } + return store->get_attrs(coll, ghobject_t{os.oi.soid}); + }; + return get_attrs_maybe_from_cache().safe_then( [&delta_stats, &osd_op](auto&& attrs) { std::vector> user_xattrs; ceph::bufferlist bl; diff --git a/src/crimson/osd/pg_backend.h b/src/crimson/osd/pg_backend.h index ad7bf32492c..880b429b24b 100644 --- a/src/crimson/osd/pg_backend.h +++ b/src/crimson/osd/pg_backend.h @@ -279,13 +279,15 @@ public: get_attr_errorator>; get_attr_ierrorator::future<> getxattr( const ObjectState& os, + const ObjectContext::attr_cache_t& attr_cache, OSDOp& osd_op, object_stat_sum_t& delta_stats) const; - get_attr_ierrorator::future getxattr( + virtual get_attr_ierrorator::future getxattr( const hobject_t& soid, - std::string&& key) const; + std::string&& key) const = 0; get_attr_ierrorator::future<> get_xattrs( const ObjectState& os, + const ObjectContext::attr_cache_t& attr_cache, OSDOp& osd_op, object_stat_sum_t& delta_stats) const; using cmp_xattr_errorator = get_attr_errorator::extend< diff --git a/src/crimson/osd/replicated_backend.cc b/src/crimson/osd/replicated_backend.cc index e3d2414a5d6..4f31c70665d 100644 --- a/src/crimson/osd/replicated_backend.cc +++ b/src/crimson/osd/replicated_backend.cc @@ -361,4 +361,14 @@ void ReplicatedBackend::do_pct(const MOSDPGPCT &m) pg.peering_state.update_pct(m.pg_committed_to); } +PGBackend::get_attr_ierrorator::future +ReplicatedBackend::getxattr( + const hobject_t& soid, + std::string&& key) const +{ + return seastar::do_with(key, [this, &soid](auto &key) { + return store->get_attr(coll, ghobject_t{soid}, key); + }); +} + } diff --git a/src/crimson/osd/replicated_backend.h b/src/crimson/osd/replicated_backend.h index 7bf067ffc71..a726699ac00 100644 --- a/src/crimson/osd/replicated_backend.h +++ b/src/crimson/osd/replicated_backend.h @@ -34,6 +34,11 @@ public: void got_rep_op_reply(const MOSDRepOpReply& reply) final; seastar::future<> stop() final; void on_actingset_changed(bool same_primary) final; + + PGBackend::get_attr_ierrorator::future getxattr( + const hobject_t& soid, + std::string&& key) const final; + private: ll_read_ierrorator::future _read(const hobject_t& hoid,