Skip to content

Commit 0cbe982

Browse files
committed
mson/osd/replicated_recovery_backend: Introduce prep_push_to_repli…
…ca() Intelligently push an object to a replica. make use of existing clones/heads and dup data ranges where possible. Signed-off-by: Matan Breizman <[email protected]>
1 parent 869fc82 commit 0cbe982

File tree

2 files changed

+56
-6
lines changed

2 files changed

+56
-6
lines changed

src/crimson/osd/replicated_recovery_backend.cc

Lines changed: 54 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -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

332379
RecoveryBackend::interruptible_future<PushOp>
333380
ReplicatedRecoveryBackend::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;

src/crimson/osd/replicated_recovery_backend.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,8 @@ class ReplicatedRecoveryBackend : public RecoveryBackend {
5757
const hobject_t& soid,
5858
eversion_t need,
5959
pg_shard_t pg_shard,
60-
const crimson::osd::subsets_t& subsets);
60+
const crimson::osd::subsets_t& subsets,
61+
const SnapSet push_info_ss);
6162
void prepare_pull(
6263
const crimson::osd::ObjectContextRef &head_obc,
6364
PullOp& pull_op,

0 commit comments

Comments
 (0)