]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
mds: requeue dir if we can't split now due to dftlock
authorSage Weil <sage@newdream.net>
Wed, 27 Oct 2010 01:33:10 +0000 (18:33 -0700)
committerSage Weil <sage@newdream.net>
Wed, 27 Oct 2010 02:19:04 +0000 (19:19 -0700)
Signed-off-by: Sage Weil <sage@newdream.net>
src/mds/MDBalancer.cc
src/mds/MDBalancer.h
src/mds/MDCache.cc
src/mds/MDCache.h

index 609e16f517dbdb03c79e34ae13d3a995e126b741..1fb769bccfa223386f07fb23a0d4276d0b03005a 100644 (file)
@@ -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<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;
@@ -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();
 }
 
 
index d5685584de4196dc6e20d100ef1a9126a448ea8d..292a7aedee478e8c991c8ff3331b17650d74d12b 100644 (file)
@@ -116,6 +116,8 @@ public:
   void show_imports(bool external=false);
   void dump_pop_map();  
 
+  void queue_split(CDir *dir);
+
 };
 
 
index 7bab5447dbb728f499159418164fe060022375d2..7f59f564905f045cb2c8d7ff7fc4fefb0141e427 100644 (file)
@@ -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<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;
     }
   }
@@ -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);
index e75e4636a89cfbda8950b9c9593b89c145f212de..17f6747327b214716bb55478da700521cd244f00 100644 (file)
@@ -1061,6 +1061,7 @@ private:
 
   friend class EFragment;
 
+  bool can_fragment_lock(CInode *diri);
   bool can_fragment(CInode *diri, list<CDir*>& dirs);
 
 public: