]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
mds: fix race between submitting EImportFinish and SubtreeMap
authorYan, Zheng <zyan@redhat.com>
Wed, 18 Jan 2017 02:53:00 +0000 (10:53 +0800)
committerYan, Zheng <zyan@redhat.com>
Thu, 19 Jan 2017 06:59:20 +0000 (14:59 +0800)
MDCache::create_subtree_map() use MDCache::my_ambiguous_imports
and Migrator::is_ambiguous_import() to decide if a subtree is
ambiguous import.  Submitting log event can start new segment
and submit an extra SubtreeMap. So before submitting EImportFinish
event, we need to cleanup MDCache::my_ambiguous_imports and
Migrator::import_state.

Signed-off-by: Yan, Zheng <zyan@redhat.com>
src/mds/MDCache.cc
src/mds/Migrator.cc

index d1271e6ba58fee2cc84af0b8e5fcff902b6dc3c3..c0e54385b3d52054ddd2729a1a3f9d62e812e8d4 100644 (file)
@@ -3207,6 +3207,7 @@ void MDCache::handle_resolve(MMDSResolve *m)
            claimed_by_sender = true;
        }
 
+       my_ambiguous_imports.erase(p);  // no longer ambiguous.
        if (claimed_by_sender) {
          dout(7) << "ambiguous import failed on " << *dir << dendl;
          migrator->import_reverse(dir);
@@ -3214,7 +3215,6 @@ void MDCache::handle_resolve(MMDSResolve *m)
          dout(7) << "ambiguous import succeeded on " << *dir << dendl;
          migrator->import_finish(dir, true);
        }
-       my_ambiguous_imports.erase(p);  // no longer ambiguous.
       }
       p = next;
     }
@@ -3507,7 +3507,7 @@ void MDCache::disambiguate_imports()
     map<dirfrag_t, vector<dirfrag_t> >::iterator q = my_ambiguous_imports.begin();
 
     CDir *dir = get_dirfrag(q->first);
-    if (!dir) continue;
+    assert(dir);
     
     if (dir->authority() != me_ambig) {
       dout(10) << "ambiguous import auth known, must not be me " << *dir << dendl;
index d9c867ea802b924193b4893ce3a81c3ea2f67b3c..07d4e8764d45287af289e6b0f56470bdbc81909d 100644 (file)
@@ -2375,6 +2375,7 @@ void Migrator::import_reverse(CDir *dir)
   dout(7) << "import_reverse " << *dir << dendl;
 
   import_state_t& stat = import_state[dir->dirfrag()];
+  stat.state = IMPORT_ABORTING;
 
   set<CDir*> bounds;
   cache->get_subtree_bounds(dir, bounds);
@@ -2493,7 +2494,6 @@ void Migrator::import_reverse(CDir *dir)
   cache->trim(-1, num_dentries); // try trimming dentries
 
   // notify bystanders; wait in aborting state
-  stat.state = IMPORT_ABORTING;
   import_notify_abort(dir, bounds);
 }