From: Ronen Friedman Date: Thu, 11 Jun 2026 12:32:34 +0000 (+0000) Subject: crimson/osd: return ENOENT from EC getxattr for non-existent objects X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=e9bf02b72b047d2c8c9ec7ff611fdec96b7cc995;p=ceph.git crimson/osd: return ENOENT from EC getxattr for non-existent objects PGBackend::getxattr() for EC pools reads from the attr_cache and returns ENODATA when an attr is not found, without distinguishing between "object exists but attr not set" and "object doesn't exist". This causes cls methods like cls_refcount_get() to proceed as if the object exists, enter the EC RMW pipeline, and hang. Add an os.exists check in the EC path so non-existent objects return ENOENT, matching the behavior of the replicated path which goes to the object store and gets ENOENT directly. Fixes: https://tracker.ceph.com/issues/77335 Signed-off-by: Ronen Friedman --- diff --git a/src/crimson/osd/pg_backend.cc b/src/crimson/osd/pg_backend.cc index 6a2e57d0992..0c31e28f333 100644 --- a/src/crimson/osd/pg_backend.cc +++ b/src/crimson/osd/pg_backend.cc @@ -1170,6 +1170,10 @@ PGBackend::get_attr_ierrorator::future<> PGBackend::getxattr( logger().debug("getxattr on obj={} for attr={}", os.oi.soid, name); return crimson::ct_error::enodata::make(); }; + if (is_erasure() && !os.exists) { + logger().debug("getxattr: object {} does not exist (erasure)", os.oi.soid); + return crimson::ct_error::enoent::make(); + } return get_attr_maybe_from_cache().safe_then_interruptible( [&delta_stats, &osd_op] (ceph::bufferlist&& val) { osd_op.outdata = std::move(val);