can_serve_replica_read uses PGLog::has_write_since, when checking for
writes we actually check if any pglog entry belongs to the head object.
The only two pglog entries that are of a clone object are:
1) At creation (pg_log_entry_t::CLONE)
2) At trimming (See remove_or_update)
In both cases, the there would be another pg log entry of the head.
---
Add assertion in prepare_head_update to assert that the above is true.
The obc passed to prepare_head_update (by OpsExecuter) could also be
a clone object (after being resolved). However, write operations should
only occur to head - so let's verify that.
Signed-off-by: Matan Breizman <mbreizma@redhat.com>
{
LOG_PREFIX(OpsExecuter::prepare_head_update);
assert(obc->obs.oi.soid.snap >= CEPH_MAXSNAP);
+ assert(obc->obs.oi.soid.is_head());
update_clone_overlap();
if (cloning_ctx) {
co_await reply_op_error(pgref, -EAGAIN);
co_return;
} else if (!pg.get_peering_state().can_serve_replica_read(m->get_hobj())) {
+ // Note: can_serve_replica_read checks for writes on the head object
+ // as writes can only occur to head.
DEBUGDPP("{}.{}: unstable write on replica, bouncing to primary",
pg, *this, this_instance_id);
pg.get_perf_logger().inc(l_osd_replica_read_redirect_conflict);