object has been pushed.
In crimson, the increase of BackfillState::last_backfill_started may happen
after a client request's "recover_missing" phase, but the actual object push
may be blocked by the client requests' later handling, in which case we must
check whether the object is pushed to the backfill target precisely when
determining whether to send the client request to the backfill target.
Fixes: https://tracker.ceph.com/issues/68661
Signed-off-by: Xuehan Xu <xuxuehan@qianxin.com>
return true;
bool should_send =
(hoid.pool != (int64_t)get_info().pgid.pool() ||
- (has_backfill_state() && hoid <= get_last_backfill_started()) ||
- hoid <= peering_state.get_peer_info(peer).last_backfill);
+ // An object has been fully pushed to the backfill target if and only if
+ // either of the following conditions is met:
+ // 1. peer_info.last_backfill has passed "hoid"
+ // 2. last_backfill_started has passed "hoid" and "hoid" is not in the peer
+ // missing set
+ hoid <= peering_state.get_peer_info(peer).last_backfill ||
+ (has_backfill_state() && hoid <= get_last_backfill_started() &&
+ !peering_state.get_peer_missing(peer).is_missing(hoid)));
if (!should_send) {
ceph_assert(is_backfill_target(peer));
logger().debug("{} issue_repop shipping empty opt to osd."