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>
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();
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();
}
}
}
// 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();
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);
}
}
+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);
#define dout_context g_ceph_context
class Context;
-class CDentry;
class CDir;
class CInode;
class MDCache;
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);
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;
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);
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;
void MDBalancer::find_exports(CDir *dir,
double amount,
- list<CDir*>& exports,
+ std::vector<CDir*>* exports,
double& have,
set<CDir*>& already_exporting)
{
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();
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) {
// lucky find?
if (pop > needmin && pop < needmax) {
- exports.push_back(subdir);
+ exports->push_back(subdir);
already_exporting.insert(subdir);
have += pop;
return;
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)
++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)
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 {
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);
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);
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);
} 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);
}
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?
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);
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);
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) {
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;
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;
}
}
- 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();
}
}
// 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);
+ }
+ }
}
}
}
{
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
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);
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);
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;
}
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;
// 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();
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);
}
dout(10) << "subtree " << *dir << dendl;
// auth items in this subtree
- list<CDir*> dq;
+ std::deque<CDir*> dq;
dq.push_back(dir);
while (!dq.empty()) {
}
// subdirs in this subtree?
- in->get_nested_dirfrags(dq);
+ {
+ auto&& dirs = in->get_nested_dirfrags();
+ for (const auto& dir : dirs) {
+ dq.push_back(dir);
+ }
+ }
}
}
}
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;
// 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);
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);
}
// 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
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);
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
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;
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) {
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) {
{
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;
}
// root frags
- list<CDir*> basefrags;
+ std::vector<CDir*> basefrags;
for (set<CInode*>::iterator p = base_inodes.begin();
p != base_inodes.end();
++p)
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;
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;
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;
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();
// 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.
// 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.
// 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) {
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();
}
}
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) {
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;
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
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();
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;
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();
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
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();
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);
+ }
+ }
}
}
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();
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);
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) {
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());
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()) {
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()) {
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) {
// 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());
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);
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) {
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());
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)) {