From: Yan, Zheng Date: Thu, 18 May 2017 07:47:30 +0000 (+0800) Subject: mds: match EMetaBlob::add_dir_context with MDCache::create_subtree_map X-Git-Tag: v12.1.0~128^2~1 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=ba3fd506c77fb8a4016d4eed45b02f670a8f8124;p=ceph.git mds: match EMetaBlob::add_dir_context with MDCache::create_subtree_map In EMetaBlob::add_dir_context(), the code that checks if a subtree was journaled in the latest ESubtreeMap is different from the code that creates ESubtreeMap. When creating ESubtreeMap, if a subtree's dir_auth.first is equal to its parent subtree's dir_auth.first, the subtree may not be journaled. EMetaBlob::add_dir_context() attempts to get the result by checking CDir::STATE_{EXPORTBOUND,AUXSUBTREE} and CDir::is_ambiguous_auth(). The difference makes the code hard to understand and error prone. Signed-off-by: "Yan, Zheng" --- diff --git a/src/mds/Migrator.cc b/src/mds/Migrator.cc index e954038de1301..258a13a31159d 100644 --- a/src/mds/Migrator.cc +++ b/src/mds/Migrator.cc @@ -1683,17 +1683,13 @@ void Migrator::handle_export_ack(MExportDirAck *m) set bounds; cache->get_subtree_bounds(dir, bounds); - // list us second, them first. - // this keeps authority().first in sync with subtree auth state in the journal. - cache->adjust_subtree_auth(dir, it->second.peer, mds->get_nodeid()); - // log completion. // include export bounds, to ensure they're in the journal. EExport *le = new EExport(mds->mdlog, dir, it->second.peer);; mds->mdlog->start_entry(le); le->metablob.add_dir_context(dir, EMetaBlob::TO_ROOT); - le->metablob.add_dir( dir, false ); + le->metablob.add_dir(dir, false); for (set::iterator p = bounds.begin(); p != bounds.end(); ++p) { @@ -1703,6 +1699,10 @@ void Migrator::handle_export_ack(MExportDirAck *m) le->metablob.add_dir(bound, false); } + // list us second, them first. + // this keeps authority().first in sync with subtree auth state in the journal. + cache->adjust_subtree_auth(dir, it->second.peer, mds->get_nodeid()); + // log export completion, then finish (unfreeze, trigger finish context, etc.) mds->mdlog->submit_entry(le, new C_MDS_ExportFinishLogged(this, dir)); mds->mdlog->flush(); diff --git a/src/mds/journal.cc b/src/mds/journal.cc index a65b45725a877..4d63f28923645 100644 --- a/src/mds/journal.cc +++ b/src/mds/journal.cc @@ -329,13 +329,20 @@ void EMetaBlob::add_dir_context(CDir *dir, int mode) if (mode == TO_AUTH_SUBTREE_ROOT) { // subtree root? - if (dir->is_subtree_root() && - !dir->state_test(CDir::STATE_EXPORTBOUND)) { - if (dir->is_auth() && !dir->is_ambiguous_auth() ) { - if (dir->state_test(CDir::STATE_AUXSUBTREE) && - dir->get_dir_auth().first == diri->authority().first) { - // auxiliary subtree. treat it as normal dirfrag - dout(20) << "EMetaBlob::add_dir_context(" << dir << ") auxiliary subtree " << dendl; + if (dir->is_subtree_root()) { + // match logic in MDCache::create_subtree_map() + if (dir->get_dir_auth().first == mds->get_nodeid()) { + mds_authority_t parent_auth = parent ? parent->authority() : CDIR_AUTH_UNDEF; + if (parent_auth.first == dir->get_dir_auth().first) { + if (parent_auth.second == CDIR_AUTH_UNKNOWN && + !dir->is_ambiguous_dir_auth() && + !dir->state_test(CDir::STATE_EXPORTBOUND) && + !dir->state_test(CDir::STATE_AUXSUBTREE) && + !diri->state_test(CInode::STATE_AMBIGUOUSAUTH)) { + dout(0) << "EMetaBlob::add_dir_context unexpected subtree " << *dir << dendl; + assert(0); + } + dout(20) << "EMetaBlob::add_dir_context(" << dir << ") ambiguous or transient subtree " << dendl; } else { // it's an auth subtree, we don't need maybe (if any), and we're done. dout(20) << "EMetaBlob::add_dir_context(" << dir << ") reached unambig auth subtree, don't need " << maybe @@ -351,7 +358,7 @@ void EMetaBlob::add_dir_context(CDir *dir, int mode) maybenot = false; } } - + // was the inode journaled in this blob? if (event_seq && diri->last_journaled == event_seq) { dout(20) << "EMetaBlob::add_dir_context(" << dir << ") already have diri this blob " << *diri << dendl;