]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
mds: improve StrayManager::eval_remote_stray()
authorYan, Zheng <zyan@redhat.com>
Thu, 8 Jun 2017 05:03:44 +0000 (13:03 +0800)
committerYan, Zheng <zyan@redhat.com>
Mon, 12 Jun 2017 01:46:02 +0000 (09:46 +0800)
choose auth and pinnable remote dentry when possible. If the chosen
remote dentry is frozen, retry when it gets unfreezed.

Signed-off-by: "Yan, Zheng" <zyan@redhat.com>
src/mds/StrayManager.cc

index ea4b2025a8444f5f6f8654f3f6b354467aeb89ec..25c2477441eaacfa7f7fc282ecd886c584d3203f 100644 (file)
@@ -586,6 +586,20 @@ void StrayManager::eval_remote(CDentry *remote_dn)
   }
 }
 
+class C_RetryEvalRemote : public StrayManagerContext {
+  CDentry *dn;
+  public:
+    C_RetryEvalRemote(StrayManager *sm_, CDentry *dn_) :
+      StrayManagerContext(sm_), dn(dn_) {
+      dn->get(CDentry::PIN_PTRWAITER);
+    }
+    void finish(int r) override {
+      if (dn->get_projected_linkage()->is_remote())
+       sm->eval_remote(dn);
+      dn->put(CDentry::PIN_PTRWAITER);
+    }
+};
+
 void StrayManager::_eval_stray_remote(CDentry *stray_dn, CDentry *remote_dn)
 {
   dout(20) << __func__ << " " << *stray_dn << dendl;
@@ -603,9 +617,14 @@ void StrayManager::_eval_stray_remote(CDentry *stray_dn, CDentry *remote_dn)
       for (compact_set<CDentry*>::iterator p = stray_in->remote_parents.begin();
           p != stray_in->remote_parents.end();
           ++p)
-       if ((*p)->last == CEPH_NOSNAP) {
-         remote_dn = *p;
-         break;
+       if ((*p)->last == CEPH_NOSNAP && !(*p)->is_projected()) {
+         if ((*p)->is_auth()) {
+           remote_dn = *p;
+           if (remote_dn->dir->can_auth_pin())
+             break;
+         } else if (!remote_dn) {
+           remote_dn = *p;
+         }
        }
     }
     if (!remote_dn) {
@@ -616,8 +635,14 @@ void StrayManager::_eval_stray_remote(CDentry *stray_dn, CDentry *remote_dn)
   assert(remote_dn->last == CEPH_NOSNAP);
   // NOTE: we repeat this check in _rename(), since our submission path is racey.
   if (!remote_dn->is_projected()) {
-    if (remote_dn->is_auth() && remote_dn->dir->can_auth_pin()) {
-      reintegrate_stray(stray_dn, remote_dn);
+    if (remote_dn->is_auth()) {
+      if (remote_dn->dir->can_auth_pin()) {
+       reintegrate_stray(stray_dn, remote_dn);
+      } else {
+       remote_dn->dir->add_waiter(CDir::WAIT_UNFREEZE, new C_RetryEvalRemote(this, remote_dn));
+       dout(20) << __func__ << ": not reintegrating (can't authpin remote parent)" << dendl;
+      }
+
     } else if (!remote_dn->is_auth() && stray_dn->is_auth()) {
       migrate_stray(stray_dn, remote_dn->authority().first);
     } else {