]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
mds: fix replay of EFragment rollback
authorSage Weil <sage@newdream.net>
Sat, 30 Apr 2011 00:23:58 +0000 (17:23 -0700)
committerSage Weil <sage@newdream.net>
Sat, 30 Apr 2011 00:46:23 +0000 (17:46 -0700)
Remove from the uncommitted list.

Also, make uncommitted list updated unconditional: we need to do it even
if the inode wasn't already in our cache.

Also, journal the rollback with the same signedness as the prepare, so that
the descriptor/map key matches up.  Adjust signs accordingly.

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

index 773c885c69f7e6e5087eefd8d1faaa66c1842152..695ce557cf5225400975db45998a74eb9cf213d1 100644 (file)
@@ -9758,7 +9758,7 @@ void MDCache::rollback_uncommitted_fragments()
     if (g_conf.mds_debug_frag)
       diri->verify_dirfrags();
 
-    EFragment *le = new EFragment(mds->mdlog, EFragment::OP_ROLLBACK, diri->ino(), p->first.frag, -p->second);
+    EFragment *le = new EFragment(mds->mdlog, EFragment::OP_ROLLBACK, diri->ino(), p->first.frag, p->second);
     mds->mdlog->start_submit_entry(le);
   }
   uncommitted_fragments.clear();
index e2b737411c76a42fe7b1a63dfea362f18bfaba77..242f718ea25e0b2a0d12cac52426cea845f229d2 100644 (file)
@@ -1100,28 +1100,37 @@ void ESubtreeMap::replay(MDS *mds)
 void EFragment::replay(MDS *mds)
 {
   dout(10) << "EFragment.replay " << op_name(op) << " " << ino << " " << basefrag << " by " << bits << dendl;
-  CInode *in = mds->mdcache->get_inode(ino);
-  if (in) {
-    list<CDir*> resultfrags;
-    list<Context*> waiters;
 
-    pair<dirfrag_t,int> desc(dirfrag_t(ino,basefrag), bits);
+  list<CDir*> resultfrags;
+  list<Context*> waiters;
+  pair<dirfrag_t,int> desc(dirfrag_t(ino,basefrag), bits);
+
+  // in may be NULL if it wasn't in our cache yet.  if it's a prepare
+  // it will be once we replay the metablob , but first we need to
+  // refragment anything we already have in the cache.
+  CInode *in = mds->mdcache->get_inode(ino);
 
-    switch (op) {
-    case OP_PREPARE:
-      mds->mdcache->uncommitted_fragments.insert(desc);
-    case OP_ONESHOT:
+  switch (op) {
+  case OP_PREPARE:
+    mds->mdcache->uncommitted_fragments.insert(desc);
+  case OP_ONESHOT:
+    if (in)
       mds->mdcache->adjust_dir_fragments(in, basefrag, bits, resultfrags, waiters, true);
-      break;
+    break;
 
-    case OP_COMMIT:
-      mds->mdcache->uncommitted_fragments.erase(desc);
-      break;
+  case OP_COMMIT:
+    mds->mdcache->uncommitted_fragments.erase(desc);
+    break;
 
-    case OP_ROLLBACK:
-      mds->mdcache->adjust_dir_fragments(in, basefrag, bits, resultfrags, waiters, true);
-      break;
+  case OP_ROLLBACK:
+    if (mds->mdcache->uncommitted_fragments.count(desc)) {
+      mds->mdcache->uncommitted_fragments.erase(desc);
+      assert(in);
+      mds->mdcache->adjust_dir_fragments(in, basefrag, -bits, resultfrags, waiters, true);
+    } else {
+      dout(10) << " no record of prepare for " << desc << dendl;
     }
+    break;
   }
   metablob.replay(mds, _segment);
   if (in && g_conf.mds_debug_frag)