]> git.apps.os.sepia.ceph.com Git - ceph-ci.git/commitdiff
mds: convert get_*dirfrags to use vector
authorPatrick Donnelly <pdonnell@redhat.com>
Sat, 9 Mar 2019 20:09:46 +0000 (12:09 -0800)
committerPatrick Donnelly <pdonnell@redhat.com>
Fri, 15 Mar 2019 21:33:08 +0000 (14:33 -0700)
The idea of this change is to use a more allocation efficient structure.

For reasons I don't understand, this patch caused CInode::get_nested_dirfrags
and CInode::get_subtree_dirfrags to fail to compile when in-lined in the
header. The problem was that the inlined methods tried to access the CDir
internals when CDir is an incomplete types. What confuses me is that those
inlined methods ever compiled. In any case, I have moved the methods to the
CInode.cc source to avoid the issue.

Signed-off-by: Patrick Donnelly <pdonnell@redhat.com>
src/mds/CDir.cc
src/mds/CInode.cc
src/mds/CInode.h
src/mds/MDBalancer.cc
src/mds/MDBalancer.h
src/mds/MDCache.cc
src/mds/MDSRank.cc
src/mds/Migrator.cc
src/mds/OpenFileTable.cc
src/mds/Server.cc
src/mds/journal.cc

index d3461fba2e0707e84bf580c356a6a74432dd6e06..9ff132caa9ac04eec6379708c68979a546c4afc3 100644 (file)
@@ -2830,11 +2830,9 @@ void CDir::verify_fragstat()
 
 void CDir::_walk_tree(std::function<bool(CDir*)> callback)
 {
-
   deque<CDir*> dfq;
   dfq.push_back(this);
 
-  vector<CDir*> dfv;
   while (!dfq.empty()) {
     CDir *dir = dfq.front();
     dfq.pop_front();
@@ -2847,13 +2845,12 @@ void CDir::_walk_tree(std::function<bool(CDir*)> callback)
       if (!in->is_dir())
        continue;
 
-      in->get_nested_dirfrags(dfv);
+      auto&& dfv = in->get_nested_dirfrags();
       for (auto& dir : dfv) {
        auto ret = callback(dir);
        if (ret)
          dfq.push_back(dir);
       }
-      dfv.clear();
     }
   }
 }
index d24ff0b80e6894dbc23a9cc9612a0f85fcc382dd..1636e6c91be83a5fe5e3f63a04ad6fda96ff32e0 100644 (file)
@@ -1560,8 +1560,7 @@ void CInode::encode_lock_state(int type, bufferlist& bl)
 
       // also specify which frags are mine
       set<frag_t> myfrags;
-      list<CDir*> dfls;
-      get_dirfrags(dfls);
+      auto&& dfls = get_dirfrags();
       for (const auto& dir : dfls) {
        if (dir->is_auth()) {
          frag_t fg = dir->get_frag();
@@ -4624,8 +4623,7 @@ void CInode::dump(Formatter *f, int flags) const
 
   if (flags & DUMP_DIRFRAGS) {
     f->open_array_section("dirfrags");
-    list<CDir*> dfs;
-    get_dirfrags(dfs);
+    auto&& dfs = get_dirfrags();
     for(const auto &dir: dfs) {
       f->open_object_section("dir");
       dir->dump(f, CDir::DUMP_DEFAULT | CDir::DUMP_ITEMS);
@@ -4924,4 +4922,22 @@ bool CInode::is_exportable(mds_rank_t dest) const
   }
 }
 
+void CInode::get_nested_dirfrags(std::vector<CDir*>& v) const
+{
+  for (const auto &p : dirfrags) {
+    const auto& dir = p.second;
+    if (!dir->is_subtree_root())
+      v.push_back(dir);
+  }
+}
+
+void CInode::get_subtree_dirfrags(std::vector<CDir*>& v) const
+{
+  for (const auto &p : dirfrags) {
+    const auto& dir = p.second;
+    if (dir->is_subtree_root())
+      v.push_back(dir);
+  }
+}
+
 MEMPOOL_DEFINE_OBJECT_FACTORY(CInode, co_inode, mds_co);
index 54cbe46535fad221ef3685e14cdb80799f44553f..ca3d105066609a08d513ff67c4472a247a7c044a 100644 (file)
@@ -46,7 +46,6 @@
 #define dout_context g_ceph_context
 
 class Context;
-class CDentry;
 class CDir;
 class CInode;
 class MDCache;
@@ -571,27 +570,24 @@ public:
     for (const auto &p : dirfrags)
       ls.push_back(p.second);
   }
-  template<typename Container>
-  void get_nested_dirfrags(Container& ls) const {
-    // dirfrags in same subtree
-    if constexpr (std::is_same_v<Container, std::vector<CDir*>>)
-      ls.reserve(ls.size() + dirfrags.size() - num_subtree_roots);
-    for (const auto &p : dirfrags) {
-      typename Container::value_type dir = p.second;
-      if (!dir->is_subtree_root())
-        ls.push_back(dir);
-    }
+
+  auto get_dirfrags() const {
+    std::vector<CDir*> result;
+    get_dirfrags(result);
+    return result;
   }
-  template<typename Container>
-  void get_subtree_dirfrags(Container& ls) {
-    // dirfrags that are roots of new subtrees
-    if constexpr (std::is_same_v<Container, std::vector<CDir*>>)
-      ls.reserve(ls.size() + num_subtree_roots);
-    for (const auto &p : dirfrags) {
-      typename Container::value_type dir = p.second;
-      if (dir->is_subtree_root())
-        ls.push_back(dir);
-    }
+
+  void get_nested_dirfrags(std::vector<CDir*>&) const;
+  std::vector<CDir*> get_nested_dirfrags() const {
+    std::vector<CDir*> v;
+    get_nested_dirfrags(v);
+    return v;
+  }
+  void get_subtree_dirfrags(std::vector<CDir*>&) const;
+  std::vector<CDir*> get_subtree_dirfrags() const {
+    std::vector<CDir*> v;
+    get_subtree_dirfrags(v);
+    return v;
   }
 
   CDir *get_or_open_dirfrag(MDCache *mdcache, frag_t fg);
index aed00b4c36f680ec09320e9e1fb07f6100ce9ea3..d4a28e2e8ac377fe7792db551d7d3a7e18663fbf 100644 (file)
@@ -104,8 +104,7 @@ void MDBalancer::handle_export_pins(void)
     mds_rank_t export_pin = in->get_export_pin(false);
 
     bool remove = true;
-    list<CDir*> dfls;
-    in->get_dirfrags(dfls);
+    auto&& dfls = in->get_dirfrags();
     for (auto dir : dfls) {
       if (!dir->is_auth())
        continue;
@@ -230,8 +229,7 @@ mds_load_t MDBalancer::get_load()
   mds_load_t load{DecayRate()}; /* zero DecayRate! */
 
   if (mds->mdcache->get_root()) {
-    list<CDir*> ls;
-    mds->mdcache->get_root()->get_dirfrags(ls);
+    auto&& ls = mds->mdcache->get_root()->get_dirfrags();
     for (auto &d : ls) {
       load.auth.add(d->pop_auth_subtree_nested);
       load.all.add(d->pop_nested);
@@ -963,19 +961,19 @@ void MDBalancer::try_rebalance(balance_state_t& state)
       continue;
 
     // okay, search for fragments of my workload
-    list<CDir*> exports;
+    std::vector<CDir*> exports;
 
     for (auto p = import_pop_map.rbegin();
         p != import_pop_map.rend();
         ++p) {
       CDir *dir = p->second;
-      find_exports(dir, amount, exports, have, already_exporting);
+      find_exports(dir, amount, &exports, have, already_exporting);
       if (amount-have < MIN_OFFLOAD)
        break;
     }
     //fudge = amount - have;
 
-    for (auto dir : exports) {
+    for (const auto& dir : exports) {
       dout(5) << "   - exporting " << dir->pop_auth_subtree
              << " " << dir->pop_auth_subtree.meta_load()
              << " to mds." << target << " " << *dir << dendl;
@@ -989,7 +987,7 @@ void MDBalancer::try_rebalance(balance_state_t& state)
 
 void MDBalancer::find_exports(CDir *dir,
                               double amount,
-                              list<CDir*>& exports,
+                              std::vector<CDir*>* exports,
                               double& have,
                               set<CDir*>& already_exporting)
 {
@@ -1012,7 +1010,7 @@ void MDBalancer::find_exports(CDir *dir,
   double midchunk = need * g_conf()->mds_bal_midchunk;
   double minchunk = need * g_conf()->mds_bal_minchunk;
 
-  list<CDir*> bigger_rep, bigger_unrep;
+  std::vector<CDir*> bigger_rep, bigger_unrep;
   multimap<double, CDir*> smaller;
 
   double dir_pop = dir->pop_auth_subtree.meta_load();
@@ -1027,8 +1025,7 @@ void MDBalancer::find_exports(CDir *dir,
     ceph_assert(in->is_dir());
     ceph_assert(in->get_parent_dir() == dir);
 
-    list<CDir*> dfls;
-    in->get_nested_dirfrags(dfls);
+    auto&& dfls = in->get_nested_dirfrags();
 
     size_t num_idle_frags = 0;
     for (const auto& subdir : dfls) {
@@ -1053,7 +1050,7 @@ void MDBalancer::find_exports(CDir *dir,
 
       // lucky find?
       if (pop > needmin && pop < needmax) {
-       exports.push_back(subdir);
+       exports->push_back(subdir);
        already_exporting.insert(subdir);
        have += pop;
        return;
@@ -1083,7 +1080,7 @@ void MDBalancer::find_exports(CDir *dir,
 
     dout(7) << "   taking smaller " << *(*it).second << dendl;
 
-    exports.push_back((*it).second);
+    exports->push_back((*it).second);
     already_exporting.insert((*it).second);
     have += (*it).first;
     if (have > needmin)
@@ -1104,7 +1101,7 @@ void MDBalancer::find_exports(CDir *dir,
        ++it) {
     dout(7) << "   taking (much) smaller " << it->first << " " << *(*it).second << dendl;
 
-    exports.push_back((*it).second);
+    exports->push_back((*it).second);
     already_exporting.insert((*it).second);
     have += (*it).first;
     if (have > needmin)
@@ -1334,7 +1331,7 @@ void MDBalancer::handle_mds_failure(mds_rank_t who)
 
 int MDBalancer::dump_loads(Formatter *f) const
 {
-  list<CDir*> dfs;
+  std::deque<CDir*> dfs;
   if (mds->mdcache->get_root()) {
     mds->mdcache->get_root()->get_dirfrags(dfs);
   } else {
@@ -1357,9 +1354,8 @@ int MDBalancer::dump_loads(Formatter *f) const
       if (!in || !in->is_dir())
        continue;
 
-      list<CDir*> ls;
-      in->get_dirfrags(ls);
-      for (auto subdir : ls) {
+      auto&& ls = in->get_dirfrags();
+      for (const auto& subdir : ls) {
        if (subdir->pop_nested.meta_load() < .001)
          continue;
        dfs.push_back(subdir);
index 33d8f81d851403b20b308c6784efd524c82a2004..a3f087a70b2f9ff2a1d999983df7ecd5855e09e8 100644 (file)
@@ -102,7 +102,7 @@ private:
   void handle_heartbeat(const MHeartbeat::const_ref &m);
   void find_exports(CDir *dir,
                     double amount,
-                    std::list<CDir*>& exports,
+                    std::vector<CDir*>* exports,
                     double& have,
                     set<CDir*>& already_exporting);
 
index 390a9e53ee85c6ddf3490e7c8226ba0cddfc8f96..bb26263a056a5a53202982a59f56e653e602d378 100644 (file)
@@ -1342,27 +1342,27 @@ void MDCache::adjust_subtree_after_rename(CInode *diri, CDir *olddir, bool pop)
       projected_subtree_renames.erase(p);
   }
 
-  vector<CDir*> dfls;
-
   // adjust total auth pin of freezing subtree
   if (olddir != newdir) {
-    diri->get_nested_dirfrags(dfls);
-    for (auto dir : dfls)
+    auto&& dfls = diri->get_nested_dirfrags();
+    for (const auto& dir : dfls)
       olddir->adjust_freeze_after_rename(dir);
-    dfls.clear();
   }
 
   // adjust subtree
-  // make sure subtree dirfrags are at the front of the list
-  diri->get_subtree_dirfrags(dfls);
+  // N.B. make sure subtree dirfrags are at the front of the list
+  auto dfls = diri->get_subtree_dirfrags();
   diri->get_nested_dirfrags(dfls);
-  for (auto dir : dfls) {
+  for (const auto& dir : dfls) {
     dout(10) << "dirfrag " << *dir << dendl;
     CDir *oldparent = get_subtree_root(olddir);
     dout(10) << " old parent " << *oldparent << dendl;
     CDir *newparent = get_subtree_root(newdir);
     dout(10) << " new parent " << *newparent << dendl;
 
+    auto& oldbounds = subtrees[oldparent];
+    auto& newbounds = subtrees[newparent];
+
     if (olddir != newdir)
       mds->balancer->adjust_pop_for_rename(olddir, dir, false);
 
@@ -1371,21 +1371,19 @@ void MDCache::adjust_subtree_after_rename(CInode *diri, CDir *olddir, bool pop)
     } else if (dir->is_subtree_root()) {
       // children are fine.  change parent.
       dout(10) << "moving " << *dir << " from " << *oldparent << " to " << *newparent << dendl;
-      ceph_assert(subtrees[oldparent].count(dir));
-      subtrees[oldparent].erase(dir);
-      ceph_assert(subtrees.count(newparent));
-      subtrees[newparent].insert(dir);
+      {
+        auto n = oldbounds.erase(dir);
+        ceph_assert(n == 1);
+      }
+      newbounds.insert(dir);
       // caller is responsible for 'eval diri'
       try_subtree_merge_at(dir, NULL, false);
     } else {
       // mid-subtree.
 
       // see if any old bounds move to the new parent.
-      list<CDir*> tomove;
-      for (set<CDir*>::iterator p = subtrees[oldparent].begin();
-          p != subtrees[oldparent].end();
-          ++p) {
-       CDir *bound = *p;
+      std::vector<CDir*> tomove;
+      for (const auto& bound : oldbounds) {
        CDir *broot = get_subtree_root(bound->get_parent_dir());
        if (broot != oldparent) {
          ceph_assert(broot == newparent);
@@ -1394,8 +1392,8 @@ void MDCache::adjust_subtree_after_rename(CInode *diri, CDir *olddir, bool pop)
       }
       for (const auto& bound : tomove) {
        dout(10) << "moving bound " << *bound << " from " << *oldparent << " to " << *newparent << dendl;
-       subtrees[oldparent].erase(bound);
-       subtrees[newparent].insert(bound);
+       oldbounds.erase(bound);
+       newbounds.insert(bound);
       }           
 
       // did auth change?
@@ -2512,8 +2510,7 @@ ESubtreeMap *MDCache::create_subtree_map()
     for (const auto& [olddir, newdir] : renames) {
       dout(10) << " adjusting for projected rename of " << *diri << " to " << *newdir << dendl;
 
-      list<CDir*> dfls;
-      diri->get_dirfrags(dfls);
+      auto&& dfls = diri->get_dirfrags();
       for (const auto& dir : dfls) {
        dout(10) << "dirfrag " << dir->dirfrag() << " " << *dir << dendl;
        CDir *oldparent = get_projected_subtree_root(olddir);
@@ -3060,8 +3057,7 @@ void MDCache::handle_mds_recovery(mds_rank_t who)
          dnl->get_inode()->take_waiting(i_mask, waiters);
          
          // recurse?
-         list<CDir*> ls;
-         dnl->get_inode()->get_dirfrags(ls);
+         auto&& ls = dnl->get_inode()->get_dirfrags();
          for (const auto& subdir : ls) {
            if (!subdir->is_subtree_root())
              q.push_back(subdir);
@@ -3429,8 +3425,7 @@ void MDCache::finish_uncommitted_slave_update(metareqid_t reqid, mds_rank_t mast
     it->second--;
     if (it->second == 0) {
       uncommitted_slave_rename_olddir.erase(it);
-      list<CDir*> ls;
-      diri->get_dirfrags(ls);
+      auto&& ls = diri->get_dirfrags();
       for (const auto& dir : ls) {
        CDir *root = get_subtree_root(dir);
        if (root->get_dir_auth() == CDIR_AUTH_UNDEF) {
@@ -3623,13 +3618,9 @@ void MDCache::finish_ambiguous_import(dirfrag_t df)
 void MDCache::remove_inode_recursive(CInode *in)
 {
   dout(10) << "remove_inode_recursive " << *in << dendl;
-  list<CDir*> ls;
-  in->get_dirfrags(ls);
-  list<CDir*>::iterator p = ls.begin();
-  while (p != ls.end()) {
-    CDir *subdir = *p++;
-
-    dout(10) << " removing dirfrag " << subdir << dendl;
+  auto&& ls = in->get_dirfrags();
+  for (const auto& subdir : ls) {
+    dout(10) << " removing dirfrag " << *subdir << dendl;
     auto it = subdir->items.begin();
     while (it != subdir->items.end()) {
       CDentry *dn = it->second;
@@ -3657,9 +3648,8 @@ bool MDCache::expire_recursive(CInode *in, expiremap &expiremap)
   dout(10) << __func__ << ":" << *in << dendl;
 
   // Recurse into any dirfrags beneath this inode
-  list<CDir*> ls;
-  in->get_dirfrags(ls);
-  for (auto subdir : ls) {
+  auto&& ls = in->get_dirfrags();
+  for (const auto& subdir : ls) {
     if (!in->is_mdsdir() && subdir->is_subtree_root()) {
       dout(10) << __func__ << ": stray still has subtree " << *in << dendl;
       return true;
@@ -3755,7 +3745,7 @@ void MDCache::recalc_auth_bits(bool replay)
       }
     }
 
-    list<CDir*> dfq;  // dirfrag queue
+    std::deque<CDir*> dfq;  // dirfrag queue
     dfq.push_back(p->first);
 
     bool auth = p->first->authority().first == mds->get_nodeid();
@@ -3818,8 +3808,12 @@ void MDCache::recalc_auth_bits(bool replay)
            }
          }
          // recurse?
-         if (in->is_dir())
-           in->get_nested_dirfrags(dfq);
+         if (in->is_dir()) {
+           auto&& dfv = in->get_nested_dirfrags();
+            for (const auto& dir : dfv) {
+              dfq.push_back(dir);
+            }
+          }
        }
       }
     }
@@ -4147,7 +4141,7 @@ void MDCache::rejoin_walk(CDir *dir, const MMDSCacheRejoin::ref &rejoin)
 {
   dout(10) << "rejoin_walk " << *dir << dendl;
 
-  list<CDir*> nested;  // finish this dir, then do nested items
+  std::vector<CDir*> nested;  // finish this dir, then do nested items
   
   if (mds->is_rejoin()) {
     // WEAK
@@ -4161,7 +4155,10 @@ void MDCache::rejoin_walk(CDir *dir, const MMDSCacheRejoin::ref &rejoin)
       CInode *in = dnl->get_inode();
       ceph_assert(dnl->get_inode()->is_dir());
       rejoin->add_weak_primary_dentry(dir->ino(), dn->get_name(), dn->first, dn->last, in->ino());
-      in->get_nested_dirfrags(nested);
+      {
+        auto&& dirs = in->get_nested_dirfrags();
+        nested.insert(std::end(nested), std::begin(dirs), std::end(dirs));
+      }
       if (in->is_dirty_scattered()) {
        dout(10) << " sending scatterlock state on " << *in << dendl;
        rejoin->add_scatterlock_state(in);
@@ -4223,7 +4220,10 @@ void MDCache::rejoin_walk(CDir *dir, const MMDSCacheRejoin::ref &rejoin)
                                 in->nestlock.get_state(),
                                 in->dirfragtreelock.get_state());
        in->state_set(CInode::STATE_REJOINING);
-       in->get_nested_dirfrags(nested);
+        {
+          auto&& dirs = in->get_nested_dirfrags();
+          nested.insert(std::end(nested), std::begin(dirs), std::end(dirs));
+        }
        if (in->is_dirty_scattered()) {
          dout(10) << " sending scatterlock state on " << *in << dendl;
          rejoin->add_scatterlock_state(in);
@@ -4525,8 +4525,7 @@ void MDCache::rejoin_scour_survivor_replicas(mds_rank_t from, const MMDSCacheRej
     if (!in->is_dir())
       return;
     
-    list<CDir*> dfs;
-    in->get_dirfrags(dfs);
+    const auto&& dfs = in->get_dirfrags();
     for (const auto& dir : dfs) {
       if (!dir->is_auth())
        continue;
@@ -4982,8 +4981,7 @@ void MDCache::handle_cache_rejoin_ack(const MMDSCacheRejoin::const_ref &ack)
   }
 
   for (const auto& in : refragged_inodes) {
-    list<CDir*> ls;
-    in->get_nested_dirfrags(ls);
+    auto&& ls = in->get_nested_dirfrags();
     for (const auto& dir : ls) {
       if (dir->is_auth() || ack->strong_dirfrags.count(dir->dirfrag()))
        continue;
@@ -5149,8 +5147,7 @@ void MDCache::rejoin_trim_undef_inodes()
     
     // close out dirfrags
     if (in->is_dir()) {
-      list<CDir*> dfls;
-      in->get_dirfrags(dfls);
+      const auto&& dfls = in->get_dirfrags();
       for (const auto& dir : dfls) {
        dir->clear_replica_map();
 
@@ -5917,8 +5914,7 @@ void MDCache::opened_undef_inode(CInode *in) {
       ceph_assert(dir);
       rejoin_undef_dirfrags.erase(dir);
       in->force_dirfrags();
-      list<CDir*> ls;
-      in->get_dirfrags(ls);
+      auto&& ls = in->get_dirfrags();
       for (const auto& dir : ls) {
        rejoin_undef_dirfrags.insert(dir);
       }
@@ -6003,7 +5999,7 @@ void MDCache::rejoin_send_acks()
     dout(10) << "subtree " << *dir << dendl;
     
     // auth items in this subtree
-    list<CDir*> dq;
+    std::deque<CDir*> dq;
     dq.push_back(dir);
 
     while (!dq.empty()) {
@@ -6058,7 +6054,12 @@ void MDCache::rejoin_send_acks()
        }
        
        // subdirs in this subtree?
-       in->get_nested_dirfrags(dq);
+       {
+          auto&& dirs = in->get_nested_dirfrags();
+          for (const auto& dir : dirs) {
+            dq.push_back(dir);
+          }
+        }
       }
     }
   }
@@ -6586,8 +6587,7 @@ std::pair<bool, uint64_t> MDCache::trim(uint64_t count)
       if (!diri->is_auth()) {
        if (dir->get_num_ref() > 1)  // only subtree pin
          continue;
-       list<CDir*> ls;
-       diri->get_subtree_dirfrags(ls);
+       auto&& ls = diri->get_subtree_dirfrags();
        if (diri->get_num_ref() > (int)ls.size()) // only pinned by subtrees
          continue;
 
@@ -6604,8 +6604,7 @@ std::pair<bool, uint64_t> MDCache::trim(uint64_t count)
 
   // trim root?
   if (mds->is_stopping() && root) {
-    list<CDir*> ls;
-    root->get_dirfrags(ls);
+    auto&& ls = root->get_dirfrags();
     for (const auto& dir : ls) {
       if (dir->get_num_ref() == 1) { // subtree pin
        trim_dirfrag(dir, 0, expiremap);
@@ -6636,8 +6635,7 @@ std::pair<bool, uint64_t> MDCache::trim(uint64_t count)
     const bool aborted = expire_recursive(mdsdir_in, expiremap);
     if (!aborted) {
       dout(20) << __func__ << ": successfully expired mdsdir" << dendl;
-      list<CDir*> ls;
-      mdsdir_in->get_dirfrags(ls);
+      auto&& ls = mdsdir_in->get_dirfrags();
       for (auto dir : ls) {
        if (dir->get_num_ref() == 1) {  // subtree pin
          trim_dirfrag(dir, dir, expiremap);
@@ -6845,8 +6843,7 @@ bool MDCache::trim_inode(CDentry *dn, CInode *in, CDir *con, expiremap& expirema
     }
 
     // DIR
-    list<CDir*> dfls;
-    in->get_dirfrags(dfls);
+    auto&& dfls = in->get_dirfrags();
     for (const auto& dir : dfls) {
       ceph_assert(!dir->is_subtree_root());
       trim_dirfrag(dir, con ? con:dir, expiremap);  // if no container (e.g. root dirfrag), use *p
@@ -6965,8 +6962,7 @@ void MDCache::trim_non_auth()
       else if (dnl->is_primary()) {
        CInode *in = dnl->get_inode();
        dout(10) << " removing " << *in << dendl;
-       list<CDir*> ls;
-       in->get_dirfrags(ls);
+       auto&& ls = in->get_dirfrags();
        for (const auto& subdir : ls) {
          ceph_assert(!subdir->is_subtree_root());
          in->close_dirfrag(subdir->dirfrag().frag);
@@ -7012,8 +7008,7 @@ void MDCache::trim_non_auth()
       CInode *in = p->second;
       ++p;
       if (!in->is_auth()) {
-       list<CDir*> ls;
-       in->get_dirfrags(ls);
+       auto&& ls = in->get_dirfrags();
        for (const auto& dir : ls) {
          dout(10) << " removing " << *dir << dendl;
          ceph_assert(dir->get_num_ref() == 1);  // SUBTREE
@@ -7055,8 +7050,7 @@ bool MDCache::trim_non_auth_subtree(CDir *dir)
       CInode *in = dnl->get_inode();
       bool keep_inode = false;
       if (in->is_dir()) {
-        list<CDir*> subdirs;
-        in->get_dirfrags(subdirs);
+        auto&& subdirs = in->get_dirfrags();
         for (const auto& subdir : subdirs) {
           if (subdir->is_subtree_root()) {
             keep_inode = true;
@@ -7301,8 +7295,7 @@ void MDCache::handle_cache_expire(const MCacheExpire::const_ref &m)
          if (mds->is_rejoin() &&
              rejoin_ack_gather.count(mds->get_nodeid()) && // haven't sent rejoin ack yet
              !diri->is_replica(from)) {
-           list<CDir*> ls;
-           diri->get_nested_dirfrags(ls);
+           auto&& ls = diri->get_nested_dirfrags();
            dout(7) << " dir expire on dirfrag " << q.first << " from mds." << from
                    << " while rejoining, inode isn't replicated" << dendl;
            for (const auto& d : ls) {
@@ -7597,7 +7590,7 @@ bool MDCache::shutdown_pass()
   if (!subtrees.empty() &&
       mds->get_nodeid() != 0) {
     dout(7) << "looking for subtrees to export to mds0" << dendl;
-    list<CDir*> ls;
+    std::vector<CDir*> ls;
     for (map<CDir*, set<CDir*> >::iterator it = subtrees.begin();
          it != subtrees.end();
          ++it) {
@@ -9658,7 +9651,7 @@ void MDCache::scan_stray_dir(dirfrag_t next)
 {
   dout(10) << "scan_stray_dir " << next << dendl;
 
-  list<CDir*> ls;
+  std::vector<CDir*> ls;
   for (int i = 0; i < NUM_STRAY; ++i) {
     if (strays[i]->ino() < next.ino)
       continue;
@@ -11930,7 +11923,7 @@ void MDCache::show_subtrees(int dbl)
   }
 
   // root frags
-  list<CDir*> basefrags;
+  std::vector<CDir*> basefrags;
   for (set<CInode*>::iterator p = base_inodes.begin();
        p != base_inodes.end();
        ++p) 
@@ -12063,8 +12056,7 @@ void MDCache::show_cache()
       dout(7) << " unlinked " << *in << dendl;
 
     // dirfrags?
-    list<CDir*> dfs;
-    in->get_dirfrags(dfs);
+    auto&& dfs = in->get_dirfrags();
     for (const auto& dir : dfs) {
       dout(7) << "  dirfrag " << *dir << dendl;
 
@@ -12101,8 +12093,7 @@ void MDCache::dump_tree(CInode *in, const int cur_depth, const int max_depth, Fo
   if ((max_depth >= 0) && (cur_depth > max_depth)) {
     return;
   }
-  list<CDir*> ls;
-  in->get_dirfrags(ls);
+  auto&& ls = in->get_dirfrags();
   for (const auto &subdir : ls) {
     for (const auto &p : subdir->items) {
       CDentry *dn = p.second;
@@ -12195,8 +12186,7 @@ int MDCache::dump_cache(std::string_view fn, Formatter *f)
     r = safe_write(fd, s.c_str(), s.length());
     if (r < 0)
       return r;
-    list<CDir*> dfs;
-    in->get_dirfrags(dfs);
+    auto&& dfs = in->get_dirfrags();
     for (auto &dir : dfs) {
       ostringstream tt;
       tt << " " << *dir << std::endl;
@@ -12823,8 +12813,7 @@ void MDCache::maybe_eval_stray(CInode *in, bool delay) {
 void MDCache::clear_dirty_bits_for_stray(CInode* diri) {
   dout(10) << __func__ << " " << *diri << dendl;
   ceph_assert(diri->get_projected_parent_dir()->inode->is_stray());
-  list<CDir*> ls;
-  diri->get_dirfrags(ls);
+  auto&& ls = diri->get_dirfrags();
   for (auto &p : ls) {
     if (p->is_auth() && !(p->is_frozen() || p->is_freezing()))
       p->try_remove_dentries_for_stray();
index 8b622cab0f97171faa4c9e80296f7fc673a7b39f..dfa6ce8d19fa59b7cd7dabad440ef37dd8e3b77b 100644 (file)
@@ -1079,14 +1079,9 @@ bool MDSRank::_dispatch(const Message::const_ref &m, bool new_msg)
     // pick a random dir inode
     CInode *in = mdcache->hack_pick_random_inode();
 
-    list<CDir*> ls;
-    in->get_dirfrags(ls);
+    auto&& ls = in->get_dirfrags();
     if (!ls.empty()) { // must be an open dir.
-      list<CDir*>::iterator p = ls.begin();
-      int n = rand() % ls.size();
-      while (n--)
-        ++p;
-      CDir *dir = *p;
+      const auto& dir = ls[rand() % ls.size()];
       if (!dir->get_parent_dir()) continue;    // must be linked.
       if (!dir->is_auth()) continue;           // must be auth.
 
@@ -1109,8 +1104,7 @@ bool MDSRank::_dispatch(const Message::const_ref &m, bool new_msg)
     // pick a random dir inode
     CInode *in = mdcache->hack_pick_random_inode();
 
-    list<CDir*> ls;
-    in->get_dirfrags(ls);
+    auto&& ls = in->get_dirfrags();
     if (ls.empty()) continue;                // must be an open dir.
     CDir *dir = ls.front();
     if (!dir->get_parent_dir()) continue;    // must be linked.
index 6a1a431e1457605cb1fdadd6064fb7d6c16d7b63..2d8de84642fc3ef2b9ffec8b2f09e6af4b1dbd34 100644 (file)
@@ -409,7 +409,7 @@ void Migrator::handle_mds_failure_or_stop(mds_rank_t who)
   // confuse the shit out of us.  we'll remove it after canceling the
   // freeze.  this way no freeze completions run before we want them
   // to.
-  list<CDir*> pinned_dirs;
+  std::vector<CDir*> pinned_dirs;
   for (map<CDir*,export_state_t>::iterator p = export_state.begin();
        p != export_state.end();
        ++p) {
@@ -575,11 +575,9 @@ void Migrator::handle_mds_failure_or_stop(mds_rank_t who)
     q = next;
   }
 
-  while (!pinned_dirs.empty()) {
-    CDir *dir = pinned_dirs.front();
+  for (const auto& dir : pinned_dirs) {
     dout(10) << "removing temp auth_pin on " << *dir << dendl;
     dir->auth_unpin(this);
-    pinned_dirs.pop_front();
   }  
 }
 
@@ -824,14 +822,16 @@ void Migrator::export_dir(CDir *dir, mds_rank_t dest)
 
   if (g_conf()->mds_thrash_exports) {
     // create random subtree bound (which will not be exported)
-    list<CDir*> ls;
+    std::vector<CDir*> ls;
     for (auto p = dir->begin(); p != dir->end(); ++p) {
       auto dn = p->second;
       CDentry::linkage_t *dnl= dn->get_linkage();
       if (dnl->is_primary()) {
        CInode *in = dnl->get_inode();
-       if (in->is_dir())
-         in->get_nested_dirfrags(ls);
+       if (in->is_dir()) {
+          auto&& dirs = in->get_nested_dirfrags();
+          ls.insert(std::end(ls), std::begin(dirs), std::end(dirs));
+        }
       }
     }
     if (ls.size() > 0) {
@@ -925,8 +925,7 @@ void Migrator::maybe_split_export(CDir* dir, uint64_t max_size, bool null_okay,
       dirfrag_size += in->get_client_caps().size() * cap_size;
 
       if (in->is_dir()) {
-       vector<CDir*> ls;
-       in->get_nested_dirfrags(ls);
+       auto ls = in->get_nested_dirfrags();
        std::reverse(ls.begin(), ls.end());
 
        bool complete = true;
@@ -1409,8 +1408,7 @@ void Migrator::get_export_client_set(CDir *dir, set<client_t>& client_set)
       CInode *in = dn->get_linkage()->get_inode();
       if (in->is_dir()) {
        // directory?
-       vector<CDir*> ls;
-       in->get_dirfrags(ls);
+       auto&& ls = in->get_dirfrags();
        for (auto& q : ls) {
          if (!q->state_test(CDir::STATE_EXPORTBOUND)) {
            // include nested dirfrag
@@ -1735,7 +1733,7 @@ uint64_t Migrator::encode_export_dir(bufferlist& exportbl,
   encode(nden, exportbl);
   
   // dentries
-  list<CDir*> subdirs;
+  std::vector<CDir*> subdirs;
   for (auto &p : *dir) {
     CDentry *dn = p.second;
     CInode *in = dn->get_linkage()->get_inode();
@@ -1781,19 +1779,18 @@ uint64_t Migrator::encode_export_dir(bufferlist& exportbl,
     encode_export_inode(in, exportbl, exported_client_map, exported_client_metadata_map);  // encode, and (update state for) export
     
     // directory?
-    list<CDir*> dfs;
-    in->get_dirfrags(dfs);
+    auto&& dfs = in->get_dirfrags();
     for (const auto& t : dfs) {
       if (!t->state_test(CDir::STATE_EXPORTBOUND)) {
        // include nested dirfrag
        ceph_assert(t->get_dir_auth().first == CDIR_AUTH_PARENT);
-       subdirs.push_front(t);  // it's ours, recurse (later)
+       subdirs.push_back(t);  // it's ours, recurse (later)
       }
     }
   }
 
   // subdirs
-  for (auto &dir : subdirs)
+  for (const auto& dir : subdirs)
     num_exported += encode_export_dir(exportbl, dir, exported_client_map, exported_client_metadata_map);
 
   return num_exported;
@@ -1824,7 +1821,7 @@ void Migrator::finish_export_dir(CDir *dir, mds_rank_t peer,
   dir->finish_export();
 
   // dentries
-  list<CDir*> subdirs;
+  std::vector<CDir*> subdirs;
   for (auto &p : *dir) {
     CDentry *dn = p.second;
     CInode *in = dn->get_linkage()->get_inode();
@@ -1837,7 +1834,8 @@ void Migrator::finish_export_dir(CDir *dir, mds_rank_t peer,
       finish_export_inode(in, peer, peer_imported[in->ino()], finished);
 
       // subdirs?
-      in->get_nested_dirfrags(subdirs);
+      auto&& dirs = in->get_nested_dirfrags();
+      subdirs.insert(std::end(subdirs), std::begin(dirs), std::end(dirs));
     }
 
     cache->touch_dentry_bottom(dn); // move dentry to tail of LRU
@@ -1954,7 +1952,7 @@ void Migrator::export_reverse(CDir *dir, export_state_t& stat)
   cache->get_subtree_bounds(dir, bounds);
 
   // remove exporting pins
-  list<CDir*> rq;
+  std::deque<CDir*> rq;
   rq.push_back(dir);
   while (!rq.empty()) {
     CDir *t = rq.front(); 
@@ -1971,8 +1969,12 @@ void Migrator::export_reverse(CDir *dir, export_state_t& stat)
        in->state_clear(CInode::STATE_EVALSTALECAPS);
        to_eval.insert(in);
       }
-      if (in->is_dir())
-       in->get_nested_dirfrags(rq);
+      if (in->is_dir()) {
+        auto&& dirs = in->get_nested_dirfrags();
+        for (const auto& dir : dirs) {
+          rq.push_back(dir);
+        }
+      }
     }
   }
   
@@ -2782,7 +2784,7 @@ void Migrator::import_reverse(CDir *dir)
 
   int num_dentries = 0;
   // adjust auth bits.
-  list<CDir*> q;
+  std::deque<CDir*> q;
   q.push_back(dir);
   while (!q.empty()) {
     CDir *cur = q.front();
@@ -2825,8 +2827,7 @@ void Migrator::import_reverse(CDir *dir)
        in->clear_file_locks();
 
        // non-bounding dir?
-       list<CDir*> dfs;
-       in->get_dirfrags(dfs);
+       auto&& dfs = in->get_dirfrags();
        for (const auto& dir : dfs) {
          if (bounds.count(dir) == 0)
            q.push_back(dir);
index 323069db931973aa567052fdce5fd626103e1da2..868212426dcf03ce5777817748964c913117b3b7 100644 (file)
@@ -1021,7 +1021,7 @@ void OpenFileTable::_prefetch_dirfrags()
   ceph_assert(prefetch_state == DIRFRAGS);
 
   MDCache *mdcache = mds->mdcache;
-  list<CDir*> fetch_queue;
+  std::vector<CDir*> fetch_queue;
 
   CInode *last_in = nullptr;
   for (auto df : loaded_dirfrags) {
@@ -1058,7 +1058,7 @@ void OpenFileTable::_prefetch_dirfrags()
 
   MDSGatherBuilder gather(g_ceph_context);
   int num_opening_dirfrags = 0;
-  for (auto dir : fetch_queue) {
+  for (const auto& dir : fetch_queue) {
     if (dir->state_test(CDir::STATE_REJOINUNDEF))
       ceph_assert(dir->get_inode()->dirfragtree.is_leaf(dir->get_frag()));
     dir->fetch(gather.new_sub());
index c55ce145689c13144a1595f3330ee86a77e2f03d..fd1a2ddc047407c420cd42acc2ed1078ed1dc97c 100644 (file)
@@ -7223,8 +7223,7 @@ bool Server::_dir_is_nonempty_unlocked(MDRequestRef& mdr, CInode *in)
   if (in->snaprealm && in->snaprealm->srnode.snaps.size())
     return true; // in a snapshot!
 
-  list<CDir*> ls;
-  in->get_dirfrags(ls);
+  auto&& ls = in->get_dirfrags();
   for (const auto& dir : ls) {
     // is the frag obviously non-empty?
     if (dir->is_auth()) {
@@ -7248,8 +7247,7 @@ bool Server::_dir_is_nonempty(MDRequestRef& mdr, CInode *in)
   frag_info_t dirstat;
   version_t dirstat_version = in->get_projected_inode()->dirstat.version;
 
-  list<CDir*> ls;
-  in->get_dirfrags(ls);
+  auto&& ls = in->get_dirfrags();
   for (const auto& dir : ls) {
     const fnode_t *pf = dir->get_projected_fnode();
     if (pf->fragstat.size()) {
@@ -7872,8 +7870,7 @@ version_t Server::_rename_prepare_import(MDRequestRef& mdr, CDentry *srcdn, buff
 
 bool Server::_need_force_journal(CInode *diri, bool empty)
 {
-  std::vector<CDir*> dirs;
-  diri->get_dirfrags(dirs);
+  auto&& dirs = diri->get_dirfrags();
 
   bool force_journal = false;
   if (empty) {
@@ -8019,8 +8016,7 @@ void Server::_rename_prepare(MDRequestRef& mdr,
        // note which dirfrags have child subtrees in the journal
        // event, so that we can open those (as bounds) during replay.
        if (srci->is_dir()) {
-         list<CDir*> ls;
-         srci->get_dirfrags(ls);
+         auto&& ls = srci->get_dirfrags();
          for (const auto& dir : ls) {
            if (!dir->is_auth())
              metablob->renamed_dir_frags.push_back(dir->get_frag());
@@ -8197,8 +8193,7 @@ void Server::_rename_prepare(MDRequestRef& mdr,
       metablob->add_primary_dentry(destdn, srci, true);
       if (srcdn->is_auth() && srci->is_dir()) {
        // journal new subtrees root dirfrags
-       list<CDir*> ls;
-       srci->get_dirfrags(ls);
+       auto&& ls = srci->get_dirfrags();
        for (const auto& dir : ls) {
          if (dir->is_auth())
            metablob->add_dir(dir, true);
@@ -8732,7 +8727,7 @@ void Server::_logged_slave_rename(MDRequestRef& mdr,
   if (srcdn->is_auth() && srcdnl->is_primary()) {
     // set export bounds for CInode::encode_export()
     if (reply) {
-      list<CDir*> bounds;
+      std::vector<CDir*> bounds;
       if (srcdnl->get_inode()->is_dir()) {
        srcdnl->get_inode()->get_dirfrags(bounds);
        for (const auto& bound : bounds) {
@@ -9217,8 +9212,7 @@ void Server::do_rename_rollback(bufferlist &rbl, mds_rank_t master, MDRequestRef
     dout(10) << " noting renamed dir ino " << in->ino() << " in metablob" << dendl;
     le->commit.renamed_dirino = in->ino();
     if (srcdn->authority().first == whoami) {
-      list<CDir*> ls;
-      in->get_dirfrags(ls);
+      auto&& ls = in->get_dirfrags();
       for (const auto& dir : ls) {
        if (!dir->is_auth())
          le->commit.renamed_dir_frags.push_back(dir->get_frag());
index 93b5ff20cff19d294a22db2dd06bd331894a339d..60eb0675fa1726cec18774798a5e3a48111a4d1b 100644 (file)
@@ -532,8 +532,7 @@ void EMetaBlob::fullbit::update_inode(MDSRank *mds, CInode *in)
       in->dirfragtree = dirfragtree;
       in->force_dirfrags();
       if (in->has_dirfrags() && in->authority() == CDIR_AUTH_UNDEF) {
-       list<CDir*> ls;
-       in->get_nested_dirfrags(ls);
+       auto&& ls = in->get_nested_dirfrags();
        for (const auto& dir : ls) {
          if (dir->get_num_any() == 0 &&
              mds->mdcache->can_trim_non_auth_dirfrag(dir)) {