]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
mds: match EMetaBlob::add_dir_context with MDCache::create_subtree_map
authorYan, Zheng <zyan@redhat.com>
Thu, 18 May 2017 07:47:30 +0000 (15:47 +0800)
committerYan, Zheng <zyan@redhat.com>
Wed, 24 May 2017 09:12:25 +0000 (17:12 +0800)
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" <zyan@redhat.com>
src/mds/Migrator.cc
src/mds/journal.cc

index e954038de1301df9d17177a1fa694d1f521585ba..258a13a31159d2f3cb8ae9e37463f0ff7f5b3154 100644 (file)
@@ -1683,17 +1683,13 @@ void Migrator::handle_export_ack(MExportDirAck *m)
   set<CDir*> 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<CDir*>::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();
index a65b45725a877a0356a194a8b117dbd6c76aa94b..4d63f28923645fd6e39ca51c9369435dffb23f2f 100644 (file)
@@ -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;