From 299ddd31b29e332dc5e76bc4f871e4769698665d Mon Sep 17 00:00:00 2001 From: "Yan, Zheng" Date: Thu, 10 Oct 2013 10:35:48 +0800 Subject: mds: fix infinite loop of MDCache::populate_mydir(). 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 Reviewed-by: Greg Farnum Reviewed-by: Sage Weil (cherry picked from commit 007f06ec174d4ee5cfb578c8b3f1c96b2bb0c238) Conflicts: src/mds/MDCache.h Reviewed-by: Greg Farnum --- src/mds/MDCache.cc | 31 ++++++++++++++++++++++++------- src/mds/MDCache.h | 3 ++- src/mds/MDS.cc | 1 - 3 files changed, 26 insertions(+), 9 deletions(-) diff --git a/src/mds/MDCache.cc b/src/mds/MDCache.cc index b6c37aec53f..992730d3c0a 100644 --- a/src/mds/MDCache.cc +++ b/src/mds/MDCache.cc @@ -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) @@ -9125,19 +9127,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 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::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(); diff --git a/src/mds/MDCache.h b/src/mds/MDCache.h index 36a322c6324..2574e755c9b 100644 --- a/src/mds/MDCache.h +++ b/src/mds/MDCache.h @@ -858,7 +858,6 @@ public: // -- stray -- public: - void scan_stray_dir(); void eval_stray(CDentry *dn); void eval_remote(CDentry *dn); @@ -872,6 +871,7 @@ public: eval_stray(dn); } protected: + void scan_stray_dir(dirfrag_t next=dirfrag_t()); void fetch_backtrace(inodeno_t ino, int64_t pool, bufferlist& bl, Context *fin); void remove_backtrace(inodeno_t ino, int64_t pool, Context *fin); void _purge_forwarding_pointers(bufferlist& bl, CDentry *dn, int r); @@ -880,6 +880,7 @@ protected: 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_PurgeForwardingPointers; friend class C_MDC_PurgeStray; diff --git a/src/mds/MDS.cc b/src/mds/MDS.cc index 70c5efbec58..3a7f7b9339b 100644 --- a/src/mds/MDS.cc +++ b/src/mds/MDS.cc @@ -1520,7 +1520,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 -- cgit v1.2.1