return howmuch;
}
-
+void MDBalancer::queue_split(CDir *dir)
+{
+ split_queue.insert(dir->dirfrag());
+}
void MDBalancer::do_fragmenting()
{
dout(0) << "do_fragmenting " << split_queue.size() << " dirs marked for possible splitting" << dendl;
- for (set<dirfrag_t>::iterator i = split_queue.begin();
- i != split_queue.end();
+ set<dirfrag_t> q;
+ q.swap(split_queue);
+
+ for (set<dirfrag_t>::iterator i = q.begin();
+ i != q.end();
i++) {
CDir *dir = mds->mdcache->get_dirfrag(*i);
if (!dir) continue;
dout(0) << "do_fragmenting splitting " << *dir << dendl;
mds->mdcache->split_dir(dir, g_conf.mds_bal_split_bits);
}
- split_queue.clear();
}
};
+bool MDCache::can_fragment_lock(CInode *diri)
+{
+ if (!diri->dirfragtreelock.can_wrlock(-1)) {
+ dout(7) << "can_fragment: can't wrlock dftlock" << dendl;
+ mds->locker->scatter_nudge(&diri->dirfragtreelock, NULL);
+ return false;
+ }
+ return true;
+}
+
bool MDCache::can_fragment(CInode *diri, list<CDir*>& dirs)
{
if (mds->mdsmap->is_degraded()) {
- dout(7) << "cluster degraded, no fragmenting for now" << dendl;
+ dout(7) << "can_fragment: cluster degraded, no fragmenting for now" << dendl;
return false;
}
if (diri->get_parent_dir() &&
diri->get_parent_dir()->get_inode()->is_stray()) {
- dout(7) << "i won't merge|split anything in stray" << dendl;
- return false;
- }
- if (!diri->dirfragtreelock.can_wrlock(-1)) {
- dout(7) << "can't wrlock dftlock" << dendl;
+ dout(7) << "can_fragment: i won't merge|split anything in stray" << dendl;
return false;
}
for (list<CDir*>::iterator p = dirs.begin(); p != dirs.end(); p++) {
CDir *dir = *p;
if (dir->state_test(CDir::STATE_FRAGMENTING)) {
- dout(7) << " already fragmenting " << *dir << dendl;
+ dout(7) << "can_fragment: already fragmenting " << *dir << dendl;
return false;
}
if (!dir->is_auth()) {
- dout(7) << " not auth on " << *dir << dendl;
+ dout(7) << "can_fragment: not auth on " << *dir << dendl;
return false;
}
if (dir->is_frozen() ||
dir->is_freezing()) {
- dout(7) << " can't merge, freezing|frozen. wait for other exports to finish first." << dendl;
+ dout(7) << "can_fragment: can't merge, freezing|frozen. wait for other exports to finish first." << dendl;
return false;
}
}
if (!can_fragment(diri, dirs))
return;
+ if (!can_fragment_lock(diri)) {
+ dout(10) << " requeuing dir " << dir->dirfrag() << dendl;
+ mds->balancer->queue_split(dir);
+ return;
+ }
C_Gather *gather = new C_Gather(new C_MDC_FragmentFrozen(this, dirs, dir->get_frag(), bits));
fragment_freeze_dirs(dirs, gather);
if (!can_fragment(diri, dirs))
return;
+ if (!can_fragment_lock(diri)) {
+ //dout(10) << " requeuing dir " << dir->dirfrag() << dendl;
+ //mds->mdbalancer->split_queue.insert(dir->dirfrag());
+ return;
+ }
C_Gather *gather = new C_Gather(new C_MDC_FragmentFrozen(this, dirs, frag, 0));
fragment_freeze_dirs(dirs, gather);