From e9bf02b72b047d2c8c9ec7ff611fdec96b7cc995 Mon Sep 17 00:00:00 2001 From: Ronen Friedman Date: Thu, 11 Jun 2026 12:32:34 +0000 Subject: [PATCH] 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 --- src/crimson/osd/pg_backend.cc | 4 ++++ 1 file changed, 4 insertions(+) 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); -- 2.47.3