]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
mds: fix infinite loop of MDCache::populate_mydir(). 702/head
authorYan, Zheng <zheng.z.yan@intel.com>
Thu, 10 Oct 2013 02:35:48 +0000 (10:35 +0800)
committerYan, Zheng <zheng.z.yan@intel.com>
Thu, 10 Oct 2013 02:53:24 +0000 (10:53 +0800)
make MDCache::populate_mydir() only fetch bare-bone stray dirs.
After all stray dirs are populated, call MDCache::scan_stray_dir(),
it fetches incomplete stray dirs.

Fixes: #4405
Signed-off-by: Yan, Zheng <zheng.z.yan@intel.com>
src/mds/MDCache.cc
src/mds/MDCache.h
src/mds/MDS.cc

index 9dc1229fbb96336a99b045fe965734acaa48d3f6..a9721fa54c62df293abe3827d51d3f10b1452f11 100644 (file)
@@ -632,7 +632,7 @@ void MDCache::populate_mydir()
       CDir *dir = strays[i]->get_dirfrag(fg);
       if (!dir)
        dir = strays[i]->get_or_open_dirfrag(this, fg);
-      if (!dir->is_complete()) {
+      if (dir->get_version() == 0) {
        dir->fetch(new C_MDS_RetryOpenRoot(this));
        return;
       }
@@ -653,6 +653,8 @@ void MDCache::populate_mydir()
   assert(!open);    
   open = true;
   mds->queue_waiters(waiting_for_open);
+
+  scan_stray_dir();
 }
 
 void MDCache::open_foreign_mdsdir(inodeno_t ino, Context *fin)
@@ -9135,19 +9137,34 @@ void MDCache::_snaprealm_create_finish(MDRequest *mdr, Mutation *mut, CInode *in
 // -------------------------------------------------------------------------------
 // STRAYS
 
-void MDCache::scan_stray_dir()
+struct C_MDC_RetryScanStray : public Context {
+  MDCache *cache;
+  dirfrag_t next;
+  C_MDC_RetryScanStray(MDCache *c,  dirfrag_t n) : cache(c), next(n) { }
+  void finish(int r) {
+    cache->scan_stray_dir(next);
+  }
+};
+
+void MDCache::scan_stray_dir(dirfrag_t next)
 {
-  dout(10) << "scan_stray_dir" << dendl;
-  
+  dout(10) << "scan_stray_dir " << next << dendl;
+
   list<CDir*> ls;
   for (int i = 0; i < NUM_STRAY; ++i) {
-    if (strays[i]) {
-      strays[i]->get_dirfrags(ls);
-    }
+    if (strays[i]->ino() < next.ino)
+      continue;
+    strays[i]->get_dirfrags(ls);
   }
 
   for (list<CDir*>::iterator p = ls.begin(); p != ls.end(); ++p) {
     CDir *dir = *p;
+    if (dir->dirfrag() < next)
+      continue;
+    if (!dir->is_complete()) {
+      dir->fetch(new C_MDC_RetryScanStray(this, dir->dirfrag()));
+      return;
+    }
     for (CDir::map_t::iterator q = dir->items.begin(); q != dir->items.end(); ++q) {
       CDentry *dn = q->second;
       CDentry::linkage_t *dnl = dn->get_projected_linkage();
index d8f2a9486fb7e0884a9a45c6c757bd529a6d214a..416c6454292ba06bbce9f5b3c311effb086b177d 100644 (file)
@@ -870,7 +870,6 @@ public:
 public:
   elist<CDentry*> delayed_eval_stray;
 
-  void scan_stray_dir();
   void eval_stray(CDentry *dn, bool delay=false);
   void eval_remote(CDentry *dn);
 
@@ -884,11 +883,13 @@ public:
       eval_stray(dn, delay);
   }
 protected:
+  void scan_stray_dir(dirfrag_t next=dirfrag_t());
   void fetch_backtrace(inodeno_t ino, int64_t pool, bufferlist& bl, Context *fin);
   void purge_stray(CDentry *dn);
   void _purge_stray_purged(CDentry *dn, int r=0);
   void _purge_stray_logged(CDentry *dn, version_t pdv, LogSegment *ls);
   void _purge_stray_logged_truncate(CDentry *dn, LogSegment *ls);
+  friend class C_MDC_RetryScanStray;
   friend class C_MDC_FetchedBacktrace;
   friend class C_MDC_PurgeStrayLogged;
   friend class C_MDC_PurgeStrayLoggedTruncate;
index c2e0bbbe3691602cbb559f906af05a53d7f16d0d..83722274981d9c1b8b43246dbbea7b3103dc5bf0 100644 (file)
@@ -1525,7 +1525,6 @@ void MDS::active_start()
     mdcache->open_root();
 
   mdcache->clean_open_file_lists();
-  mdcache->scan_stray_dir();
   mdcache->export_remaining_imported_caps();
   finish_contexts(g_ceph_context, waiting_for_replay);  // kick waiters
   finish_contexts(g_ceph_context, waiting_for_active);  // kick waiters