]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
mds: freeze fragments during split/merge
authorSage Weil <sage@newdream.net>
Wed, 27 Apr 2011 22:09:35 +0000 (15:09 -0700)
committerSage Weil <sage@newdream.net>
Wed, 27 Apr 2011 22:09:35 +0000 (15:09 -0700)
Freeze the target fragment(s) before unfreezing the old fragment(s) to
avoid any weird events going off when the unfreeze unauth_pins the dir
inode (in certain cases).  This makes the whole process cleaner and more
symmetrical.

Signed-off-by: Sage Weil <sage@newdream.net>
src/mds/CDir.cc
src/mds/CDir.h
src/mds/MDCache.cc

index 8821d00aa15369ce140f33e87f39a47d356f15a2..2c921c0acc15e51731b7442309f69f40fc48f92a 100644 (file)
@@ -659,7 +659,7 @@ void CDir::purge_stale_snap_data(const set<snapid_t>& snaps)
 /**
  * steal_dentry -- semi-violently move a dentry from one CDir to another
  * (*) violently, in that nitems, most pins, etc. are not correctly maintained 
- * on the old CDir corpse; must call purge_stolen() when finished.
+ * on the old CDir corpse; must call finish_old_fragment() when finished.
  */
 void CDir::steal_dentry(CDentry *dn)
 {
@@ -722,7 +722,13 @@ void CDir::steal_dentry(CDentry *dn)
   dn->dir = this;
 }
 
-void CDir::purge_stolen(list<Context*>& waiters, bool replay)
+void CDir::prepare_new_fragment(bool replay)
+{
+  if (!replay && is_auth())
+    _freeze_dir();
+}
+
+void CDir::finish_old_fragment(list<Context*>& waiters, bool replay)
 {
   // take waiters _before_ unfreeze...
   if (!replay) {
@@ -818,6 +824,8 @@ void CDir::split(int bits, list<CDir*>& subs, list<Context*>& waiters, bool repl
     subfrags[n++] = f;
     subs.push_back(f);
     inode->add_dirfrag(f);
+
+    f->prepare_new_fragment(replay);
   }
   
   // repartition dentries
@@ -854,13 +862,15 @@ void CDir::split(int bits, list<CDir*>& subs, list<Context*>& waiters, bool repl
   subfrags[0]->fnode.accounted_rstat.add_delta(zero, olddiff);
   dout(10) << "               " << subfrags[0]->fnode.accounted_fragstat << dendl;
 
-  purge_stolen(waiters, replay);
+  finish_old_fragment(waiters, replay);
 }
 
 void CDir::merge(list<CDir*>& subs, list<Context*>& waiters, bool replay)
 {
   dout(10) << "merge " << subs << dendl;
 
+  prepare_new_fragment(replay);
+
   // see if _any_ of the source frags have stale fragstat or rstat
   int stale_rstat = 0;
   int stale_fragstat = 0;
@@ -906,7 +916,7 @@ void CDir::merge(list<CDir*>& subs, list<Context*>& waiters, bool replay)
     state_set(dir->get_state() & MASK_STATE_FRAGMENT_KEPT);
     dir_auth = dir->dir_auth;
 
-    dir->purge_stolen(waiters, replay);
+    dir->finish_old_fragment(waiters, replay);
     inode->close_dirfrag(dir->get_frag());
   }
 
index 2060e98473e661e96a1eb8e4bc4284e1fad84b6c..80c68c5d097b8babe6ee28d7893e143bc39918ed 100644 (file)
@@ -370,8 +370,9 @@ public:
   }
 
 private:
+  void prepare_new_fragment(bool replay);
   void steal_dentry(CDentry *dn);  // from another dir.  used by merge/split.
-  void purge_stolen(list<Context*>& waiters, bool replay);
+  void finish_old_fragment(list<Context*>& waiters, bool replay);
   void init_fragment_pins();
 
 
index a5cf7ef6af38550d86e28fa7010b96a630d907aa..b6e3d19f6e74ad7c69d2efcee88b33496c6522d3 100644 (file)
@@ -4607,7 +4607,7 @@ void MDCache::open_snap_parents()
           q++)
        for (set<inodeno_t>::iterator r = q->second.begin();
             r != q->second.end();
-            r++)
+            r++) 
          prepare_realm_split(in->snaprealm, q->first, *r, splits);
 
       missing_snap_parents.erase(p++);
@@ -9617,7 +9617,6 @@ void MDCache::fragment_frozen(list<CDir*>& dirs, frag_t basefrag, int bits)
     // freeze and store them too
     dir->state_set(CDir::STATE_FRAGMENTING);
     dir->commit(0, gather->new_sub(), true);  // ignore authpinnability
-    dir->_freeze_dir();
   }
 
   mds->mdlog->submit_entry(le, gather->new_sub());