Skip to content

Commit

Permalink
osd: fix rare race for pg relevant events
Browse files Browse the repository at this point in the history
Theoretically even if _have_pg() returns ture, we still can't assert that
_lookup_lock_pg() will always succeed. This is because when we switch between
these two methods, we will drop pg_map_lock, and thus may let a pg removal
sneak in, which may eventually cause divergence.

However this is a really rare case, and is less likely to happen in a
production environment. But this pr provided a safer way to achieve
the same goal and is a little faster by eliminating a duplicated search
from the pg_map, which makes it meaningful.

Signed-off-by: xie xingguo <xie.xingguo@zte.com.cn>
  • Loading branch information
xiexingguo committed Mar 22, 2016
1 parent 4546427 commit 7bcaedb
Showing 1 changed file with 37 additions and 40 deletions.
77 changes: 37 additions & 40 deletions src/osd/OSD.cc
Expand Up @@ -7840,40 +7840,39 @@ void OSD::handle_pg_trim(OpRequestRef op)

op->mark_started();

if (!_have_pg(m->pgid)) {
PG *pg = _lookup_lock_pg(m->pgid);
if(!pg) {
dout(10) << " don't have pg " << m->pgid << dendl;
} else {
PG *pg = _lookup_lock_pg(m->pgid);
assert(pg);
if (m->epoch < pg->info.history.same_interval_since) {
dout(10) << *pg << " got old trim to " << m->trim_to << ", ignoring" << dendl;
pg->unlock();
return;
}
return;
}

if (pg->is_primary()) {
// peer is informing us of their last_complete_ondisk
dout(10) << *pg << " replica osd." << from << " lcod " << m->trim_to << dendl;
pg->peer_last_complete_ondisk[pg_shard_t(from, m->pgid.shard)] =
m->trim_to;
if (pg->calc_min_last_complete_ondisk()) {
dout(10) << *pg << " min lcod now " << pg->min_last_complete_ondisk << dendl;
pg->trim_peers();
}
} else {
// primary is instructing us to trim
ObjectStore::Transaction t;
PG::PGLogEntryHandler handler;
pg->pg_log.trim(&handler, m->trim_to, pg->info);
handler.apply(pg, &t);
pg->dirty_info = true;
pg->write_if_dirty(t);
int tr = store->queue_transaction(
pg->osr.get(), std::move(t), NULL);
assert(tr == 0);
}
if (m->epoch < pg->info.history.same_interval_since) {
dout(10) << *pg << " got old trim to " << m->trim_to << ", ignoring" << dendl;
pg->unlock();
return;
}

if (pg->is_primary()) {
// peer is informing us of their last_complete_ondisk
dout(10) << *pg << " replica osd." << from << " lcod " << m->trim_to << dendl;
pg->peer_last_complete_ondisk[pg_shard_t(from, m->pgid.shard)] =
m->trim_to;
if (pg->calc_min_last_complete_ondisk()) {
dout(10) << *pg << " min lcod now " << pg->min_last_complete_ondisk << dendl;
pg->trim_peers();
}
} else {
// primary is instructing us to trim
ObjectStore::Transaction t;
PG::PGLogEntryHandler handler;
pg->pg_log.trim(&handler, m->trim_to, pg->info);
handler.apply(pg, &t);
pg->dirty_info = true;
pg->write_if_dirty(t);
int tr = store->queue_transaction(pg->osr.get(), std::move(t), NULL);
assert(tr == 0);
}
pg->unlock();
}

void OSD::handle_pg_backfill_reserve(OpRequestRef op)
Expand Down Expand Up @@ -7914,12 +7913,11 @@ void OSD::handle_pg_backfill_reserve(OpRequestRef op)
return;
}

PG *pg = 0;
if (!_have_pg(m->pgid))
PG *pg = _lookup_lock_pg(m->pgid);
if (!pg) {
dout(10) << " don't have pg " << m->pgid << dendl;
return;

pg = _lookup_lock_pg(m->pgid);
assert(pg);
}

pg->queue_peering_event(evt);
pg->unlock();
Expand Down Expand Up @@ -7963,12 +7961,11 @@ void OSD::handle_pg_recovery_reserve(OpRequestRef op)
return;
}

PG *pg = 0;
if (!_have_pg(m->pgid))
PG *pg = _lookup_lock_pg(m->pgid);
if (!pg) {
dout(10) << " don't have pg " << m->pgid << dendl;
return;

pg = _lookup_lock_pg(m->pgid);
assert(pg);
}

pg->queue_peering_event(evt);
pg->unlock();
Expand Down

0 comments on commit 7bcaedb

Please sign in to comment.