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 <rfriedma@redhat.com>
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);