]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
mds: fix MDSTableClient ack double journaling
authorSage Weil <sage@newdream.net>
Tue, 30 Mar 2010 17:30:02 +0000 (10:30 -0700)
committerSage Weil <sage@newdream.net>
Tue, 30 Mar 2010 17:30:02 +0000 (10:30 -0700)
Do not journal ack unless the tid is registered in the LogSegment.  Once
we journal it, we remove it from the LogSegment list, and once it's
journaled, we remove the pending_commit[tid] entry.

This fixes a bug where the mds got two acks, journaled both of them, and
crashed in the completion for the second because pending_commit[tid] was
gone.  The second ack should have been ignored.

src/mds/MDSTableClient.cc

index 513b7901463592c721b8f21abbb41bcef054fbf8..05c7944f4d1bab8298b999dbe1f2f0a9955857b3 100644 (file)
@@ -85,7 +85,8 @@ void MDSTableClient::handle_request(class MMDSTableRequest *m)
     break;
 
   case TABLESERVER_OP_ACK:
-    if (pending_commit.count(tid)) {
+    if (pending_commit.count(tid) &&
+       pending_commit[tid]->pending_commit_tids[table].count(tid)) {
       dout(10) << "got ack on tid " << tid << ", logging" << dendl;
       
       assert(g_conf.mds_kill_mdstable_at != 7);
@@ -175,9 +176,10 @@ void MDSTableClient::got_journaled_agree(version_t tid, LogSegment *ls)
 void MDSTableClient::got_journaled_ack(version_t tid)
 {
   dout(10) << "got_journaled_ack " << tid << dendl;
-  if (pending_commit.count(tid))
+  if (pending_commit.count(tid)) {
     pending_commit[tid]->pending_commit_tids[table].erase(tid);
-  pending_commit.erase(tid);
+    pending_commit.erase(tid);
+  }
 }
 
 void MDSTableClient::finish_recovery()