void PeeringState::apply_pwlc(const std::pair<eversion_t, eversion_t> pwlc,
const pg_shard_t &shard,
pg_info_t &info,
+ peering_stage stage,
pg_log_t *log1,
PGLog *log2)
{
// knowledge of partial_writes
const auto & [fromversion, toversion] = pwlc;
if (toversion > info.last_update) {
- if (fromversion <= info.last_update) {
+ if ((fromversion <= info.last_update) &&
+ ((stage == AFTER_ACTIVATE) ||
+ (info.last_complete == info.last_update))) {
if (info.last_complete == info.last_update) {
psdout(10) << "osd." << shard << " has last_complete"
<< "=last_update " << info.last_update
}
void PeeringState::update_peer_info(const pg_shard_t &from,
- const pg_info_t &oinfo)
+ const pg_info_t &oinfo,
+ peering_stage stage)
{
// Merge pwlc information from another shard into
// info.partial_writes_last_complete keeping the newest
if (is_primary()) {
for (auto & [shard, peer] : peer_info) {
if (info.partial_writes_last_complete.contains(shard.shard)) {
- apply_pwlc(info.partial_writes_last_complete[shard.shard], shard, peer);
+ apply_pwlc(info.partial_writes_last_complete[shard.shard], shard, peer,
+ stage);
}
}
}
// Non-primary shards might need to apply pwlc to update info
if (info.partial_writes_last_complete.contains(pg_whoami.shard)) {
apply_pwlc(info.partial_writes_last_complete[pg_whoami.shard], pg_whoami,
- info, &pg_log);
+ info, stage, &pg_log);
}
}
peer_info[from] = oinfo;
stats_last_update[from] = oinfo.last_update;
- update_peer_info(from, oinfo);
+ update_peer_info(from, oinfo, BEFORE_ACTIVATE);
might_have_unfound.insert(from);
update_history(oinfo.history);
PeeringCtxWrapper &ctx)
{
uint64_t num_unfound_before = missing_loc.num_unfound();
+ pg_info_t tinfo(oinfo);
+ tinfo.pgid.shard = pg_whoami.shard;
+ // add partial write from our info
+ tinfo.partial_writes_last_complete = info.partial_writes_last_complete;
+ tinfo.partial_writes_last_complete_epoch = info.partial_writes_last_complete_epoch;
+ if (info.partial_writes_last_complete.contains(from.shard)) {
+ apply_pwlc(info.partial_writes_last_complete[from.shard], from, tinfo, AFTER_ACTIVATE);
+ }
bool found_missing = missing_loc.add_source_info(
- from, oinfo, omissing, ctx.handle);
+ from, tinfo, omissing, ctx.handle);
if (found_missing && num_unfound_before != missing_loc.num_unfound())
pl->publish_stats_to_osd();
// avoid doing this if the peer is empty. This is abit of paranoia
// last_update=0'0 that's impossible.)
if (found_missing &&
oinfo.last_update != eversion_t()) {
- pg_info_t tinfo(oinfo);
- tinfo.pgid.shard = pg_whoami.shard;
- // add partial write from our info
- tinfo.partial_writes_last_complete = info.partial_writes_last_complete;
- tinfo.partial_writes_last_complete_epoch = info.partial_writes_last_complete_epoch;
- if (info.partial_writes_last_complete.contains(from.shard)) {
- apply_pwlc(info.partial_writes_last_complete[from.shard], from, tinfo);
- }
if (!tinfo.partial_writes_last_complete.empty()) {
psdout(20) << "sending info to " << from
<< " pwlc=e" << tinfo.partial_writes_last_complete_epoch
ceph_assert(pi_it != peer_info.end());
auto pm_it = peer_missing.find(*i);
ceph_assert(pm_it != peer_missing.end());
+ if (info.partial_writes_last_complete.contains(i->shard)) {
+ apply_pwlc(info.partial_writes_last_complete[i->shard], *i,
+ pi_it->second, AFTER_ACTIVATE);
+ }
missing_loc.add_source_info(
*i,
pi_it->second,
if (info.partial_writes_last_complete.contains(from.shard)) {
apply_pwlc(info.partial_writes_last_complete[from.shard], from, oinfo,
- &olog);
+ BEFORE_ACTIVATE, &olog);
}
bool invalidate_stats = false;
if (info.partial_writes_last_complete.contains(from.shard)) {
apply_pwlc(info.partial_writes_last_complete[from.shard], from, oinfo,
- &olog);
+ BEFORE_ACTIVATE, &olog);
}
pg_log.proc_replica_log(oinfo, olog, omissing, from, pool.info.allows_ecoptimizations());
peer_info[from] = oinfo;
- update_peer_info(from, oinfo);
+ update_peer_info(from, oinfo, BEFORE_ACTIVATE);
psdout(10) << " peer osd." << from << " now "
<< oinfo << " " << omissing << dendl;
might_have_unfound.insert(from);
ObjectStore::Transaction &t = context<PeeringMachine>().get_cur_transaction();
if (msg->info.partial_writes_last_complete.contains(ps->pg_whoami.shard)) {
ps->apply_pwlc(msg->info.partial_writes_last_complete[ps->pg_whoami.shard],
- ps->pg_whoami, ps->info, &ps->pg_log);
+ ps->pg_whoami, ps->info, AFTER_ACTIVATE, &ps->pg_log);
}
ps->merge_log(t, logevt.msg->info, std::move(logevt.msg->log), logevt.from);
- ps->update_peer_info(logevt.from, logevt.msg->info);
+ ps->update_peer_info(logevt.from, logevt.msg->info, AFTER_ACTIVATE);
ceph_assert(ps->pg_log.get_head() == ps->info.last_update);
if (logevt.msg->lease) {
ps->proc_lease(*logevt.msg->lease);
} else {
if (msg->info.partial_writes_last_complete.contains(ps->pg_whoami.shard)) {
ps->apply_pwlc(msg->info.partial_writes_last_complete[ps->pg_whoami.shard],
- ps->pg_whoami, ps->info, &ps->pg_log);
+ ps->pg_whoami, ps->info, AFTER_ACTIVATE, &ps->pg_log);
}
ps->merge_log(t, msg->info, std::move(msg->log), logevt.from);
- ps->update_peer_info(logevt.from, msg->info);
+ ps->update_peer_info(logevt.from, msg->info, AFTER_ACTIVATE);
}
if (logevt.msg->lease) {
ps->proc_lease(*logevt.msg->lease);
// Log must be consistent with info
ceph_assert(ps->pg_log.get_head() == ps->info.last_update);
// Update pwlc
- ps->update_peer_info(infoevt.from, infoevt.info);
+ ps->update_peer_info(infoevt.from, infoevt.info, AFTER_ACTIVATE);
post_event(Activate(infoevt.info.last_epoch_started));
return transit<ReplicaActive>();
}
psdout(10) << "Noting missing from osd." << logevt.from << dendl;
ps->peer_missing[logevt.from].claim(std::move(logevt.msg->missing));
ps->peer_info[logevt.from] = logevt.msg->info;
- ps->update_peer_info(logevt.from, logevt.msg->info);
+ ps->update_peer_info(logevt.from, logevt.msg->info, BEFORE_ACTIVATE);
return discard_event();
}
void update_heartbeat_peers();
void query_unfound(Formatter *f, std::string state);
+
+ enum peering_stage {
+ BEFORE_ACTIVATE,
+ AFTER_ACTIVATE
+ };
+
void apply_pwlc(const std::pair<eversion_t, eversion_t> pwlc,
const pg_shard_t &shard,
pg_info_t &info,
+ peering_stage stage,
pg_log_t *log1,
PGLog *log2);
void apply_pwlc(const std::pair<eversion_t, eversion_t> pwlc,
const pg_shard_t &shard,
pg_info_t &info,
+ peering_stage stage,
pg_log_t *log)
{
- apply_pwlc(pwlc, shard, info, log, nullptr);
+ apply_pwlc(pwlc, shard, info, stage, log, nullptr);
}
void apply_pwlc(const std::pair<eversion_t, eversion_t> pwlc,
const pg_shard_t &shard,
pg_info_t &info,
+ peering_stage stage,
PGLog *log = nullptr)
{
- apply_pwlc(pwlc, shard, info, nullptr, log);
+ apply_pwlc(pwlc, shard, info, stage, nullptr, log);
}
- void update_peer_info(const pg_shard_t &from, const pg_info_t &oinfo);
+ void update_peer_info(const pg_shard_t &from, const pg_info_t &oinfo, peering_stage stage);
bool proc_replica_notify(const pg_shard_t &from, const pg_notify_t ¬ify);
void remove_down_peer_info(const OSDMapRef &osdmap);
void check_recovery_sources(const OSDMapRef& map);