]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
mds: don't add null auth dentry to bottom lru
authorShen, Hang <shenhang@kuaishou.com>
Tue, 19 Jan 2021 06:38:29 +0000 (14:38 +0800)
committershenhang <shenhang@kuaishou.com>
Wed, 9 Feb 2022 09:31:45 +0000 (17:31 +0800)
null dentries are the key of not fetching complete dirfrag. don't trim
them too fast

Signed-off-by: "Shen, Hang" <shenhang@kuaishou.com>
src/mds/CDentry.cc
src/mds/CDentry.h
src/mds/CDir.cc
src/mds/CDir.h
src/mds/MDCache.cc
src/mds/Migrator.cc
src/mds/Server.cc
src/mds/journal.cc

index 3a9aa5ef4f53b550a3351b287b68ab4758b49c39..20db291556da21d9ae0df04e0491774c9b51ad1c 100644 (file)
@@ -225,6 +225,22 @@ void CDentry::mark_new()
   state_set(STATE_NEW);
 }
 
+void CDentry::mark_auth()
+{
+  if (!is_auth()) {
+    state_set(STATE_AUTH);
+    dir->adjust_dentry_lru(this);
+  }
+}
+
+void CDentry::clear_auth()
+{
+  if (is_auth()) {
+    state_clear(STATE_AUTH);
+    dir->adjust_dentry_lru(this);
+  }
+}
+
 void CDentry::make_path_string(string& s, bool projected) const
 {
   if (dir) {
index dff250bcac332f2309492a4fae84f43c36dac842..68d5d8b34c5085cb6a38ba03fc5e8b48127820ff 100644 (file)
@@ -257,6 +257,9 @@ public:
   void mark_new();
   bool is_new() const { return state_test(STATE_NEW); }
   void clear_new() { state_clear(STATE_NEW); }
+
+  void mark_auth();
+  void clear_auth();
   
   // -- exporting
   // note: this assumes the dentry already exists.  
@@ -276,7 +279,7 @@ public:
     // twiddle
     clear_replica_map();
     replica_nonce = EXPORT_NONCE;
-    state_clear(CDentry::STATE_AUTH);
+    clear_auth();
     if (is_dirty())
       mark_clean();
     put(PIN_TEMPEXPORTING);
@@ -296,7 +299,7 @@ public:
 
     // twiddle
     state &= MASK_STATE_IMPORT_KEPT;
-    state_set(CDentry::STATE_AUTH);
+    mark_auth();
     if (nstate & STATE_DIRTY)
       _mark_dirty(ls);
     if (is_replicated())
index 162edff6b4ecbf0d924bbc5646fc23f91b852bba..5bd44be7f4c14b89401f636577141ab5eac757c9 100644 (file)
@@ -337,6 +337,31 @@ CDentry *CDir::lookup_exact_snap(std::string_view name, snapid_t last) {
   return p->second;
 }
 
+void CDir::adjust_dentry_lru(CDentry *dn)
+{
+  bool bottom_lru;
+  if (dn->get_linkage()->is_primary()) {
+    bottom_lru = !is_auth() && inode->is_stray();
+  } else if (dn->get_linkage()->is_remote()) {
+    bottom_lru = false;
+  } else {
+    bottom_lru = !is_auth();
+  }
+  if (bottom_lru) {
+    if (!dn->state_test(CDentry::STATE_BOTTOMLRU)) {
+      mdcache->lru.lru_remove(dn);
+      mdcache->bottom_lru.lru_insert_mid(dn);
+      dn->state_set(CDentry::STATE_BOTTOMLRU);
+    }
+  } else {
+    if (dn->state_test(CDentry::STATE_BOTTOMLRU)) {
+      mdcache->bottom_lru.lru_remove(dn);
+      mdcache->lru.lru_insert_mid(dn);
+      dn->state_clear(CDentry::STATE_BOTTOMLRU);
+    }
+  }
+}
+
 /***
  * linking fun
  */
@@ -349,11 +374,13 @@ CDentry* CDir::add_null_dentry(std::string_view dname,
    
   // create dentry
   CDentry* dn = new CDentry(dname, inode->hash_dentry_name(dname), "", first, last);
-  if (is_auth()) 
+  if (is_auth()) {
     dn->state_set(CDentry::STATE_AUTH);
-
-  mdcache->bottom_lru.lru_insert_mid(dn);
-  dn->state_set(CDentry::STATE_BOTTOMLRU);
+    mdcache->lru.lru_insert_mid(dn);
+  } else {
+    mdcache->bottom_lru.lru_insert_mid(dn);
+    dn->state_set(CDentry::STATE_BOTTOMLRU);
+  }
 
   dn->dir = this;
   dn->version = get_projected_version();
@@ -623,7 +650,8 @@ void CDir::unlink_inode(CDentry *dn, bool adjust_lru)
 
   unlink_inode_work(dn);
 
-  if (adjust_lru && !dn->state_test(CDentry::STATE_BOTTOMLRU)) {
+  if (adjust_lru && !is_auth() &&
+      !dn->state_test(CDentry::STATE_BOTTOMLRU)) {
     mdcache->lru.lru_remove(dn);
     mdcache->bottom_lru.lru_insert_mid(dn);
     dn->state_set(CDentry::STATE_BOTTOMLRU);
@@ -639,7 +667,6 @@ void CDir::unlink_inode(CDentry *dn, bool adjust_lru)
   ceph_assert(get_num_any() == items.size());
 }
 
-
 void CDir::try_remove_unlinked_dn(CDentry *dn)
 {
   ceph_assert(dn->dir == this);
index 064061f1c8b332fa5d2fce39ae1284c3dad2598a..1d87f314dcb7455502b6db577260ea1eb7ca57d8 100644 (file)
@@ -368,6 +368,7 @@ public:
   CDentry* lookup_exact_snap(std::string_view dname, snapid_t last);
   CDentry* lookup(std::string_view n, snapid_t snap=CEPH_NOSNAP);
 
+  void adjust_dentry_lru(CDentry *dn);
   CDentry* add_null_dentry(std::string_view dname,
                           snapid_t first=2, snapid_t last=CEPH_NOSNAP);
   CDentry* add_primary_dentry(std::string_view dname, CInode *in, mempool::mds_co::string alternate_name,
index 3616c91eaff9d0a07c112847202c184a0d469fd2..b525601280d6e7ad525a8017cf0aa3762c261c6e 100644 (file)
@@ -3873,9 +3873,9 @@ void MDCache::recalc_auth_bits(bool replay)
        CDentry *dn = p.second;
        CDentry::linkage_t *dnl = dn->get_linkage();
        if (auth) {
-         dn->state_set(CDentry::STATE_AUTH);
+         dn->mark_auth();
        } else {
-         dn->state_clear(CDentry::STATE_AUTH);
+         dn->clear_auth();
          if (!replay) {
            dn->state_set(CDentry::STATE_REJOINING);
            if (dn->is_dirty())
@@ -7260,7 +7260,7 @@ bool MDCache::trim_non_auth_subtree(CDir *dir)
         dir->remove_dentry(dn);
       } else {
         dout(20) << "trim_non_auth_subtree(" << dir << ") keeping inode " << in << " with dentry " << dn <<dendl;
-       dn->state_clear(CDentry::STATE_AUTH);
+       dn->clear_auth();
        in->state_clear(CInode::STATE_AUTH);
       }
     } else if (keep_dir && dnl->is_null()) { // keep null dentry for peer rollback
index 2e76fc2a2b56f846e69d143188567f10406e9ea9..caa7e0053a60c9c59d94bfab04db393a8d51f131 100644 (file)
@@ -2850,7 +2850,7 @@ void Migrator::import_reverse(CDir *dir)
       CDentry *dn = p.second;
 
       // dentry
-      dn->state_clear(CDentry::STATE_AUTH);
+      dn->clear_auth();
       dn->clear_replica_map();
       dn->set_replica_nonce(CDentry::EXPORT_NONCE);
       if (dn->is_dirty()) 
@@ -2859,7 +2859,7 @@ void Migrator::import_reverse(CDir *dir)
       // inode?
       if (dn->get_linkage()->is_primary()) {
        CInode *in = dn->get_linkage()->get_inode();
-       in->state_clear(CDentry::STATE_AUTH);
+       in->state_clear(CInode::STATE_AUTH);
        in->clear_replica_map();
        in->set_replica_nonce(CInode::EXPORT_NONCE);
        if (in->is_dirty()) 
index b0113d73fb50f9c8868207baa97a073a258b418c..b526754b1d16282aaf4e386cd25402636ccd660b 100644 (file)
@@ -4691,8 +4691,11 @@ void Server::handle_client_readdir(MDRequestRef& mdr)
     bool dnp = dn->use_projected(client, mdr);
     CDentry::linkage_t *dnl = dnp ? dn->get_projected_linkage() : dn->get_linkage();
 
-    if (dnl->is_null())
+    if (dnl->is_null()) {
+      if (dn->get_num_ref() == 0 && !dn->is_projected())
+       dir->remove_dentry(dn);
       continue;
+    }
 
     if (dn->last < snapid || dn->first > snapid) {
       dout(20) << "skipping non-overlapping snap " << *dn << dendl;
index 0c211ee39fe3e052b659507aaf1a4d9f3fa0199d..729d394bd9ed2d5032ca3308d6ca37341dc3c231 100644 (file)
@@ -1298,7 +1298,7 @@ void EMetaBlob::replay(MDSRank *mds, LogSegment *logseg, MDPeerUpdate *peerup)
        ceph_assert(dn->last == fb.dnlast);
       }
       if (lump.is_importing())
-       dn->state_set(CDentry::STATE_AUTH);
+       dn->mark_auth();
 
       CInode *in = mds->mdcache->get_inode(fb.inode->ino, fb.dnlast);
       if (!in) {
@@ -1395,7 +1395,7 @@ void EMetaBlob::replay(MDSRank *mds, LogSegment *logseg, MDPeerUpdate *peerup)
        ceph_assert(dn->last == rb.dnlast);
       }
       if (lump.is_importing())
-       dn->state_set(CDentry::STATE_AUTH);
+       dn->mark_auth();
 
       if (!(++count % 1000))
         mds->heartbeat_reset();
@@ -1430,7 +1430,7 @@ void EMetaBlob::replay(MDSRank *mds, LogSegment *logseg, MDPeerUpdate *peerup)
       }
       olddir = dir;
       if (lump.is_importing())
-       dn->state_set(CDentry::STATE_AUTH);
+       dn->mark_auth();
 
       // Make null dentries the first things we trim
       dout(10) << "EMetaBlob.replay pushing to bottom of lru " << *dn << dendl;