From: Yan, Zheng Date: Tue, 28 Jul 2020 09:27:18 +0000 (+0800) Subject: mds: purge orphan objects created by lost async file creation X-Git-Tag: v17.1.0~2726^2~1 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=a7a1b0a3224ff1efae15f071357bb0b4ff488f9c;p=ceph.git mds: purge orphan objects created by lost async file creation Signed-off-by: "Yan, Zheng" --- diff --git a/src/mds/Server.cc b/src/mds/Server.cc index 19c5d1f8a45a..61a67d8a50ec 100644 --- a/src/mds/Server.cc +++ b/src/mds/Server.cc @@ -297,7 +297,14 @@ void Server::dispatch(const cref_t &m) queue_replay = true; if (req->head.ino && !session->have_completed_request(req->get_reqid().tid, nullptr)) { - mdcache->add_replay_ino_alloc(inodeno_t(req->head.ino)); + inodeno_t ino(req->head.ino); + mdcache->add_replay_ino_alloc(ino); + if (replay_unsafe_with_closed_session && + session->free_prealloc_inos.contains(ino)) { + // don't purge inodes that will be created by later replay + session->free_prealloc_inos.erase(ino); + session->delegated_inos.insert(ino); + } } } else if (req->get_retry_attempt()) { // process completed request in clientreplay stage. The completed request @@ -370,10 +377,6 @@ class C_MDS_session_finish : public ServerLogContext { public: C_MDS_session_finish(Server *srv, Session *se, uint64_t sseq, bool s, version_t mv, Context *fin_ = nullptr) : ServerLogContext(srv), session(se), state_seq(sseq), open(s), cmapv(mv), inotablev(0), fin(fin_) { } - C_MDS_session_finish(Server *srv, Session *se, uint64_t sseq, bool s, version_t mv, - const interval_set& to_free, version_t iv, Context *fin_ = nullptr) : - ServerLogContext(srv), session(se), state_seq(sseq), open(s), cmapv(mv), - inos_to_free(to_free), inotablev(iv), fin(fin_) { } C_MDS_session_finish(Server *srv, Session *se, uint64_t sseq, bool s, version_t mv, const interval_set& to_free, version_t iv, const interval_set& to_purge, LogSegment *_ls, Context *fin_ = nullptr) : @@ -1255,7 +1258,7 @@ void Server::handle_conf_change(const std::set& changed) { * XXX bump in the interface here, not using an MDSContext here * because all the callers right now happen to use a SaferCond */ -void Server::kill_session(Session *session, Context *on_safe, bool need_purge_inos) +void Server::kill_session(Session *session, Context *on_safe) { ceph_assert(ceph_mutex_is_locked_by_me(mds->mds_lock)); @@ -1264,7 +1267,7 @@ void Server::kill_session(Session *session, Context *on_safe, bool need_purge_in session->is_stale()) && !session->is_importing()) { dout(10) << "kill_session " << session << dendl; - journal_close_session(session, Session::STATE_KILLING, on_safe, need_purge_inos); + journal_close_session(session, Session::STATE_KILLING, on_safe); } else { dout(10) << "kill_session importing or already closing/killing " << session << dendl; if (session->is_closing() || @@ -1322,12 +1325,13 @@ size_t Server::apply_blocklist(const std::set &blocklist) return victims.size(); } -void Server::journal_close_session(Session *session, int state, Context *on_safe, bool need_purge_inos) +void Server::journal_close_session(Session *session, int state, Context *on_safe) { dout(10) << __func__ << " : " - << "("<< need_purge_inos << ")" << session->info.inst - << "(" << session->info.prealloc_inos.size() << "|" << session->pending_prealloc_inos.size() << ")" << dendl; + << " pending_prealloc_inos " << session->pending_prealloc_inos + << " free_prealloc_inos " << session->free_prealloc_inos + << " delegated_inos " << session->delegated_inos << dendl; uint64_t sseq = mds->sessionmap.set_state(session, state); version_t pv = mds->sessionmap.mark_projected(session); @@ -1335,29 +1339,19 @@ void Server::journal_close_session(Session *session, int state, Context *on_safe // release alloc and pending-alloc inos for this session // and wipe out session state, in case the session close aborts for some reason - interval_set both; - both.insert(session->pending_prealloc_inos); - if (!need_purge_inos) - both.insert(session->info.prealloc_inos); - if (both.size()) { - mds->inotable->project_release_ids(both); + interval_set inos_to_free; + inos_to_free.insert(session->pending_prealloc_inos); + inos_to_free.insert(session->free_prealloc_inos); + if (inos_to_free.size()) { + mds->inotable->project_release_ids(inos_to_free); piv = mds->inotable->get_projected_version(); } else piv = 0; - if(need_purge_inos && session->info.prealloc_inos.size()) { - dout(10) << "start purge indoes " << session->info.prealloc_inos << dendl; - LogSegment* ls = mdlog->get_current_segment(); - LogEvent* e = new ESession(session->info.inst, false, pv, both, piv, session->info.prealloc_inos); - MDSLogContextBase* c = new C_MDS_session_finish(this, session, sseq, false, pv, both, piv, - session->info.prealloc_inos, ls, on_safe); - mdlog->start_submit_entry(e, c); - } else { - interval_set empty; - LogEvent* e = new ESession(session->info.inst, false, pv, both, piv, empty); - MDSLogContextBase* c = new C_MDS_session_finish(this, session, sseq, false, pv, both, piv, on_safe); - mdlog->start_submit_entry(e, c); - } + auto le = new ESession(session->info.inst, false, pv, inos_to_free, piv, session->delegated_inos); + auto fin = new C_MDS_session_finish(this, session, sseq, false, pv, inos_to_free, piv, + session->delegated_inos, mdlog->get_current_segment(), on_safe); + mdlog->start_submit_entry(le, fin); mdlog->flush(); // clean up requests, too @@ -1703,12 +1697,15 @@ void Server::reconnect_tick() << ", after waiting " << elapse1 << " seconds during MDS startup"; + // make _session_logged() purge orphan objects of lost async/unsafe requests + session->delegated_inos.swap(session->free_prealloc_inos); + if (g_conf()->mds_session_blocklist_on_timeout) { CachedStackStringStream css; mds->evict_client(session->get_client().v, false, true, *css, gather.new_sub()); } else { - kill_session(session, NULL, true); + kill_session(session, NULL); } failed_reconnects++; diff --git a/src/mds/Server.h b/src/mds/Server.h index 0074c4ff1ead..2021ec53e33f 100644 --- a/src/mds/Server.h +++ b/src/mds/Server.h @@ -130,9 +130,10 @@ public: void finish_flush_session(Session *session, version_t seq); void terminate_sessions(); void find_idle_sessions(); - void kill_session(Session *session, Context *on_safe, bool need_purge_inos = false); + + void kill_session(Session *session, Context *on_safe); size_t apply_blocklist(const std::set &blocklist); - void journal_close_session(Session *session, int state, Context *on_safe, bool need_purge_inos = false); + void journal_close_session(Session *session, int state, Context *on_safe); size_t get_num_pending_reclaim() const { return client_reclaim_gather.size(); } Session *find_session_by_uuid(std::string_view uuid);