From cbd1c447591374a71dbca4a8258f85d945a050d5 Mon Sep 17 00:00:00 2001 From: "Yan, Zheng" Date: Wed, 5 Mar 2014 18:56:01 +0800 Subject: [PATCH] mds: improve success rate of subtree exporting When exporting a subtree, the migrator acquires the required locks, then freezes the subtree and releases the locks. After subtree is frozen, it try acquiring the same locks again. This patch make scatter locks keep in their old states if inode has exporting dirfrag. It improves the chance that migrator acquires all required locks when subtree is frozen. Signed-off-by: Yan, Zheng --- src/mds/CInode.cc | 10 ++++++++++ src/mds/CInode.h | 1 + src/mds/Locker.cc | 8 ++++---- 3 files changed, 15 insertions(+), 4 deletions(-) diff --git a/src/mds/CInode.cc b/src/mds/CInode.cc index e58ceb18f4b60..c813f5c29ab11 100644 --- a/src/mds/CInode.cc +++ b/src/mds/CInode.cc @@ -642,6 +642,16 @@ bool CInode::has_subtree_root_dirfrag(int auth) return false; } +bool CInode::has_subtree_or_exporting_dirfrag() +{ + for (map::iterator p = dirfrags.begin(); + p != dirfrags.end(); + ++p) + if (p->second->is_subtree_root() || + p->second->state_test(CDir::STATE_EXPORTING)) + return true; + return false; +} void CInode::get_stickydirs() { diff --git a/src/mds/CInode.h b/src/mds/CInode.h index 7d2dd659b5968..efc9825aa353f 100644 --- a/src/mds/CInode.h +++ b/src/mds/CInode.h @@ -355,6 +355,7 @@ public: void close_dirfrag(frag_t fg); void close_dirfrags(); bool has_subtree_root_dirfrag(int auth=-1); + bool has_subtree_or_exporting_dirfrag(); void force_dirfrags(); void verify_dirfrags(); diff --git a/src/mds/Locker.cc b/src/mds/Locker.cc index 1906c49bc4c13..1d570bb0b0c56 100644 --- a/src/mds/Locker.cc +++ b/src/mds/Locker.cc @@ -1298,7 +1298,7 @@ bool Locker::wrlock_start(SimpleLock *lock, MDRequest *mut, bool nowait) CInode *in = static_cast(lock->get_parent()); client_t client = mut->get_client(); bool want_scatter = !nowait && lock->get_parent()->is_auth() && - (in->has_subtree_root_dirfrag() || + (in->has_subtree_or_exporting_dirfrag() || static_cast(lock)->get_scatter_wanted()); while (1) { @@ -3920,7 +3920,7 @@ void Locker::scatter_eval(ScatterLock *lock, bool *need_issue) } CInode *in = static_cast(lock->get_parent()); - if (!in->has_subtree_root_dirfrag() || in->is_base()) { + if (!in->has_subtree_or_exporting_dirfrag() || in->is_base()) { // i _should_ be sync. if (!lock->is_wrlocked() && lock->get_state() != LOCK_SYNC) { @@ -4284,7 +4284,7 @@ void Locker::file_eval(ScatterLock *lock, bool *need_issue) !lock->is_rdlocked() && //!lock->is_waiter_for(SimpleLock::WAIT_WR) && ((wanted & (CEPH_CAP_GWR|CEPH_CAP_GBUFFER)) || - (in->inode.is_dir() && !in->has_subtree_root_dirfrag())) && + (in->inode.is_dir() && !in->has_subtree_or_exporting_dirfrag())) && in->get_target_loner() >= 0) { dout(7) << "file_eval stable, bump to loner " << *lock << " on " << *lock->get_parent() << dendl; @@ -4308,7 +4308,7 @@ void Locker::file_eval(ScatterLock *lock, bool *need_issue) !lock->is_waiter_for(SimpleLock::WAIT_WR) && !(wanted & (CEPH_CAP_GWR|CEPH_CAP_GBUFFER)) && !((lock->get_state() == LOCK_MIX) && - in->is_dir() && in->has_subtree_root_dirfrag()) // if we are a delegation point, stay where we are + in->is_dir() && in->has_subtree_or_exporting_dirfrag()) // if we are a delegation point, stay where we are //((wanted & CEPH_CAP_RD) || //in->is_replicated() || //lock->get_num_client_lease() || -- 2.39.5