From: Sage Weil Date: Wed, 27 Oct 2010 01:33:10 +0000 (-0700) Subject: mds: requeue dir if we can't split now due to dftlock X-Git-Tag: v0.23~61^2~6 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=4c79f3691c27c28a0e2245817c22ee00697d4337;p=ceph.git mds: requeue dir if we can't split now due to dftlock Signed-off-by: Sage Weil --- diff --git a/src/mds/MDBalancer.cc b/src/mds/MDBalancer.cc index 609e16f517db..1fb769bccfa2 100644 --- a/src/mds/MDBalancer.cc +++ b/src/mds/MDBalancer.cc @@ -309,7 +309,10 @@ double MDBalancer::try_match(int ex, double& maxex, return howmuch; } - +void MDBalancer::queue_split(CDir *dir) +{ + split_queue.insert(dir->dirfrag()); +} void MDBalancer::do_fragmenting() { @@ -320,8 +323,11 @@ void MDBalancer::do_fragmenting() dout(0) << "do_fragmenting " << split_queue.size() << " dirs marked for possible splitting" << dendl; - for (set::iterator i = split_queue.begin(); - i != split_queue.end(); + set q; + q.swap(split_queue); + + for (set::iterator i = q.begin(); + i != q.end(); i++) { CDir *dir = mds->mdcache->get_dirfrag(*i); if (!dir) continue; @@ -330,7 +336,6 @@ void MDBalancer::do_fragmenting() dout(0) << "do_fragmenting splitting " << *dir << dendl; mds->mdcache->split_dir(dir, g_conf.mds_bal_split_bits); } - split_queue.clear(); } diff --git a/src/mds/MDBalancer.h b/src/mds/MDBalancer.h index d5685584de41..292a7aedee47 100644 --- a/src/mds/MDBalancer.h +++ b/src/mds/MDBalancer.h @@ -116,6 +116,8 @@ public: void show_imports(bool external=false); void dump_pop_map(); + void queue_split(CDir *dir); + }; diff --git a/src/mds/MDCache.cc b/src/mds/MDCache.cc index 7bab5447dbb7..7f59f564905f 100644 --- a/src/mds/MDCache.cc +++ b/src/mds/MDCache.cc @@ -8533,35 +8533,41 @@ public: }; +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& 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::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; } } @@ -8580,6 +8586,11 @@ void MDCache::split_dir(CDir *dir, int bits) 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); @@ -8600,6 +8611,11 @@ void MDCache::merge_dir(CInode *diri, frag_t frag) 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); diff --git a/src/mds/MDCache.h b/src/mds/MDCache.h index e75e4636a89c..17f6747327b2 100644 --- a/src/mds/MDCache.h +++ b/src/mds/MDCache.h @@ -1061,6 +1061,7 @@ private: friend class EFragment; + bool can_fragment_lock(CInode *diri); bool can_fragment(CInode *diri, list& dirs); public: