From: Venky Shankar Date: Mon, 5 Nov 2018 05:10:15 +0000 (-0500) Subject: mds: introduce C_ExecAndReply context completion class X-Git-Tag: v14.1.0~502^2~6 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=9ac1c28b131eb872f433f145a36011ac8451e964;p=ceph.git mds: introduce C_ExecAndReply context completion class Tell commands that need to asynchronous reply back can subclass C_ExecAndReply() and implement exec() virtual function to support asynchronous execution of the command (via finisher thread). Signed-off-by: Venky Shankar --- diff --git a/src/mds/MDSRank.cc b/src/mds/MDSRank.cc index d126c0131983..f9230cafa11c 100644 --- a/src/mds/MDSRank.cc +++ b/src/mds/MDSRank.cc @@ -2578,6 +2578,45 @@ public: } }; +class C_ExecAndReply : public C_MDS_Send_Command_Reply { +public: + C_ExecAndReply(MDSRank *mds, const MCommand::const_ref &m) + : C_MDS_Send_Command_Reply(mds, m), f(true) { + } + + void finish(int r) override { + std::stringstream ds; + std::stringstream ss; + if (r != 0) { + f.flush(ss); + } else { + f.flush(ds); + } + + send(r, ss.str(), ds); + } + + virtual void exec() = 0; + +protected: + JSONFormatter f; +}; + +class C_CacheDropExecAndReply : public C_ExecAndReply { +public: + C_CacheDropExecAndReply(MDSRank *mds, const MCommand::const_ref &m, + uint64_t timeout) + : C_ExecAndReply(mds, m), timeout(timeout) { + } + + void exec() override { + mds->command_cache_drop(timeout, &f, this); + } + +private: + uint64_t timeout; +}; + /** * This function drops the mds_lock, so don't do anything with * MDSRank after calling it (we could have gone into shutdown): just @@ -3299,6 +3338,12 @@ void MDSRank::bcast_mds_map() last_client_mdsmap_bcast = mdsmap->get_epoch(); } +Context *MDSRank::create_async_exec_context(C_ExecAndReply *ctx) { + return new C_OnFinisher(new FunctionContext([ctx](int _) { + ctx->exec(); + }), finisher); +} + MDSRankDispatcher::MDSRankDispatcher( mds_rank_t whoami_, Mutex &mds_lock_, @@ -3381,40 +3426,15 @@ bool MDSRankDispatcher::handle_command( timeout = 0; } - JSONFormatter *f = new JSONFormatter(true); - C_MDS_Send_Command_Reply *reply = new C_MDS_Send_Command_Reply(this, m); - Context *on_finish = new FunctionContext([this, f, reply](int r) { - cache_drop_send_reply(f, reply, r); - delete f; - delete reply; - }); - *need_reply = false; - *run_later = new C_OnFinisher( - new FunctionContext([this, timeout, f, on_finish](int _) { - command_cache_drop((uint64_t)timeout, f, on_finish); - }), finisher); - + *run_later = create_async_exec_context(new C_CacheDropExecAndReply + (this, m, (uint64_t)timeout)); return true; } else { return false; } } -void MDSRank::cache_drop_send_reply(Formatter *f, C_MDS_Send_Command_Reply *reply, int r) { - dout(20) << __func__ << ": r=" << r << dendl; - - std::stringstream ds; - std::stringstream ss; - if (r != 0) { - f->flush(ss); - } else { - f->flush(ds); - } - - reply->send(r, ss.str(), ds); -} - void MDSRank::command_cache_drop(uint64_t timeout, Formatter *f, Context *on_finish) { dout(20) << __func__ << dendl; diff --git a/src/mds/MDSRank.h b/src/mds/MDSRank.h index 93dbdd9a4d02..2ca8c50bcfbd 100644 --- a/src/mds/MDSRank.h +++ b/src/mds/MDSRank.h @@ -119,6 +119,7 @@ class MonClient; class Finisher; class ScrubStack; class C_MDS_Send_Command_Reply; +class C_ExecAndReply; /** * The public part of this class's interface is what's exposed to all @@ -138,6 +139,8 @@ class MDSRank { friend class C_Flush_Journal; friend class C_Drop_Cache; + friend class C_CacheDropExecAndReply; + mds_rank_t get_nodeid() const { return whoami; } int64_t get_metadata_pool(); @@ -481,8 +484,6 @@ class MDSRank { void command_openfiles_ls(Formatter *f); void command_dump_tree(const cmdmap_t &cmdmap, std::ostream &ss, Formatter *f); void command_dump_inode(Formatter *f, const cmdmap_t &cmdmap, std::ostream &ss); - - void cache_drop_send_reply(Formatter *f, C_MDS_Send_Command_Reply *reply, int r); void command_cache_drop(uint64_t timeout, Formatter *f, Context *on_finish); protected: @@ -559,6 +560,9 @@ class MDSRank { void set_mdsmap_multimds_snaps_allowed(); private: mono_time starttime = mono_clock::zero(); + +protected: + Context *create_async_exec_context(C_ExecAndReply *ctx); }; /* This expects to be given a reference which it is responsible for.