From: Yan, Zheng Date: Mon, 18 May 2015 10:53:25 +0000 (+0800) Subject: mds: avoid calling StrayManager::eval_stray() recursively X-Git-Tag: v9.0.2~40^2~4 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=a13414da2c5d0b4ef3f671789127959682d51e51;p=ceph.git mds: avoid calling StrayManager::eval_stray() recursively StrayManager::eval_stray() may close dirfrags and unlink remote dentries. These operations drop inode's reference, which may call StrayManager::eval_stray() again. Signed-off-by: Yan, Zheng --- diff --git a/src/mds/CDentry.h b/src/mds/CDentry.h index f56f2a208ba..40a4723601c 100644 --- a/src/mds/CDentry.h +++ b/src/mds/CDentry.h @@ -72,6 +72,7 @@ public: static const int STATE_FRAGMENTING = (1<<1); static const int STATE_PURGING = (1<<2); static const int STATE_BADREMOTEINO = (1<<3); + static const int STATE_EVALUATINGSTRAY = (1<<4); // stray dentry needs notification of releasing reference static const int STATE_STRAY = STATE_NOTIFYREF; diff --git a/src/mds/StrayManager.cc b/src/mds/StrayManager.cc index d0334f5a3ba..71b776a69c5 100644 --- a/src/mds/StrayManager.cc +++ b/src/mds/StrayManager.cc @@ -520,7 +520,7 @@ struct C_MDC_EvalStray : public StrayManagerContext { } }; -bool StrayManager::eval_stray(CDentry *dn, bool delay) +bool StrayManager::__eval_stray(CDentry *dn, bool delay) { dout(10) << "eval_stray " << *dn << dendl; CDentry::linkage_t *dnl = dn->get_projected_linkage(); @@ -644,6 +644,18 @@ bool StrayManager::eval_stray(CDentry *dn, bool delay) } } +bool StrayManager::eval_stray(CDentry *dn, bool delay) +{ + // avoid nested eval_stray + if (dn->state_test(CDentry::STATE_EVALUATINGSTRAY)) + return false; + + dn->state_set(CDentry::STATE_EVALUATINGSTRAY); + bool ret = __eval_stray(dn, delay); + dn->state_clear(CDentry::STATE_EVALUATINGSTRAY); + return ret; +} + void StrayManager::eval_remote_stray(CDentry *stray_dn, CDentry *remote_dn) { assert(stray_dn != NULL); diff --git a/src/mds/StrayManager.h b/src/mds/StrayManager.h index ca5c612981c..d508017e45f 100644 --- a/src/mds/StrayManager.h +++ b/src/mds/StrayManager.h @@ -130,11 +130,28 @@ class StrayManager : public md_config_obs_t */ void reintegrate_stray(CDentry *dn, CDentry *rlink); + /** + * Evaluate a stray dentry for purging or reintegration. + * + * purging: If the inode has no linkage, and no more references, then + * we may decide to purge it. + * + * reintegration: If the inode still has linkage, then it means someone else + * (a hard link) is still referring to it, and we should + * think about reintegrating that inode into the remote dentry. + * + * @returns true if the dentry will be purged (caller should never + * take more refs after this happens), else false. + */ + bool __eval_stray(CDentry *dn, bool delay=false); + // My public interface is for consumption by MDCache public: StrayManager(MDS *mds); void set_logger(PerfCounters *l) {logger = l;} + bool eval_stray(CDentry *dn, bool delay=false); + /** * Where eval_stray was previously invoked with delay=true, call * eval_stray again for any dentries that were put on the @@ -148,21 +165,6 @@ class StrayManager : public md_config_obs_t */ void advance_delayed(); - /** - * Evaluate a stray dentry for purging or reintegration. - * - * purging: If the inode has no linkage, and no more references, then - * we may decide to purge it. - * - * reintegration: If the inode still has linkage, then it means someone else - * (a hard link) is still referring to it, and we should - * think about reintegrating that inode into the remote dentry. - * - * @returns true if the dentry will be purged (caller should never - * take more refs after this happens), else false. - */ - bool eval_stray(CDentry *dn, bool delay=false); - /** * When a metadata op touches a remote dentry that points to * a stray, call in here to evaluate it for migration (move