]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
mds: avoid calling StrayManager::eval_stray() recursively
authorYan, Zheng <zyan@redhat.com>
Mon, 18 May 2015 10:53:25 +0000 (18:53 +0800)
committerYan, Zheng <zyan@redhat.com>
Tue, 19 May 2015 07:47:17 +0000 (15:47 +0800)
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 <zyan@redhat.com>
src/mds/CDentry.h
src/mds/StrayManager.cc
src/mds/StrayManager.h

index f56f2a208baa8ae297db5e0b8f1238d4995dcf9a..40a4723601cd05bf00707a2a6852e7eb143a43e1 100644 (file)
@@ -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;
 
index d0334f5a3ba190fecf889b55686476f9b5d931d4..71b776a69c54f48aa1bb32ced097c9f8d72906df 100644 (file)
@@ -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);
index ca5c612981c302ba387fb780b8f42904b5a20578..d508017e45ff17e3fc72f8d64cee881ae9d0007c 100644 (file)
@@ -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