From 4fd34befd5b626b5baeba91cd23b5478b60529d0 Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Fri, 16 Aug 2013 22:08:00 -0700 Subject: [PATCH] mds: create only one ESubtreeMap during fs creation Previously we would create an empty ESubtreeMap when we opened the log segment and then immediately journal a second one that created the root and mdsdir. More importantly, for the second ESubtreeMap, we would not wait for it to commit before requesting the ACTIVE state, leading to #4894. Instead, break start_new_segment() into two steps: one that creates the in-memory LogSegment tracking structure, and one that journals the ESubtreeMap. Open things early and write the (one) ESubtreeMap at the end of boot_create().. and then wait for it. Fixes: #4894 Signed-off-by: Sage Weil Reviewed-by: Yan, Zheng --- src/mds/MDLog.cc | 23 ++++++++++++++++------- src/mds/MDLog.h | 2 ++ src/mds/MDS.cc | 13 +++++++++---- 3 files changed, 27 insertions(+), 11 deletions(-) diff --git a/src/mds/MDLog.cc b/src/mds/MDLog.cc index 3dfc00fc221ec..1ace72e0ac378 100644 --- a/src/mds/MDLog.cc +++ b/src/mds/MDLog.cc @@ -267,16 +267,19 @@ void MDLog::cap() void MDLog::start_new_segment(Context *onsync) { - dout(7) << "start_new_segment at " << journaler->get_write_pos() << dendl; - - segments[journaler->get_write_pos()] = new LogSegment(journaler->get_write_pos()); - - ESubtreeMap *le = mds->mdcache->create_subtree_map(); - submit_entry(le); + prepare_new_segment(); + journal_segment_subtree_map(); if (onsync) { - wait_for_safe(onsync); + wait_for_safe(onsync); flush(); } +} + +void MDLog::prepare_new_segment() +{ + dout(7) << __func__ << " at " << journaler->get_write_pos() << dendl; + + segments[journaler->get_write_pos()] = new LogSegment(journaler->get_write_pos()); logger->inc(l_mdl_segadd); logger->set(l_mdl_seg, segments.size()); @@ -287,6 +290,12 @@ void MDLog::start_new_segment(Context *onsync) mds->mdcache->advance_stray(); } +void MDLog::journal_segment_subtree_map() +{ + dout(7) << __func__ << dendl; + submit_entry(mds->mdcache->create_subtree_map()); +} + void MDLog::trim(int m) { int max_segments = g_conf->mds_log_max_segments; diff --git a/src/mds/MDLog.h b/src/mds/MDLog.h index 46b34d26f6987..82d51c33d1500 100644 --- a/src/mds/MDLog.h +++ b/src/mds/MDLog.h @@ -161,6 +161,8 @@ public: // -- segments -- void start_new_segment(Context *onsync=0); + void prepare_new_segment(); + void journal_segment_subtree_map(); LogSegment *peek_current_segment() { return segments.empty() ? NULL : segments.rbegin()->second; diff --git a/src/mds/MDS.cc b/src/mds/MDS.cc index 092d5ebec655c..fc05ca0ecb735 100644 --- a/src/mds/MDS.cc +++ b/src/mds/MDS.cc @@ -1140,7 +1140,9 @@ void MDS::boot_create() // start with a fresh journal dout(10) << "boot_create creating fresh journal" << dendl; mdlog->create(fin.new_sub()); - mdlog->start_new_segment(fin.new_sub()); + + // open new journal segment, but do not journal subtree map (yet) + mdlog->prepare_new_segment(); if (whoami == mdsmap->get_root()) { dout(3) << "boot_create creating fresh hierarchy" << dendl; @@ -1170,6 +1172,12 @@ void MDS::boot_create() snapserver->save(fin.new_sub()); snapserver->handle_mds_recovery(whoami); } + + // ok now journal it + mdlog->journal_segment_subtree_map(); + mdlog->wait_for_safe(fin.new_sub()); + mdlog->flush(); + fin.activate(); } @@ -1177,9 +1185,6 @@ void MDS::creating_done() { dout(1)<< "creating_done" << dendl; request_state(MDSMap::STATE_ACTIVE); - - // start new segment - mdlog->start_new_segment(0); } -- 2.39.5