osd: split backoffs on PG split

Signed-off-by: Sage Weil <sage@redhat.com>
This commit is contained in:
Sage Weil 2017-02-01 17:27:32 -05:00
parent cefb43dd14
commit 9cef8e4e4a
2 changed files with 72 additions and 0 deletions

View File

@ -2308,6 +2308,12 @@ void PG::split_into(pg_t child_pgid, PG *child, unsigned split_bits)
split_ops(child, split_bits);
_split_into(child_pgid, child, split_bits);
// release all backoffs so that Objecter doesn't need to handle unblock
// on split backoffs
release_backoffs(hobject_t(), hobject_t::get_max());
// split any remaining (deleting) backoffs among child PGs
split_backoffs(child, split_bits);
child->on_new_interval();
child->dirty_info = true;
@ -2411,6 +2417,71 @@ void PG::release_backoffs(const hobject_t& begin, const hobject_t& end)
}
}
void PG::split_backoffs(PG *child, unsigned split_bits)
{
dout(10) << __func__ << " split_bits " << split_bits << " child "
<< child->info.pgid.pgid << dendl;
unsigned mask = ~((~0)<<split_bits);
vector<BackoffRef> backoffs_to_dup; // pg backoffs
vector<BackoffRef> backoffs_to_move; // oid backoffs
{
Mutex::Locker l(backoff_lock);
auto p = backoffs.begin();
while (p != backoffs.end()) {
if (p->first == info.pgid.pgid.get_hobj_start()) {
// if it is a full PG we always dup it for the child.
for (auto& q : p->second) {
dout(10) << __func__ << " pg backoff " << p->first
<< " " << q << dendl;
backoffs_to_dup.push_back(q);
}
} else {
// otherwise, we move it to the child only if falls into the
// childs hash range.
if ((p->first.get_hash() & mask) == child->info.pgid.pgid.ps()) {
for (auto& q : p->second) {
dout(20) << __func__ << " will move " << p->first
<< " " << q << dendl;
backoffs_to_move.push_back(q);
}
p = backoffs.erase(p);
continue;
} else {
dout(20) << __func__ << " will not move " << p->first
<< " " << p->second << dendl;
}
}
++p;
}
}
for (auto b : backoffs_to_dup) {
SessionRef s;
{
Mutex::Locker l(b->lock);
b->end = info.pgid.pgid.get_hobj_end(split_bits);
dout(10) << __func__ << " pg backoff " << *b << dendl;
s = b->session;
}
if (s) {
child->add_pg_backoff(b->session);
} else {
dout(20) << __func__ << " didn't dup pg backoff, session is null"
<< dendl;
}
}
for (auto b : backoffs_to_move) {
Mutex::Locker l(b->lock);
if (b->pg == this) {
dout(10) << __func__ << " move backoff " << *b << " to child" << dendl;
b->pg = child;
child->backoffs[b->begin].insert(b);
} else {
dout(20) << __func__ << " move backoff " << *b << " nowhere... pg is null"
<< dendl;
}
}
}
void PG::clear_backoffs()
{
dout(10) << __func__ << " " << dendl;

View File

@ -1094,6 +1094,7 @@ public:
release_backoffs(o, o);
}
void clear_backoffs();
void split_backoffs(PG *child, unsigned split_bits);
void add_pg_backoff(SessionRef s) {
hobject_t begin = info.pgid.pgid.get_hobj_start();