Merge pull request #37003 from xxhdx1985126/wip-47310

crimson/osd: drop repop if osdmap has increased

Reviewed-by: Kefu Chai <kchai@redhat.com>
This commit is contained in:
Kefu Chai 2020-09-08 13:38:51 +08:00 committed by GitHub
commit 056d8776ce
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 24 additions and 14 deletions

View File

@ -69,9 +69,7 @@ seastar::future<> ClientRequest::start()
return with_blocking_future(osd.wait_for_pg(m->get_spg()));
}).then([this, opref](Ref<PG> pgref) {
PG &pg = *pgref;
if (__builtin_expect(m->get_map_epoch()
< pg.get_info().history.same_primary_since,
false)) {
if (pg.can_discard_op(*m)) {
return osd.send_incremental_map(conn.get(), m->get_map_epoch());
}
return with_blocking_future(

View File

@ -908,6 +908,10 @@ seastar::future<> PG::handle_rep_op(Ref<MOSDRepOp> req)
crimson::common::system_shutdown_exception());
}
if (can_discard_replica_op(*req)) {
return seastar::now();
}
ceph::os::Transaction txn;
auto encoded_txn = req->get_data().cbegin();
decode(txn, encoded_txn);
@ -931,12 +935,13 @@ seastar::future<> PG::handle_rep_op(Ref<MOSDRepOp> req)
void PG::handle_rep_op_reply(crimson::net::Connection* conn,
const MOSDRepOpReply& m)
{
if (is_valid_rep_op_reply(m)) {
if (!can_discard_replica_op(m)) {
backend->got_rep_op_reply(m);
}
}
bool PG::is_valid_rep_op_reply(const MOSDRepOpReply& reply) const
template <typename MsgType>
bool PG::can_discard_replica_op(const MsgType& m) const
{
// if a repop is replied after a replica goes down in a new osdmap, and
// before the pg advances to this new osdmap, the repop replies before this
@ -945,27 +950,27 @@ bool PG::is_valid_rep_op_reply(const MOSDRepOpReply& reply) const
// resets the messenger sesssion when the replica reconnects. to avoid the
// out-of-order replies, the messages from that replica should be discarded.
const auto osdmap = peering_state.get_osdmap();
const int from_osd = reply.get_source().num();
const int from_osd = m.get_source().num();
if (osdmap->is_down(from_osd)) {
return false;
return true;
}
// Mostly, this overlaps with the old_peering_msg
// condition. An important exception is pushes
// sent by replicas not in the acting set, since
// if such a replica goes down it does not cause
// a new interval.
if (osdmap->get_down_at(from_osd) >= reply.map_epoch) {
return false;
if (osdmap->get_down_at(from_osd) >= m.map_epoch) {
return true;
}
// same pg?
// if pg changes *at all*, we reset and repeer!
if (epoch_t lpr = peering_state.get_last_peering_reset();
lpr > reply.map_epoch) {
lpr > m.map_epoch) {
logger().debug("{}: pg changed {} after {}, dropping",
__func__, get_info().history, reply.map_epoch);
return false;
__func__, get_info().history, m.map_epoch);
return true;
}
return true;
return false;
}
seastar::future<> PG::stop()
@ -988,4 +993,9 @@ void PG::on_change(ceph::os::Transaction &t) {
backend->on_actingset_changed({ is_primary() });
}
bool PG::can_discard_op(const MOSDOp& m) const {
return __builtin_expect(m.get_map_epoch()
< peering_state.get_info().history.same_primary_since, false);
}
}

View File

@ -670,7 +670,9 @@ private:
return seastar::make_ready_future<bool>(true);
}
bool is_valid_rep_op_reply(const MOSDRepOpReply& reply) const;
template <typename MsgType>
bool can_discard_replica_op(const MsgType& m) const;
bool can_discard_op(const MOSDOp& m) const;
bool is_missing_object(const hobject_t& soid) const {
return peering_state.get_pg_log().get_missing().get_items().count(soid);
}