]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
mds: improve success rate of subtree exporting
authorYan, Zheng <zheng.z.yan@intel.com>
Wed, 5 Mar 2014 10:56:01 +0000 (18:56 +0800)
committerYan, Zheng <zheng.z.yan@intel.com>
Wed, 19 Mar 2014 03:35:56 +0000 (11:35 +0800)
When exporting a subtree, the migrator acquires the required locks,
then freezes the subtree and releases the locks. After subtree is
frozen, it try acquiring the same locks again.

This patch make scatter locks keep in their old states if inode has
exporting dirfrag. It improves the chance that migrator acquires all
required locks when subtree is frozen.

Signed-off-by: Yan, Zheng <zheng.z.yan@intel.com>
src/mds/CInode.cc
src/mds/CInode.h
src/mds/Locker.cc

index e58ceb18f4b60cc14a9948b8e8203847aadb94e0..c813f5c29ab1195cf3db0d2e119b454ece72c081 100644 (file)
@@ -642,6 +642,16 @@ bool CInode::has_subtree_root_dirfrag(int auth)
   return false;
 }
 
+bool CInode::has_subtree_or_exporting_dirfrag()
+{
+  for (map<frag_t,CDir*>::iterator p = dirfrags.begin();
+       p != dirfrags.end();
+       ++p)
+    if (p->second->is_subtree_root() ||
+       p->second->state_test(CDir::STATE_EXPORTING))
+      return true;
+  return false;
+}
 
 void CInode::get_stickydirs()
 {
index 7d2dd659b5968aadde9d2b8a30ab30923e5fc249..efc9825aa353ffc959fd8048fe636ca8f496d939 100644 (file)
@@ -355,6 +355,7 @@ public:
   void close_dirfrag(frag_t fg);
   void close_dirfrags();
   bool has_subtree_root_dirfrag(int auth=-1);
+  bool has_subtree_or_exporting_dirfrag();
 
   void force_dirfrags();
   void verify_dirfrags();
index 1906c49bc4c1338124a3ab32b9dd86daf8f0f8dc..1d570bb0b0c56c0144d059313742b938118ce487 100644 (file)
@@ -1298,7 +1298,7 @@ bool Locker::wrlock_start(SimpleLock *lock, MDRequest *mut, bool nowait)
   CInode *in = static_cast<CInode *>(lock->get_parent());
   client_t client = mut->get_client();
   bool want_scatter = !nowait && lock->get_parent()->is_auth() &&
-                     (in->has_subtree_root_dirfrag() ||
+                     (in->has_subtree_or_exporting_dirfrag() ||
                       static_cast<ScatterLock*>(lock)->get_scatter_wanted());
 
   while (1) {
@@ -3920,7 +3920,7 @@ void Locker::scatter_eval(ScatterLock *lock, bool *need_issue)
   }
 
   CInode *in = static_cast<CInode*>(lock->get_parent());
-  if (!in->has_subtree_root_dirfrag() || in->is_base()) {
+  if (!in->has_subtree_or_exporting_dirfrag() || in->is_base()) {
     // i _should_ be sync.
     if (!lock->is_wrlocked() &&
        lock->get_state() != LOCK_SYNC) {
@@ -4284,7 +4284,7 @@ void Locker::file_eval(ScatterLock *lock, bool *need_issue)
           !lock->is_rdlocked() &&
           //!lock->is_waiter_for(SimpleLock::WAIT_WR) &&
           ((wanted & (CEPH_CAP_GWR|CEPH_CAP_GBUFFER)) ||
-           (in->inode.is_dir() && !in->has_subtree_root_dirfrag())) &&
+           (in->inode.is_dir() && !in->has_subtree_or_exporting_dirfrag())) &&
           in->get_target_loner() >= 0) {
     dout(7) << "file_eval stable, bump to loner " << *lock
            << " on " << *lock->get_parent() << dendl;
@@ -4308,7 +4308,7 @@ void Locker::file_eval(ScatterLock *lock, bool *need_issue)
           !lock->is_waiter_for(SimpleLock::WAIT_WR) &&
           !(wanted & (CEPH_CAP_GWR|CEPH_CAP_GBUFFER)) &&
           !((lock->get_state() == LOCK_MIX) &&
-            in->is_dir() && in->has_subtree_root_dirfrag())  // if we are a delegation point, stay where we are
+            in->is_dir() && in->has_subtree_or_exporting_dirfrag())  // if we are a delegation point, stay where we are
           //((wanted & CEPH_CAP_RD) || 
           //in->is_replicated() || 
           //lock->get_num_client_lease() ||