]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
mds: don't run all of try_subtree_merge on a rename across MDSes.
authorGreg Farnum <gregory.farnum@dreamhost.com>
Mon, 11 Apr 2011 23:57:50 +0000 (16:57 -0700)
committerSage Weil <sage.weil@dreamhost.com>
Sun, 17 Apr 2011 04:03:37 +0000 (21:03 -0700)
Previously we'd try and do the whole thing, which meant that
the replica got a lock twiddle before it had finished the export.
That broke things spectacularly, since we weren't respecting our
invariants about who gets remote locking messages.
Now we pass through a flag and respect our invariants.

Signed-off-by: Greg Farnum <gregory.farnum@dreamhost.com>
Signed-off-by: Sage Weil <sage.weil@dreamhost.com>
src/mds/MDCache.cc
src/mds/MDCache.h
src/mds/Server.cc

index 51b4b483feb1fbf635e6df5c56934d0a5c48bf53..5609a809c6741fd2f98f619e34eac65ad0232f65 100644 (file)
@@ -787,12 +787,11 @@ public:
   }
 };
 
-void MDCache::try_subtree_merge_at(CDir *dir)
+void MDCache::try_subtree_merge_at(CDir *dir, bool do_eval)
 {
   dout(10) << "try_subtree_merge_at " << *dir << dendl;
   assert(subtrees.count(dir));
 
-  bool do_eval = true;
   if (mds->is_any_replay() || mds->is_resolve())
     do_eval = false;
 
@@ -1210,7 +1209,8 @@ void MDCache::verify_subtree_bounds(CDir *dir, const list<dirfrag_t>& bounds)
   assert(failed == 0);
 }
 
-void MDCache::adjust_subtree_after_rename(CInode *diri, CDir *olddir)
+void MDCache::adjust_subtree_after_rename(CInode *diri, CDir *olddir,
+                                          bool imported)
 {
   dout(10) << "adjust_subtree_after_rename " << *diri << " from " << *olddir << dendl;
 
@@ -1274,7 +1274,7 @@ void MDCache::adjust_subtree_after_rename(CInode *diri, CDir *olddir)
     // un-force dir to subtree root
     if (dir->dir_auth == pair<int,int>(dir->dir_auth.first, dir->dir_auth.first)) {
       adjust_subtree_auth(dir, dir->dir_auth.first);
-      try_subtree_merge_at(dir);
+      try_subtree_merge_at(dir, !imported);
     }
   }
 
index 6e974912d6c7ad47336733c05c95573aad514553..4a0f28370642f208a20ff74fc163c8a07af9b780 100644 (file)
@@ -548,7 +548,7 @@ public:
   }
   void map_dirfrag_set(list<dirfrag_t>& dfs, set<CDir*>& result);
   void try_subtree_merge(CDir *root);
-  void try_subtree_merge_at(CDir *root);
+  void try_subtree_merge_at(CDir *root, bool do_eval=true);
   void subtree_merge_writebehind_finish(CInode *in, Mutation *mut);
   void eval_subtree_root(CInode *diri);
   CDir *get_subtree_root(CDir *dir);
@@ -563,7 +563,8 @@ public:
   void verify_subtree_bounds(CDir *root, const set<CDir*>& bounds);
   void verify_subtree_bounds(CDir *root, const list<dirfrag_t>& bounds);
 
-  void adjust_subtree_after_rename(CInode *diri, CDir *olddir);
+  void adjust_subtree_after_rename(CInode *diri, CDir *olddir,
+                                   bool imported = false);
 
   void get_auth_subtrees(set<CDir*>& s);
   void get_fullauth_subtrees(set<CDir*>& s);
index 4d871065d0eccf2b2dcfe8087ae3ec4472641f9e..16ecd11bf3df9082ff3303972b936ee79b6fdeef 100644 (file)
@@ -5273,6 +5273,8 @@ void Server::_rename_apply(MDRequest *mdr, CDentry *srcdn, CDentry *destdn, CDen
 
   CInode *oldin = destdnl->get_inode();
   
+  bool imported_inode = false;
+
   // primary+remote link merge?
   bool linkmerge = (srcdnl->get_inode() == destdnl->get_inode() &&
                    (srcdnl->is_primary() || destdnl->is_primary()));
@@ -5348,6 +5350,7 @@ void Server::_rename_apply(MDRequest *mdr, CDentry *srcdn, CDentry *destdn, CDen
       
       // hack: fix auth bit
       destdnl->get_inode()->state_set(CInode::STATE_AUTH);
+      imported_inode = true;
     }
 
     if (destdn->is_auth()) {
@@ -5375,7 +5378,9 @@ void Server::_rename_apply(MDRequest *mdr, CDentry *srcdn, CDentry *destdn, CDen
 
   // update subtree map?
   if (destdnl->is_primary() && destdnl->get_inode()->is_dir()) 
-    mdcache->adjust_subtree_after_rename(destdnl->get_inode(), srcdn->get_dir());
+    mdcache->adjust_subtree_after_rename(destdnl->get_inode(),
+                                         srcdn->get_dir(),
+                                         imported_inode);
 
   // removing a new dn?
   if (srcdn->is_auth())