@@ -319,22 +319,70 @@ ReplicatedRecoveryBackend::prep_push_to_replica(
319319
320320 auto & recovery_waiter = get_recovering (soid);
321321 auto & obc = recovery_waiter.obc ;
322- // TODO: use calc_clone_subsets
322+ SnapSet push_info_ss; // only populated if soid is_snap()
323323 crimson::osd::subsets_t subsets;
324-
324+ const auto & missing =
325+ pg.get_shard_missing ().find (pg_shard)->second ;
326+
327+ // are we doing a clone on the replica?
328+ if (soid.snap && soid.snap < CEPH_NOSNAP) {
329+ hobject_t head = soid;
330+ head.snap = CEPH_NOSNAP;
331+
332+ // try to base push off of clones that succeed/preceed poid
333+ // we need the head (and current SnapSet) locally to do that.
334+ if (pg.get_local_missing ().is_missing (head)) {
335+ logger ().debug (" {} missing head {}, pushing raw clone" ,
336+ __func__, head);
337+ if (obc->obs .oi .size ) {
338+ subsets.data_subset .insert (0 , obc->obs .oi .size );
339+ }
340+ return prep_push (soid,
341+ need,
342+ pg_shard,
343+ subsets,
344+ push_info_ss);
345+ }
346+ auto ssc = obc->ssc ;
347+ ceph_assert (ssc);
348+ push_info_ss = ssc->snapset ;
349+ logger ().debug (" push_to_replica snapset is {}" ,
350+ ssc->snapset );
351+
352+ subsets = crimson::osd::calc_clone_subsets (
353+ ssc->snapset , soid,
354+ missing,
355+ // get_peer_info() asserts `peer_info` existence.
356+ pg.get_peering_state ().get_peer_info (
357+ pg_shard).last_backfill );
358+ } else if (soid.snap == CEPH_NOSNAP) {
359+ // pushing head or unversioned object.
360+ // base this on partially on replica's clones?
361+ auto ssc = obc->ssc ;
362+ ceph_assert (ssc);
363+ logger ().debug (" push_to_replica snapset is {}" ,
364+ ssc->snapset );
365+ subsets = crimson::osd::calc_head_subsets (
366+ obc->obs .oi .size ,
367+ ssc->snapset , soid,
368+ missing,
369+ pg.get_peering_state ().get_peer_info (
370+ pg_shard).last_backfill );
371+ }
325372 return prep_push (soid,
326373 need,
327374 pg_shard,
328- subsets);
329-
375+ subsets,
376+ push_info_ss);
330377}
331378
332379RecoveryBackend::interruptible_future<PushOp>
333380ReplicatedRecoveryBackend::prep_push (
334381 const hobject_t & soid,
335382 eversion_t need,
336383 pg_shard_t pg_shard,
337- const crimson::osd::subsets_t & subsets)
384+ const crimson::osd::subsets_t & subsets,
385+ const SnapSet push_info_ss)
338386{
339387 logger ().debug (" {}: {}, {}" , __func__, soid, need);
340388 auto & recovery_waiter = get_recovering (soid);
@@ -350,6 +398,7 @@ ReplicatedRecoveryBackend::prep_push(
350398 push_info.recovery_info .size = obc->obs .oi .size ;
351399 push_info.recovery_info .copy_subset = subsets.data_subset ;
352400 push_info.recovery_info .clone_subset = subsets.clone_subsets ;
401+ push_info.recovery_info .ss = push_info_ss;
353402 push_info.recovery_info .soid = soid;
354403 push_info.recovery_info .oi = obc->obs .oi ;
355404 push_info.recovery_info .version = obc->obs .oi .version ;
0 commit comments