void MDCache::map_dirfrag_set(list<dirfrag_t>& dfs, set<CDir*>& result)
{
+ dout(10) << "map_dirfrag_set " << dfs << dendl;
+
// group by inode
map<inodeno_t, fragset_t> ino_fragset;
for (list<dirfrag_t>::iterator p = dfs.begin(); p != dfs.end(); ++p)
p != ino_fragset.end();
++p) {
CInode *in = get_inode(p->first);
- if (!in) continue;
+ if (!in)
+ continue;
list<frag_t> fglist;
for (set<frag_t>::iterator q = p->second.begin(); q != p->second.end(); ++q)
for (list<frag_t>::iterator q = fglist.begin(); q != fglist.end(); ++q) {
CDir *dir = in->get_dirfrag(*q);
- if (dir) result.insert(dir);
+ if (dir)
+ result.insert(dir);
}
}
}
// adjust auth away
mds->mdcache->adjust_bounded_subtree_auth(dir, realbounds, pair<int,int>(CDIR_AUTH_UNKNOWN, CDIR_AUTH_UNKNOWN));
- mds->mdcache->trim_non_auth_subtree(dir);
- mds->mdcache->try_subtree_merge(dir);
+
+ // can we now trim child subtrees?
+ set<CDir*> bounds;
+ mds->mdcache->get_subtree_bounds(dir, bounds);
+ for (set<CDir*>::iterator p = bounds.begin(); p != bounds.end(); p++) {
+ CDir *bd = *p;
+ if (bd->get_dir_auth().first != mds->whoami && // we are not auth
+ bd->get_num_any() == 0) { // and empty
+ CInode *bi = bd->get_inode();
+ dout(10) << "EExport.replay " << base << " closing empty non-auth child subtree " << *bd << dendl;
+ mds->mdcache->remove_subtree(bd);
+ bd->mark_clean();
+ bi->close_dirfrag(bd->get_frag());
+ }
+ }
+
+ if (mds->mdcache->trim_non_auth_subtree(dir)) {
+ // keep
+ mds->mdcache->try_subtree_merge(dir);
+ } else {
+ // can we trim this subtree (and possibly our ancestors) too?
+ CInode *diri = dir->get_inode();
+ while (!diri->is_base()) {
+ dir = mds->mdcache->get_subtree_root(diri->get_parent_dir());
+ if (dir->get_dir_auth().first == mds->whoami)
+ break; // we are auth, keep.
+ dout(10) << "EExport.replay " << base << " parent subtree also non-auth: " << *dir << dendl;
+ if (mds->mdcache->trim_non_auth_subtree(dir))
+ break;
+ dout(10) << "EExport.replay " << base << " closing empty parent subtree " << *dir << dendl;
+ mds->mdcache->remove_subtree(dir);
+ dir->mark_clean();
+ diri = dir->get_inode();
+ diri->close_dirfrag(dir->get_frag());
+ }
+ }
}