From 896491268f90d53775e4a76fb808fa8f65bdb513 Mon Sep 17 00:00:00 2001 From: "Yan, Zheng" Date: Tue, 21 Nov 2017 16:23:20 +0800 Subject: [PATCH] mds: always pass current time to MDBalancer::{hit_inode,hit_dir} There were codes that pass mdr->get_mds_stamp() to {hit_inode,hit_dir}. The stamp can be older than 'last_decay' in decay counters, which can cause DecayCounter::decay() to malfunction. Signed-off-by: "Yan, Zheng" --- src/common/DecayCounter.cc | 30 +++++++++++---------- src/mds/Locker.cc | 4 +++ src/mds/MDBalancer.cc | 4 +-- src/mds/MDBalancer.h | 4 +-- src/mds/Server.cc | 54 ++++++++++++++++++++++++-------------- 5 files changed, 58 insertions(+), 38 deletions(-) diff --git a/src/common/DecayCounter.cc b/src/common/DecayCounter.cc index 139332237f2..1f0f12e85cf 100644 --- a/src/common/DecayCounter.cc +++ b/src/common/DecayCounter.cc @@ -62,21 +62,23 @@ void DecayCounter::generate_test_instances(list& ls) void DecayCounter::decay(utime_t now, const DecayRate &rate) { - utime_t el = now; - el -= last_decay; + if (now >= last_decay) { + double el = (double)(now - last_decay); + if (el >= 1.0) { + // calculate new value + double newval = (val+delta) * exp(el * rate.k); + if (newval < .01) + newval = 0.0; - if (el.sec() >= 1) { - // calculate new value - double newval = (val+delta) * exp((double)el * rate.k); - if (newval < .01) - newval = 0.0; + // calculate velocity approx + vel += (newval - val) * el; + vel *= exp(el * rate.k); - // calculate velocity approx - vel += (newval - val) * (double)el; - vel *= exp((double)el * rate.k); - - val = newval; - delta = 0; - last_decay = now; + val = newval; + delta = 0; + last_decay = now; + } + } else { + last_decay = now; } } diff --git a/src/mds/Locker.cc b/src/mds/Locker.cc index 49687de758a..e2b4f09b33a 100644 --- a/src/mds/Locker.cc +++ b/src/mds/Locker.cc @@ -17,6 +17,7 @@ #include "MDSRank.h" #include "MDCache.h" #include "Locker.h" +#include "MDBalancer.h" #include "CInode.h" #include "CDir.h" #include "CDentry.h" @@ -1898,6 +1899,9 @@ void Locker::file_update_finish(CInode *in, MutationRef& mut, bool share_max, bo } issue_caps_set(need_issue); + utime_t now = ceph_clock_now(); + mds->balancer->hit_inode(now, in, META_POP_IWR); + // auth unpin after issuing caps mut->cleanup(); } diff --git a/src/mds/MDBalancer.cc b/src/mds/MDBalancer.cc index e82a4cf15f2..f16f4442444 100644 --- a/src/mds/MDBalancer.cc +++ b/src/mds/MDBalancer.cc @@ -1079,7 +1079,7 @@ void MDBalancer::find_exports(CDir *dir, } -void MDBalancer::hit_inode(utime_t now, CInode *in, int type, int who) +void MDBalancer::hit_inode(const utime_t& now, CInode *in, int type, int who) { // hit inode in->pop.get(type).hit(now, mds->mdcache->decayrate); @@ -1120,7 +1120,7 @@ void MDBalancer::maybe_fragment(CDir *dir, bool hot) } } -void MDBalancer::hit_dir(utime_t now, CDir *dir, int type, int who, double amount) +void MDBalancer::hit_dir(const utime_t& now, CDir *dir, int type, int who, double amount) { // hit me double v = dir->pop_me.get(type).hit(now, mds->mdcache->decayrate, amount); diff --git a/src/mds/MDBalancer.h b/src/mds/MDBalancer.h index b8962cc54b5..616379431a6 100644 --- a/src/mds/MDBalancer.h +++ b/src/mds/MDBalancer.h @@ -53,8 +53,8 @@ public: 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); + void hit_inode(const utime_t& now, CInode *in, int type, int who=-1); + void hit_dir(const utime_t& now, CDir *dir, int type, int who=-1, double amount=1.0); void queue_split(const CDir *dir, bool fast); void queue_merge(CDir *dir); diff --git a/src/mds/Server.cc b/src/mds/Server.cc index 2fdc623855a..07bbf9b9241 100644 --- a/src/mds/Server.cc +++ b/src/mds/Server.cc @@ -3080,11 +3080,14 @@ void Server::handle_client_getattr(MDRequestRef& mdr, bool is_lookup) if (!check_access(mdr, ref, MAY_READ)) return; + utime_t now = ceph_clock_now(); + mdr->set_mds_stamp(now); + // note which caps are requested, so we return at least a snapshot // value for them. (currently this matters for xattrs and inline data) mdr->getattr_caps = mask; - mds->balancer->hit_inode(ceph_clock_now(), ref, META_POP_IRD, + mds->balancer->hit_inode(now, ref, META_POP_IRD, req->get_source().num()); // reply @@ -3438,6 +3441,9 @@ void Server::handle_client_open(MDRequestRef& mdr) if (!check_access(mdr, cur, mask)) return; + utime_t now = ceph_clock_now(); + mdr->set_mds_stamp(now); + if (cur->is_file() || cur->is_dir()) { if (mdr->snapid == CEPH_NOSNAP) { // register new cap @@ -3471,9 +3477,9 @@ void Server::handle_client_open(MDRequestRef& mdr) // hit pop if (cmode & CEPH_FILE_MODE_WR) - mds->balancer->hit_inode(mdr->get_mds_stamp(), cur, META_POP_IWR); + mds->balancer->hit_inode(now, cur, META_POP_IWR); else - mds->balancer->hit_inode(mdr->get_mds_stamp(), cur, META_POP_IRD, + mds->balancer->hit_inode(now, cur, META_POP_IRD, mdr->client_request->get_source().num()); CDentry *dn = 0; @@ -3510,7 +3516,8 @@ public: MDRequestRef null_ref; get_mds()->mdcache->send_dentry_link(dn, null_ref); - get_mds()->balancer->hit_inode(mdr->get_mds_stamp(), newi, META_POP_IWR); + utime_t now = ceph_clock_now(); + get_mds()->balancer->hit_inode(now, newi, META_POP_IWR); server->respond_to_request(mdr, 0); @@ -3977,7 +3984,8 @@ public: mds->mdcache->do_realm_invalidate_and_update_notify(in, op); } - mds->balancer->hit_inode(mdr->get_mds_stamp(), in, META_POP_IWR); + utime_t now = ceph_clock_now(); + get_mds()->balancer->hit_inode(now, in, META_POP_IWR); server->respond_to_request(mdr, 0); @@ -4921,7 +4929,8 @@ public: mdr->apply(); - get_mds()->balancer->hit_inode(mdr->get_mds_stamp(), in, META_POP_IWR); + utime_t now = ceph_clock_now(); + get_mds()->balancer->hit_inode(now, in, META_POP_IWR); server->respond_to_request(mdr, 0); } @@ -5127,7 +5136,8 @@ public: get_mds()->locker->share_inode_max_size(newi); // hit pop - get_mds()->balancer->hit_inode(mdr->get_mds_stamp(), newi, META_POP_IWR); + utime_t now = ceph_clock_now(); + get_mds()->balancer->hit_inode(now, newi, META_POP_IWR); // reply server->respond_to_request(mdr, 0); @@ -5516,8 +5526,9 @@ void Server::_link_local_finish(MDRequestRef& mdr, CDentry *dn, CInode *targeti, } // bump target popularity - mds->balancer->hit_inode(mdr->get_mds_stamp(), targeti, META_POP_IWR); - mds->balancer->hit_dir(mdr->get_mds_stamp(), dn->get_dir(), META_POP_IWR); + utime_t now = ceph_clock_now(); + mds->balancer->hit_inode(now, targeti, META_POP_IWR); + mds->balancer->hit_dir(now, dn->get_dir(), META_POP_IWR); // reply respond_to_request(mdr, 0); @@ -5649,8 +5660,9 @@ void Server::_link_remote_finish(MDRequestRef& mdr, bool inc, mdcache->send_dentry_unlink(dn, NULL, null_ref); // bump target popularity - mds->balancer->hit_inode(mdr->get_mds_stamp(), targeti, META_POP_IWR); - mds->balancer->hit_dir(mdr->get_mds_stamp(), dn->get_dir(), META_POP_IWR); + utime_t now = ceph_clock_now(); + mds->balancer->hit_inode(now, targeti, META_POP_IWR); + mds->balancer->hit_dir(now, dn->get_dir(), META_POP_IWR); // reply respond_to_request(mdr, 0); @@ -5799,7 +5811,8 @@ void Server::_logged_slave_link(MDRequestRef& mdr, CInode *targeti, bool adjust_ mdr->apply(); // hit pop - mds->balancer->hit_inode(mdr->get_mds_stamp(), targeti, META_POP_IWR); + utime_t now = ceph_clock_now(); + mds->balancer->hit_inode(now, targeti, META_POP_IWR); // done. mdr->slave_request->put(); @@ -6344,7 +6357,8 @@ void Server::_unlink_local_finish(MDRequestRef& mdr, } // bump pop - mds->balancer->hit_dir(mdr->get_mds_stamp(), dn->get_dir(), META_POP_IWR); + utime_t now = ceph_clock_now(); + mds->balancer->hit_dir(now, dn->get_dir(), META_POP_IWR); // reply respond_to_request(mdr, 0); @@ -7257,9 +7271,10 @@ void Server::_rename_finish(MDRequestRef& mdr, CDentry *srcdn, CDentry *destdn, assert(g_conf->mds_kill_rename_at != 6); // bump popularity - mds->balancer->hit_dir(mdr->get_mds_stamp(), srcdn->get_dir(), META_POP_IWR); + utime_t now = ceph_clock_now(); + mds->balancer->hit_dir(now, srcdn->get_dir(), META_POP_IWR); if (destdnl->is_remote() && in->is_auth()) - mds->balancer->hit_inode(mdr->get_mds_stamp(), in, META_POP_IWR); + mds->balancer->hit_inode(now, in, META_POP_IWR); // did we import srci? if so, explicitly ack that import that, before we unlock and reply. @@ -8246,10 +8261,10 @@ void Server::_logged_slave_rename(MDRequestRef& mdr, CDentry::linkage_t *destdnl = destdn->get_linkage(); // bump popularity - mds->balancer->hit_dir(mdr->get_mds_stamp(), srcdn->get_dir(), META_POP_IWR); + utime_t now = ceph_clock_now(); + mds->balancer->hit_dir(now, srcdn->get_dir(), META_POP_IWR); if (destdnl->get_inode() && destdnl->get_inode()->is_auth()) - mds->balancer->hit_inode(mdr->get_mds_stamp(), destdnl->get_inode(), - META_POP_IWR); + mds->balancer->hit_inode(now, destdnl->get_inode(), META_POP_IWR); // done. mdr->slave_request->put(); @@ -8297,8 +8312,7 @@ void Server::_commit_slave_rename(MDRequestRef& mdr, int r, decode(peer_imported, bp); dout(10) << " finishing inode export on " << *destdnl->get_inode() << dendl; - mdcache->migrator->finish_export_inode(destdnl->get_inode(), - mdr->get_mds_stamp(), + mdcache->migrator->finish_export_inode(destdnl->get_inode(), ceph_clock_now(), mdr->slave_to_mds, peer_imported, finished); mds->queue_waiters(finished); // this includes SINGLEAUTH waiters. -- 2.39.5