From 634082c1569b2109d767a1392402cc60127d6c22 Mon Sep 17 00:00:00 2001 From: "Shen, Hang" Date: Tue, 19 Jan 2021 14:38:29 +0800 Subject: [PATCH] mds: don't add null auth dentry to bottom lru null dentries are the key of not fetching complete dirfrag. don't trim them too fast Signed-off-by: "Shen, Hang" --- src/mds/CDentry.cc | 16 ++++++++++++++++ src/mds/CDentry.h | 7 +++++-- src/mds/CDir.cc | 39 +++++++++++++++++++++++++++++++++------ src/mds/CDir.h | 1 + src/mds/MDCache.cc | 6 +++--- src/mds/Migrator.cc | 4 ++-- src/mds/Server.cc | 5 ++++- src/mds/journal.cc | 6 +++--- 8 files changed, 67 insertions(+), 17 deletions(-) diff --git a/src/mds/CDentry.cc b/src/mds/CDentry.cc index 3a9aa5ef4f53b..20db291556da2 100644 --- a/src/mds/CDentry.cc +++ b/src/mds/CDentry.cc @@ -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) { diff --git a/src/mds/CDentry.h b/src/mds/CDentry.h index dff250bcac332..68d5d8b34c508 100644 --- a/src/mds/CDentry.h +++ b/src/mds/CDentry.h @@ -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()) diff --git a/src/mds/CDir.cc b/src/mds/CDir.cc index 162edff6b4ecb..5bd44be7f4c14 100644 --- a/src/mds/CDir.cc +++ b/src/mds/CDir.cc @@ -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); diff --git a/src/mds/CDir.h b/src/mds/CDir.h index 064061f1c8b33..1d87f314dcb74 100644 --- a/src/mds/CDir.h +++ b/src/mds/CDir.h @@ -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, diff --git a/src/mds/MDCache.cc b/src/mds/MDCache.cc index 3616c91eaff9d..b525601280d6e 100644 --- a/src/mds/MDCache.cc +++ b/src/mds/MDCache.cc @@ -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 <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 diff --git a/src/mds/Migrator.cc b/src/mds/Migrator.cc index 2e76fc2a2b56f..caa7e0053a60c 100644 --- a/src/mds/Migrator.cc +++ b/src/mds/Migrator.cc @@ -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()) diff --git a/src/mds/Server.cc b/src/mds/Server.cc index b0113d73fb50f..b526754b1d162 100644 --- a/src/mds/Server.cc +++ b/src/mds/Server.cc @@ -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; diff --git a/src/mds/journal.cc b/src/mds/journal.cc index 0c211ee39fe3e..729d394bd9ed2 100644 --- a/src/mds/journal.cc +++ b/src/mds/journal.cc @@ -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; -- 2.39.5