}
}
+void MDBalancer::adjust_pop_for_rename(CDir *pdir, CDir *dir, utime_t now, bool inc)
+{
+ DecayRate& rate = mds->mdcache->decayrate;
+
+ bool adjust_subtree_nest = dir->is_auth();
+ bool adjust_subtree = adjust_subtree_nest && !dir->is_subtree_root();
+ while (true) {
+ if (inc) {
+ pdir->pop_nested.add(now, rate, dir->pop_nested);
+ if (adjust_subtree)
+ pdir->pop_auth_subtree.add(now, rate, dir->pop_auth_subtree);
+
+ if (adjust_subtree_nest)
+ pdir->pop_auth_subtree_nested.add(now, rate, dir->pop_auth_subtree_nested);
+ } else {
+ pdir->pop_nested.sub(now, rate, dir->pop_nested);
+ if (adjust_subtree)
+ pdir->pop_auth_subtree.sub(now, rate, dir->pop_auth_subtree);
+
+ if (adjust_subtree_nest)
+ pdir->pop_auth_subtree_nested.sub(now, rate, dir->pop_auth_subtree_nested);
+ }
+
+ if (pdir->is_subtree_root())
+ adjust_subtree = false;
+ pdir = pdir->inode->get_parent_dir();
+ if (!pdir) break;
+ }
+}
+
void MDBalancer::handle_mds_failure(mds_rank_t who)
{
if (0 == who) {
void subtract_export(CDir *ex, utime_t now);
void add_import(CDir *im, utime_t now);
+ void adjust_pop_for_rename(CDir *pdir, CDir *dir, utime_t now, bool inc);
void hit_inode(utime_t now, CInode *in, int type, int who=-1);
void hit_dir(utime_t now, CDir *dir, int type, int who=-1, double amount=1.0);
* merge with parent and/or child subtrees, if is it appropriate.
* merge can ONLY happen if both parent and child have unambiguous auth.
*/
-void MDCache::adjust_subtree_auth(CDir *dir, mds_authority_t auth)
+void MDCache::adjust_subtree_auth(CDir *dir, mds_authority_t auth, bool adjust_pop)
{
dout(7) << "adjust_subtree_auth " << dir->get_dir_auth() << " -> " << auth
<< " on " << *dir << dendl;
root = dir;
// adjust recursive pop counters
- if (dir->is_auth()) {
+ if (adjust_pop && dir->is_auth()) {
utime_t now = ceph_clock_now();
CDir *p = dir->get_parent_dir();
while (p) {
}
};
-void MDCache::try_subtree_merge_at(CDir *dir, set<CInode*> *to_eval)
+void MDCache::try_subtree_merge_at(CDir *dir, set<CInode*> *to_eval, bool adjust_pop)
{
dout(10) << "try_subtree_merge_at " << *dir << dendl;
subtrees[parent].erase(dir);
// adjust popularity?
- if (dir->is_auth()) {
+ if (adjust_pop && dir->is_auth()) {
utime_t now = ceph_clock_now();
CDir *p = dir->get_parent_dir();
while (p) {
dout(10) << "adjust_subtree_after_rename " << *diri << " from " << *olddir << dendl;
//show_subtrees();
+ utime_t now = ceph_clock_now();
CDir *newdir = diri->get_parent_dir();
CDir *newparent = get_subtree_root(newdir);
dout(10) << " new parent " << *newparent << dendl;
+ if (olddir != newdir)
+ mds->balancer->adjust_pop_for_rename(olddir, dir, now, false);
+
if (oldparent == newparent) {
dout(10) << "parent unchanged for " << *dir << " at " << *oldparent << dendl;
- continue;
- }
-
- if (dir->is_subtree_root()) {
+ } else if (dir->is_subtree_root()) {
// children are fine. change parent.
dout(10) << "moving " << *dir << " from " << *oldparent << " to " << *newparent << dendl;
assert(subtrees[oldparent].count(dir));
assert(subtrees.count(newparent));
subtrees[newparent].insert(dir);
// caller is responsible for 'eval diri'
- try_subtree_merge_at(dir, NULL);
+ try_subtree_merge_at(dir, NULL, false);
} else {
// mid-subtree.
// did auth change?
if (oldparent->authority() != newparent->authority()) {
- adjust_subtree_auth(dir, oldparent->authority());
+ adjust_subtree_auth(dir, oldparent->authority(), false);
// caller is responsible for 'eval diri'
- try_subtree_merge_at(dir, NULL);
+ try_subtree_merge_at(dir, NULL, false);
}
}
+
+ if (olddir != newdir)
+ mds->balancer->adjust_pop_for_rename(newdir, dir, now, true);
}
show_subtrees();
public:
bool is_subtrees() { return !subtrees.empty(); }
void list_subtrees(list<CDir*>& ls);
- void adjust_subtree_auth(CDir *root, mds_authority_t auth);
+ void adjust_subtree_auth(CDir *root, mds_authority_t auth, bool adjust_pop=true);
void adjust_subtree_auth(CDir *root, mds_rank_t a, mds_rank_t b=CDIR_AUTH_UNKNOWN) {
adjust_subtree_auth(root, mds_authority_t(a,b));
}
}
void map_dirfrag_set(list<dirfrag_t>& dfs, set<CDir*>& result);
void try_subtree_merge(CDir *root);
- void try_subtree_merge_at(CDir *root, set<CInode*> *to_eval);
+ void try_subtree_merge_at(CDir *root, set<CInode*> *to_eval, bool adjust_pop=true);
void subtree_merge_writebehind_finish(CInode *in, MutationRef& mut);
void eval_subtree_root(CInode *diri);
CDir *get_subtree_root(CDir *dir);