]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
mds: avoid calling clientreplay_done() prematurely 26781/head
authorYan, Zheng <zyan@redhat.com>
Wed, 6 Mar 2019 08:08:05 +0000 (16:08 +0800)
committerYan, Zheng <zyan@redhat.com>
Wed, 6 Mar 2019 08:15:26 +0000 (16:15 +0800)
maybe_clientreplay_done() does not correctly handle the case that
replayed request is in the finished_queue (hasn't been dispatched)

Fixes: https://tracker.ceph.com/issues/38597
Signed-off-by: "Yan, Zheng" <zyan@redhat.com>
src/mds/MDSRank.cc
src/mds/MDSRank.h
src/mds/Server.cc

index be90b70f57aebd49000e7844f63ea611c93873c7..8b622cab0f97171faa4c9e80296f7fc673a7b39f 100644 (file)
@@ -762,8 +762,6 @@ void MDSRankDispatcher::tick()
 
   if (is_reconnect())
     server->reconnect_tick();
-  if (is_clientreplay())
-    maybe_clientreplay_done();
 
   if (is_active()) {
     balancer->tick();
@@ -1931,10 +1929,12 @@ void MDSRank::rejoin_done()
     return;
   }
 
-  if (replay_queue.empty() && !server->get_num_pending_reclaim())
+  if (replay_queue.empty() && !server->get_num_pending_reclaim()) {
     request_state(MDSMap::STATE_ACTIVE);
-  else
+  } else {
+    replaying_requests_done = replay_queue.empty();
     request_state(MDSMap::STATE_CLIENTREPLAY);
+  }
 }
 
 void MDSRank::clientreplay_start()
@@ -1952,25 +1952,27 @@ bool MDSRank::queue_one_replay()
     replay_queue.pop_front();
     return true;
   }
-  // don't go to active if there are session waiting for being reclaimed
-  if (!server->get_num_pending_reclaim())
-    mdlog->wait_for_safe(new C_MDS_VoidFn(this, &MDSRank::clientreplay_done));
+  if (!replaying_requests_done) {
+    replaying_requests_done = true;
+    mdlog->flush();
+  }
+  maybe_clientreplay_done();
   return false;
 }
 
 void MDSRank::maybe_clientreplay_done()
 {
-  if (is_clientreplay() &&
-      get_want_state() == MDSMap::STATE_CLIENTREPLAY &&
-      replay_queue.empty()) {
-    int num_requests = mdcache->get_num_client_requests();
-    int num_reclaim = server->get_num_pending_reclaim();
-    if (!num_requests && !num_reclaim) {
-      clientreplay_done();
-    } else {
-      dout(1) << " still have " << num_requests << " active replay requests, "
-             << num_reclaim << " sessions need to be reclaimed" << dendl;
+  if (is_clientreplay() && get_want_state() == MDSMap::STATE_CLIENTREPLAY) {
+
+    // don't go to active if there are session waiting for being reclaimed
+    if (replaying_requests_done && !server->get_num_pending_reclaim()) {
+      mdlog->wait_for_safe(new C_MDS_VoidFn(this, &MDSRank::clientreplay_done));
+      return;
     }
+
+    dout(1) << " still have " << replay_queue.size() + (int)!replaying_requests_done
+           << " requests need to be replayed, " << server->get_num_pending_reclaim()
+           << " sessions need to be reclaimed" << dendl;
   }
 }
 
index 1bd598b8863114979dac461cd5e7825ab904571b..f53b764808ce905dc80b1c3d183fc83e89b2862b 100644 (file)
@@ -283,6 +283,8 @@ class MDSRank {
                                waiting_for_reconnect, waiting_for_resolve;
     MDSContext::vec waiting_for_any_client_connection;
     MDSContext::que replay_queue;
+    bool replaying_requests_done = false;
+
     map<mds_rank_t, MDSContext::vec > waiting_for_active_peer;
     map<epoch_t, MDSContext::vec > waiting_for_mdsmap;
 
index f4fa5b3fcbd9d0955e603ec61a82deab2fb25e75..92a9fdd9eb3c9066c51fcd6d6c9fabfa5e05c1a3 100644 (file)
@@ -1686,8 +1686,7 @@ void Server::journal_and_reply(MDRequestRef& mdr, CInode *in, CDentry *dn, LogEv
     if (mds->queue_one_replay()) {
       dout(10) << " queued next replay op" << dendl;
     } else {
-      dout(10) << " journaled last replay op, flushing" << dendl;
-      mdlog->flush();
+      dout(10) << " journaled last replay op" << dendl;
     }
   } else if (mdr->did_early_reply)
     mds->locker->drop_rdlocks_for_early_reply(mdr.get());