]> git.proxmox.com Git - ceph.git/blobdiff - ceph/src/mds/StrayManager.cc
update sources to v12.1.0
[ceph.git] / ceph / src / mds / StrayManager.cc
index f4d3ac4efc7f986540a44e088e44017a56f9fc2e..25c2477441eaacfa7f7fc282ecd886c584d3203f 100644 (file)
@@ -237,9 +237,11 @@ void StrayManager::_purge_stray_logged(CDentry *dn, version_t pdv, LogSegment *l
 
   assert(!in->state_test(CInode::STATE_RECOVERING));
 
+  bool new_dn = dn->is_new();
+
   // unlink
   assert(dn->get_projected_linkage()->is_null());
-  dn->dir->unlink_inode(dn);
+  dn->dir->unlink_inode(dn, !new_dn);
   dn->pop_projected_linkage();
   dn->mark_dirty(pdv, ls);
 
@@ -250,12 +252,10 @@ void StrayManager::_purge_stray_logged(CDentry *dn, version_t pdv, LogSegment *l
   dn->put(CDentry::PIN_PURGING);
 
   // drop dentry?
-  if (dn->is_new()) {
+  if (new_dn) {
     dout(20) << " dn is new, removing" << dendl;
     dn->mark_clean();
     dn->dir->remove_dentry(dn);
-  } else {
-    in->mdcache->touch_dentry_bottom(dn);  // drop dn as quickly as possible.
   }
 
   // drop inode
@@ -431,10 +431,6 @@ bool StrayManager::_eval_stray(CDentry *dn, bool delay)
   assert(!dn->state_test(CDentry::STATE_PURGING));
 
   if (!dn->is_auth()) {
-    // has to be mine
-    // move to bottom of lru so that we trim quickly!
-
-    in->mdcache->touch_dentry_bottom(dn);
     return false;
   }
 
@@ -472,13 +468,7 @@ bool StrayManager::_eval_stray(CDentry *dn, bool delay)
        return false;  // not until some snaps are deleted.
       }
 
-      if (in->has_dirfrags()) {
-        list<CDir*> ls;
-        in->get_nested_dirfrags(ls);
-        for (list<CDir*>::iterator p = ls.begin(); p != ls.end(); ++p) {
-          (*p)->try_remove_dentries_for_stray();
-        }
-      }
+      in->mdcache->clear_dirty_bits_for_stray(in);
 
       if (!in->remote_parents.empty()) {
        // unlink any stale remote snap dentry.
@@ -545,7 +535,7 @@ bool StrayManager::_eval_stray(CDentry *dn, bool delay)
      * if we can do anything with them if we happen to have them in
      * cache.
      */
-    eval_remote_stray(dn, NULL);
+    _eval_stray_remote(dn, NULL);
     return false;
   }
 }
@@ -568,8 +558,51 @@ bool StrayManager::eval_stray(CDentry *dn, bool delay)
   return ret;
 }
 
-void StrayManager::eval_remote_stray(CDentry *stray_dn, CDentry *remote_dn)
+void StrayManager::eval_remote(CDentry *remote_dn)
 {
+  dout(10) << __func__ << " " << *remote_dn << dendl;
+
+  CDentry::linkage_t *dnl = remote_dn->get_projected_linkage();
+  assert(dnl->is_remote());
+  CInode *in = dnl->get_inode();
+
+  if (!in) {
+    dout(20) << __func__ << ": no inode, cannot evaluate" << dendl;
+    return;
+  }
+
+  if (remote_dn->last != CEPH_NOSNAP) {
+    dout(20) << __func__ << ": snap dentry, cannot evaluate" << dendl;
+    return;
+  }
+
+  // refers to stray?
+  CDentry *primary_dn = in->get_projected_parent_dn();
+  assert(primary_dn != NULL);
+  if (primary_dn->get_dir()->get_inode()->is_stray()) {
+    _eval_stray_remote(primary_dn, remote_dn);
+  } else {
+    dout(20) << __func__ << ": inode's primary dn not stray" << dendl;
+  }
+}
+
+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;
   assert(stray_dn != NULL);
   assert(stray_dn->get_dir()->get_inode()->is_stray());
   CDentry::linkage_t *stray_dnl = stray_dn->get_projected_linkage();
@@ -584,9 +617,14 @@ void StrayManager::eval_remote_stray(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) {
@@ -597,8 +635,14 @@ void StrayManager::eval_remote_stray(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 {