]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
mds: avoid calling clientreplay_done() prematurely 31282/head
authorYan, Zheng <zyan@redhat.com>
Wed, 6 Mar 2019 08:08:05 +0000 (16:08 +0800)
committerYan, Zheng <zyan@redhat.com>
Thu, 31 Oct 2019 09:24:05 +0000 (17:24 +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>
(cherry picked from commit 3ae56ab82b69929a22251f7686b60ef1ebf471d3)

 Conflicts:
src/mds/MDSRank.cc (no client state relaim code)
src/mds/MDSRank.h (trivial)

src/mds/MDSRank.cc
src/mds/MDSRank.h
src/mds/Server.cc

index 182cbcef2cf4142a2449f82eec74f26d0a476bb8..e1cbdf0720e3d28f01417f420d44cc9ef6ad71fb 100644 (file)
@@ -1952,10 +1952,12 @@ void MDSRank::rejoin_done()
     return;
   }
 
-  if (replay_queue.empty())
+  if (replay_queue.empty()) {
     request_state(MDSMap::STATE_ACTIVE);
-  else
+  } else {
+    replaying_requests_done = replay_queue.empty();
     request_state(MDSMap::STATE_CLIENTREPLAY);
+  }
 }
 
 void MDSRank::clientreplay_start()
@@ -1968,13 +1970,30 @@ void MDSRank::clientreplay_start()
 
 bool MDSRank::queue_one_replay()
 {
-  if (replay_queue.empty()) {
-    mdlog->wait_for_safe(new C_MDS_VoidFn(this, &MDSRank::clientreplay_done));
-    return false;
+  if (!replay_queue.empty()) {
+    queue_waiter(replay_queue.front());
+    replay_queue.pop_front();
+    return true;
+  }
+  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) {
+    if (replaying_requests_done) {
+      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, " << dendl;
   }
-  queue_waiter(replay_queue.front());
-  replay_queue.pop_front();
-  return true;
 }
 
 void MDSRank::clientreplay_done()
index 1124d405c830f3ec417d140b65b7a8b553a88262..e29153864880fc88aa57c99530261969dacdf585 100644 (file)
@@ -277,6 +277,8 @@ class MDSRank {
                                  waiting_for_reconnect, waiting_for_resolve;
     list<MDSInternalContextBase*> waiting_for_any_client_connection;
     list<MDSInternalContextBase*> replay_queue;
+    bool replaying_requests_done = false;
+
     map<mds_rank_t, list<MDSInternalContextBase*> > waiting_for_active_peer;
     map<epoch_t, list<MDSInternalContextBase*> > waiting_for_mdsmap;
 
@@ -431,6 +433,7 @@ class MDSRank {
     }
 
     bool queue_one_replay();
+    void maybe_clientreplay_done();
 
     void set_osd_epoch_barrier(epoch_t e);
     epoch_t get_osd_epoch_barrier() const {return osd_epoch_barrier;}
index 1ffc6a40883c0aaddd5a2cb8b5d0262d7c9800a6..0604416b24249a1be42810d557aff609c147e90e 100644 (file)
@@ -1520,8 +1520,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());