epoch_t start, end;
vector<int> old_acting, old_up;
epoch_t same_interval_since;
+ int primary;
};
void OSD::build_past_intervals_parallel()
continue;
vector<int> acting, up;
- cur_map->pg_to_up_acting_osds(pg->info.pgid.pgid, up, acting);
+ int primary;
+ cur_map->pg_to_up_acting_osds(
+ pg->info.pgid.pgid, &up, 0, &acting, &primary);
if (p.same_interval_since == 0) {
dout(10) << __func__ << " epoch " << cur_epoch << " pg " << pg->info.pgid
p.same_interval_since = cur_epoch;
p.old_up = up;
p.old_acting = acting;
+ p.primary = primary;
continue;
}
assert(last_map);
std::stringstream debug;
bool new_interval = pg_interval_t::check_new_interval(
+ p.primary,
+ primary,
p.old_acting, acting,
p.old_up, up,
p.same_interval_since,
}
OSDMapRef last_map, cur_map;
+ int primary = -1;
+ int old_primary = -1;
vector<int> acting, up, old_acting, old_up;
cur_map = osd->get_map(cur_epoch);
- cur_map->pg_to_up_acting_osds(get_pgid().pgid, up, acting);
+ cur_map->pg_to_up_acting_osds(
+ get_pgid().pgid, &up, 0, &acting, &primary);
epoch_t same_interval_since = cur_epoch;
dout(10) << __func__ << " over epochs " << cur_epoch << "-"
<< end_epoch << dendl;
last_map.swap(cur_map);
old_up.swap(up);
old_acting.swap(acting);
+ old_primary = primary;
cur_map = osd->get_map(cur_epoch);
- cur_map->pg_to_up_acting_osds(get_pgid().pgid, up, acting);
+ cur_map->pg_to_up_acting_osds(
+ get_pgid().pgid, &up, 0, &acting, &primary);
std::stringstream debug;
bool new_interval = pg_interval_t::check_new_interval(
+ old_primary,
+ primary,
old_acting,
acting,
old_up,
set<int> new_peers;
if (is_primary()) {
- for (unsigned i=0; i<acting.size(); i++)
- new_peers.insert(acting[i]);
- for (unsigned i=0; i<up.size(); i++)
- new_peers.insert(up[i]);
+ for (unsigned i=0; i<acting.size(); i++) {
+ if (acting[i] != CRUSH_ITEM_NONE)
+ new_peers.insert(acting[i]);
+ }
+ for (unsigned i=0; i<up.size(); i++) {
+ if (up[i] != CRUSH_ITEM_NONE)
+ new_peers.insert(up[i]);
+ }
for (map<pg_shard_t,pg_info_t>::iterator p = peer_info.begin();
p != peer_info.end();
++p)
} else {
std::stringstream debug;
bool new_interval = pg_interval_t::check_new_interval(
+ oldprimary.osd,
+ new_acting_primary,
oldacting, newacting,
oldup, newup,
info.history.same_interval_since,
void pg_interval_t::encode(bufferlist& bl) const
{
- ENCODE_START(2, 2, bl);
+ ENCODE_START(3, 2, bl);
::encode(first, bl);
::encode(last, bl);
::encode(up, bl);
::encode(acting, bl);
::encode(maybe_went_rw, bl);
+ ::encode(primary, bl);
ENCODE_FINISH(bl);
}
void pg_interval_t::decode(bufferlist::iterator& bl)
{
- DECODE_START_LEGACY_COMPAT_LEN(2, 2, 2, bl);
+ DECODE_START_LEGACY_COMPAT_LEN(3, 2, 2, bl);
::decode(first, bl);
::decode(last, bl);
::decode(up, bl);
::decode(acting, bl);
::decode(maybe_went_rw, bl);
+ if (struct_v >= 3) {
+ ::decode(primary, bl);
+ } else {
+ if (acting.size())
+ primary = acting[0];
+ }
DECODE_FINISH(bl);
}
}
bool pg_interval_t::check_new_interval(
+ int old_primary,
+ int new_primary,
const vector<int> &old_acting,
const vector<int> &new_acting,
const vector<int> &old_up,
std::ostream *out)
{
// remember past interval
- if (new_acting != old_acting || new_up != old_up ||
+ if (old_primary != new_primary ||
+ new_acting != old_acting || new_up != old_up ||
(!(lastmap->get_pools().count(pool_id))) ||
(lastmap->get_pools().find(pool_id)->second.min_size !=
osdmap->get_pools().find(pool_id)->second.min_size) ||
i.last = osdmap->get_epoch() - 1;
i.acting = old_acting;
i.up = old_up;
+ i.primary = old_primary;
- if (!i.acting.empty() &&
+ if (!i.acting.empty() && i.primary != -1 &&
i.acting.size() >=
lastmap->get_pools().find(pool_id)->second.min_size) {
if (out)
*out << "generate_past_intervals " << i
<< ": not rw,"
- << " up_thru " << lastmap->get_up_thru(i.acting[0])
- << " up_from " << lastmap->get_up_from(i.acting[0])
+ << " up_thru " << lastmap->get_up_thru(i.primary)
+ << " up_from " << lastmap->get_up_from(i.primary)
<< " last_epoch_clean " << last_epoch_clean
<< std::endl;
- if (lastmap->get_up_thru(i.acting[0]) >= i.first &&
- lastmap->get_up_from(i.acting[0]) <= i.first) {
+ if (lastmap->get_up_thru(i.primary) >= i.first &&
+ lastmap->get_up_from(i.primary) <= i.first) {
i.maybe_went_rw = true;
if (out)
*out << "generate_past_intervals " << i
- << " : primary up " << lastmap->get_up_from(i.acting[0])
- << "-" << lastmap->get_up_thru(i.acting[0])
+ << " : primary up " << lastmap->get_up_from(i.primary)
+ << "-" << lastmap->get_up_thru(i.primary)
<< " includes interval"
<< std::endl;
} else if (last_epoch_clean >= i.first &&
i.maybe_went_rw = false;
if (out)
*out << "generate_past_intervals " << i
- << " : primary up " << lastmap->get_up_from(i.acting[0])
- << "-" << lastmap->get_up_thru(i.acting[0])
+ << " : primary up " << lastmap->get_up_from(i.primary)
+ << "-" << lastmap->get_up_thru(i.primary)
<< " does not include interval"
<< std::endl;
}
vector<int> up, acting;
epoch_t first, last;
bool maybe_went_rw;
+ int primary;
- pg_interval_t() : first(0), last(0), maybe_went_rw(false) {}
+ pg_interval_t() : first(0), last(0), maybe_went_rw(false), primary(-1) {}
void encode(bufferlist& bl) const;
void decode(bufferlist::iterator& bl);
* if an interval was closed out.
*/
static bool check_new_interval(
+ int old_primary, ///< [in] primary as of lastmap
+ int new_primary, ///< [in] primary as of lastmap
const vector<int> &old_acting, ///< [in] acting as of lastmap
const vector<int> &new_acting, ///< [in] acting as of osdmap
const vector<int> &old_up, ///< [in] up as of lastmap
void dec(list<OpRequestRef> *requeue) {
assert(count > 0);
assert(requeue);
- assert(requeue->empty());
count--;
if (count == 0) {
state = RWNONE;
- requeue->swap(waiters);
+ requeue->splice(requeue->end(), waiters);
}
}
void put_read(list<OpRequestRef> *requeue) {
new_acting.push_back(osd_id);
new_acting.push_back(osd_id + 1);
vector<int> old_acting = new_acting;
+ int old_primary = osd_id;
+ int new_primary = osd_id;
vector<int> new_up;
new_up.push_back(osd_id);
vector<int> old_up = new_up;
map<epoch_t, pg_interval_t> past_intervals;
ASSERT_TRUE(past_intervals.empty());
- ASSERT_FALSE(pg_interval_t::check_new_interval(old_acting,
+ ASSERT_FALSE(pg_interval_t::check_new_interval(old_primary,
+ new_primary,
+ old_acting,
new_acting,
old_up,
new_up,
map<epoch_t, pg_interval_t> past_intervals;
ASSERT_TRUE(past_intervals.empty());
- ASSERT_TRUE(pg_interval_t::check_new_interval(old_acting,
+ ASSERT_TRUE(pg_interval_t::check_new_interval(old_primary,
+ new_primary,
+ old_acting,
new_acting,
old_up,
new_up,
//
{
vector<int> new_acting;
- int new_primary = osd_id + 1;
- new_acting.push_back(new_primary);
+ int _new_primary = osd_id + 1;
+ new_acting.push_back(_new_primary);
map<epoch_t, pg_interval_t> past_intervals;
ASSERT_TRUE(past_intervals.empty());
- ASSERT_TRUE(pg_interval_t::check_new_interval(old_acting,
+ ASSERT_TRUE(pg_interval_t::check_new_interval(old_primary,
+ new_primary,
+ old_acting,
new_acting,
old_up,
new_up,
pool_id,
pgid,
&past_intervals));
+ old_primary = new_primary;
ASSERT_EQ((unsigned int)1, past_intervals.size());
ASSERT_EQ(same_interval_since, past_intervals[same_interval_since].first);
ASSERT_EQ(osdmap->get_epoch() - 1, past_intervals[same_interval_since].last);
//
{
vector<int> new_up;
- int new_primary = osd_id + 1;
- new_up.push_back(new_primary);
+ int _new_primary = osd_id + 1;
+ new_up.push_back(_new_primary);
map<epoch_t, pg_interval_t> past_intervals;
ASSERT_TRUE(past_intervals.empty());
- ASSERT_TRUE(pg_interval_t::check_new_interval(old_acting,
+ ASSERT_TRUE(pg_interval_t::check_new_interval(old_primary,
+ new_primary,
+ old_acting,
new_acting,
old_up,
new_up,
map<epoch_t, pg_interval_t> past_intervals;
ASSERT_TRUE(past_intervals.empty());
- ASSERT_TRUE(pg_interval_t::check_new_interval(old_acting,
+ ASSERT_TRUE(pg_interval_t::check_new_interval(old_primary,
+ new_primary,
+ old_acting,
new_acting,
old_up,
new_up,
map<epoch_t, pg_interval_t> past_intervals;
ASSERT_TRUE(past_intervals.empty());
- ASSERT_TRUE(pg_interval_t::check_new_interval(old_acting,
+ ASSERT_TRUE(pg_interval_t::check_new_interval(old_primary,
+ new_primary,
+ old_acting,
new_acting,
old_up,
new_up,
ostringstream out;
ASSERT_TRUE(past_intervals.empty());
- ASSERT_TRUE(pg_interval_t::check_new_interval(old_acting,
+ ASSERT_TRUE(pg_interval_t::check_new_interval(old_primary,
+ new_primary,
+ old_acting,
new_acting,
old_up,
new_up,
map<epoch_t, pg_interval_t> past_intervals;
ASSERT_TRUE(past_intervals.empty());
- ASSERT_TRUE(pg_interval_t::check_new_interval(old_acting,
+ ASSERT_TRUE(pg_interval_t::check_new_interval(old_primary,
+ new_primary,
+ old_acting,
new_acting,
old_up,
new_up,
map<epoch_t, pg_interval_t> past_intervals;
ASSERT_TRUE(past_intervals.empty());
- ASSERT_TRUE(pg_interval_t::check_new_interval(old_acting,
+ ASSERT_TRUE(pg_interval_t::check_new_interval(old_primary,
+ new_primary,
+ old_acting,
new_acting,
old_up,
new_up,
map<epoch_t, pg_interval_t> past_intervals;
ASSERT_TRUE(past_intervals.empty());
- ASSERT_TRUE(pg_interval_t::check_new_interval(old_acting,
+ ASSERT_TRUE(pg_interval_t::check_new_interval(old_primary,
+ new_primary,
+ old_acting,
new_acting,
old_up,
new_up,
map<epoch_t, pg_interval_t> past_intervals;
ASSERT_TRUE(past_intervals.empty());
- ASSERT_TRUE(pg_interval_t::check_new_interval(old_acting,
+ ASSERT_TRUE(pg_interval_t::check_new_interval(old_primary,
+ new_primary,
+ old_acting,
new_acting,
old_up,
new_up,