From: Yan, Zheng Date: Wed, 6 Mar 2019 08:08:05 +0000 (+0800) Subject: mds: avoid calling clientreplay_done() prematurely X-Git-Tag: v13.2.9~23^2 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=dacdee1876f4dec8e95e46e6b50c884c134c2343;p=ceph.git mds: avoid calling clientreplay_done() prematurely 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" (cherry picked from commit 3ae56ab82b69929a22251f7686b60ef1ebf471d3) Conflicts: src/mds/MDSRank.cc (no client state relaim code) src/mds/MDSRank.h (trivial) --- diff --git a/src/mds/MDSRank.cc b/src/mds/MDSRank.cc index 182cbcef2cf..e1cbdf0720e 100644 --- a/src/mds/MDSRank.cc +++ b/src/mds/MDSRank.cc @@ -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() diff --git a/src/mds/MDSRank.h b/src/mds/MDSRank.h index 1124d405c83..e2915386488 100644 --- a/src/mds/MDSRank.h +++ b/src/mds/MDSRank.h @@ -277,6 +277,8 @@ class MDSRank { waiting_for_reconnect, waiting_for_resolve; list waiting_for_any_client_connection; list replay_queue; + bool replaying_requests_done = false; + map > waiting_for_active_peer; map > 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;} diff --git a/src/mds/Server.cc b/src/mds/Server.cc index 1ffc6a40883..0604416b242 100644 --- a/src/mds/Server.cc +++ b/src/mds/Server.cc @@ -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());