diff --git a/src/mds/MDBalancer.cc b/src/mds/MDBalancer.cc index 6a8199aa90f..090f71e63bb 100644 --- a/src/mds/MDBalancer.cc +++ b/src/mds/MDBalancer.cc @@ -1271,6 +1271,36 @@ void MDBalancer::add_import(CDir *dir, utime_t now) } } +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) { diff --git a/src/mds/MDBalancer.h b/src/mds/MDBalancer.h index 7254dee2f9d..0f802b79a6b 100644 --- a/src/mds/MDBalancer.h +++ b/src/mds/MDBalancer.h @@ -51,6 +51,7 @@ public: 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); diff --git a/src/mds/MDCache.cc b/src/mds/MDCache.cc index 9caf909c00e..b58e394c612 100644 --- a/src/mds/MDCache.cc +++ b/src/mds/MDCache.cc @@ -809,7 +809,7 @@ void MDCache::list_subtrees(list& ls) * 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; @@ -864,7 +864,7 @@ void MDCache::adjust_subtree_auth(CDir *dir, mds_authority_t auth) 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) { @@ -909,7 +909,7 @@ public: } }; -void MDCache::try_subtree_merge_at(CDir *dir, set *to_eval) +void MDCache::try_subtree_merge_at(CDir *dir, set *to_eval, bool adjust_pop) { dout(10) << "try_subtree_merge_at " << *dir << dendl; @@ -941,7 +941,7 @@ void MDCache::try_subtree_merge_at(CDir *dir, set *to_eval) 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) { @@ -1325,6 +1325,7 @@ void MDCache::adjust_subtree_after_rename(CInode *diri, CDir *olddir, bool pop) dout(10) << "adjust_subtree_after_rename " << *diri << " from " << *olddir << dendl; //show_subtrees(); + utime_t now = ceph_clock_now(); CDir *newdir = diri->get_parent_dir(); @@ -1353,12 +1354,12 @@ void MDCache::adjust_subtree_after_rename(CInode *diri, CDir *olddir, bool pop) 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)); @@ -1366,7 +1367,7 @@ void MDCache::adjust_subtree_after_rename(CInode *diri, CDir *olddir, bool pop) 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. @@ -1391,11 +1392,14 @@ void MDCache::adjust_subtree_after_rename(CInode *diri, CDir *olddir, bool pop) // 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(); diff --git a/src/mds/MDCache.h b/src/mds/MDCache.h index 119b38f5a51..e8d38fcd95c 100644 --- a/src/mds/MDCache.h +++ b/src/mds/MDCache.h @@ -315,7 +315,7 @@ protected: public: bool is_subtrees() { return !subtrees.empty(); } void list_subtrees(list& 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)); } @@ -329,7 +329,7 @@ public: } void map_dirfrag_set(list& dfs, set& result); void try_subtree_merge(CDir *root); - void try_subtree_merge_at(CDir *root, set *to_eval); + void try_subtree_merge_at(CDir *root, set *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);