summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSage Weil <sage@inktank.com>2013-10-11 07:33:35 -0700
committerSage Weil <sage@inktank.com>2013-10-11 07:33:35 -0700
commitb214584b8439226851aa21ae346c6e4ee1f40f08 (patch)
treee0974f80de7ec715ff8dbbb4eb331dcdb0ca1a4c
parentcb9ebd6f363fb571ecb770eab9ab1313cb407108 (diff)
parent007f06ec174d4ee5cfb578c8b3f1c96b2bb0c238 (diff)
downloadceph-b214584b8439226851aa21ae346c6e4ee1f40f08.tar.gz
Merge pull request #702 from ceph/wip-4405
mds: fix infinite loop of MDCache::populate_mydir(). Reviewed-by: Greg Farnum <greg@inktank.com> Reviewed-by: Sage Weil <sage@inktank.com>
-rw-r--r--src/mds/MDCache.cc31
-rw-r--r--src/mds/MDCache.h3
-rw-r--r--src/mds/MDS.cc1
3 files changed, 26 insertions, 9 deletions
diff --git a/src/mds/MDCache.cc b/src/mds/MDCache.cc
index 9dc1229fbb9..a9721fa54c6 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)
@@ -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();
diff --git a/src/mds/MDCache.h b/src/mds/MDCache.h
index d8f2a9486fb..416c6454292 100644
--- a/src/mds/MDCache.h
+++ b/src/mds/MDCache.h
@@ -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;
diff --git a/src/mds/MDS.cc b/src/mds/MDS.cc
index c2e0bbbe369..83722274981 100644
--- a/src/mds/MDS.cc
+++ b/src/mds/MDS.cc
@@ -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