From: Yan, Zheng Date: Tue, 28 Jul 2020 08:39:53 +0000 (+0800) Subject: mds: cleanup code that purges orphan objects created by lost unsafe file creation X-Git-Tag: v17.1.0~2726^2~3 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=e48d6cba9351ccc64985ddda5fb98545823d0a4a;p=ceph.git mds: cleanup code that purges orphan objects created by lost unsafe file creation Signed-off-by: "Yan, Zheng" --- diff --git a/src/mds/LogSegment.h b/src/mds/LogSegment.h index 93d88d61860e..a7f3f39710d2 100644 --- a/src/mds/LogSegment.h +++ b/src/mds/LogSegment.h @@ -53,9 +53,9 @@ class LogSegment { void try_to_expire(MDSRank *mds, MDSGatherBuilder &gather_bld, int op_prio); void purge_inodes_finish(interval_set& inos){ - purge_inodes.subtract(inos); + purging_inodes.subtract(inos); if (NULL != purged_cb && - purge_inodes.empty()) + purging_inodes.empty()) purged_cb->complete(0); } void set_purged_cb(MDSContext* c){ @@ -84,7 +84,7 @@ class LogSegment { elist dirty_dirfrag_dirfragtree; set truncating_inodes; - interval_set purge_inodes; + interval_set purging_inodes; MDSContext* purged_cb = nullptr; map > pending_commit_tids; // mdstable diff --git a/src/mds/MDCache.cc b/src/mds/MDCache.cc index ad7a8f5be0cd..e392aad93fbb 100644 --- a/src/mds/MDCache.cc +++ b/src/mds/MDCache.cc @@ -6618,24 +6618,19 @@ void MDCache::start_recovered_truncates() class C_MDS_purge_completed_finish : public MDCacheLogContext { interval_set inos; - version_t inotablev; LogSegment *ls; + version_t inotablev; public: - C_MDS_purge_completed_finish(MDCache *m, - interval_set i, - version_t iv, - LogSegment *_ls) - : MDCacheLogContext(m), - inos(std::move(i)), - inotablev(iv), - ls(_ls) {} + C_MDS_purge_completed_finish(MDCache *m, const interval_set& _inos, + LogSegment *_ls, version_t iv) + : MDCacheLogContext(m), inos(_inos), ls(_ls), inotablev(iv) {} void finish(int r) override { assert(r == 0); if (inotablev) { - ls->purge_inodes_finish(inos); - mdcache->mds->inotable->apply_release_ids(inos); - assert(mdcache->mds->inotable->get_version() == inotablev); + get_mds()->inotable->apply_release_ids(inos); + assert(get_mds()->inotable->get_version() == inotablev); } + ls->purge_inodes_finish(inos); } }; @@ -6643,46 +6638,34 @@ void MDCache::start_purge_inodes(){ dout(10) << "start_purge_inodes" << dendl; for (auto& p : mds->mdlog->segments){ LogSegment *ls = p.second; - if (ls->purge_inodes.size()){ - purge_inodes(ls->purge_inodes, ls); + if (ls->purging_inodes.size()){ + purge_inodes(ls->purging_inodes, ls); } } } void MDCache::purge_inodes(const interval_set& inos, LogSegment *ls) { + dout(10) << __func__ << " purging inos " << inos << " logseg " << ls->seq << dendl; + // FIXME: handle non-default data pool and namespace + auto cb = new LambdaContext([this, inos, ls](int r){ assert(r == 0 || r == -2); mds->inotable->project_release_ids(inos); version_t piv = mds->inotable->get_projected_version(); assert(piv != 0); - mds->mdlog->start_submit_entry(new EPurged(inos, piv, ls->seq), - new C_MDS_purge_completed_finish(this, inos, piv, ls)); + mds->mdlog->start_submit_entry(new EPurged(inos, ls->seq, piv), + new C_MDS_purge_completed_finish(this, inos, ls, piv)); mds->mdlog->flush(); }); - dout(10) << __func__ << " start purge data : " << inos << dendl; C_GatherBuilder gather(g_ceph_context, - new C_OnFinisher( new MDSIOContextWrapper(mds, cb), mds->finisher)); + new C_OnFinisher(new MDSIOContextWrapper(mds, cb), mds->finisher)); SnapContext nullsnapc; - uint64_t num = Striper::get_num_objects(default_file_layout, default_file_layout.get_period()); - for (auto p = inos.begin(); - p != inos.end(); - ++p){ - dout(10) << __func__ - << " prealloc_inos : " << inos.size() - << " start : " << p.get_start().val - << " length : " << p.get_len() << " " - << " seq : " << ls->seq << dendl; - - for (_inodeno_t i = 0; i < p.get_len(); i++){ - dout(20) << __func__ << " : " << p.get_start() + i << dendl; - filer.purge_range(p.get_start() + i, - &default_file_layout, - nullsnapc, - 0, num, - ceph::real_clock::now(), - 0, gather.new_sub()); + for (const auto& [start, len] : inos) { + for (auto i = start; i < start + len ; i += 1) { + filer.purge_range(i, &default_file_layout, nullsnapc, 0, 1, + ceph::real_clock::now(), 0, gather.new_sub()); } } gather.activate(); diff --git a/src/mds/Server.cc b/src/mds/Server.cc index 8e18c33ed7b5..232bb6b3d537 100644 --- a/src/mds/Server.cc +++ b/src/mds/Server.cc @@ -362,22 +362,26 @@ class C_MDS_session_finish : public ServerLogContext { uint64_t state_seq; bool open; version_t cmapv; - interval_set inos; + interval_set inos_to_free; version_t inotablev; - interval_set purge_inos; + interval_set inos_to_purge; LogSegment *ls = nullptr; Context *fin; public: - C_MDS_session_finish(Server *srv, Session *se, uint64_t sseq, bool s, version_t mv, Context *fin_ = NULL) : + 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, interval_set i, version_t iv, Context *fin_ = NULL) : - ServerLogContext(srv), session(se), state_seq(sseq), open(s), cmapv(mv), inos(std::move(i)), inotablev(iv), fin(fin_) { } - C_MDS_session_finish(Server *srv, Session *se, uint64_t sseq, bool s, version_t mv, interval_set i, version_t iv, - interval_set _purge_inos, LogSegment *_ls, Context *fin_ = NULL) : - ServerLogContext(srv), session(se), state_seq(sseq), open(s), cmapv(mv), inos(std::move(i)), inotablev(iv), purge_inos(std::move(_purge_inos)), ls(_ls), 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) : + ServerLogContext(srv), session(se), state_seq(sseq), open(s), cmapv(mv), + inos_to_free(to_free), inotablev(iv), inos_to_purge(to_purge), ls(_ls), fin(fin_) {} void finish(int r) override { ceph_assert(r == 0); - server->_session_logged(session, state_seq, open, cmapv, inos, inotablev, purge_inos, ls); + server->_session_logged(session, state_seq, open, cmapv, inos_to_free, inotablev, inos_to_purge, ls); if (fin) { fin->complete(r); } @@ -799,30 +803,28 @@ void Server::finish_flush_session(Session *session, version_t seq) } void Server::_session_logged(Session *session, uint64_t state_seq, bool open, version_t pv, - const interval_set& inos, version_t piv, - const interval_set& purge_inos, LogSegment *ls) + const interval_set& inos_to_free, version_t piv, + const interval_set& inos_to_purge, LogSegment *ls) { dout(10) << "_session_logged " << session->info.inst << " state_seq " << state_seq - << " " << (open ? "open":"close") - << " " << pv - << " purge_inos : " << purge_inos << dendl; + << " " << (open ? "open":"close") << " " << pv + << " inos_to_free " << inos_to_free << " inotablev " << piv + << " inos_to_purge " << inos_to_purge << dendl; - if (NULL != ls) { - dout(10) << "_session_logged seq : " << ls->seq << dendl; - if (purge_inos.size()){ - session->info.prealloc_inos.subtract(purge_inos); - ls->purge_inodes.insert(purge_inos); - mdcache->purge_inodes(purge_inos, ls); - } + if (inos_to_purge.size()){ + ceph_assert(ls); + session->info.prealloc_inos.subtract(inos_to_purge); + ls->purging_inodes.insert(inos_to_purge); + mdcache->purge_inodes(inos_to_purge, ls); } if (piv) { ceph_assert(session->is_closing() || session->is_killing() || session->is_opening()); // re-open closing session - session->info.prealloc_inos.subtract(inos); + session->info.prealloc_inos.subtract(inos_to_free); session->delegated_inos.clear(); - mds->inotable->apply_release_ids(inos); + mds->inotable->apply_release_ids(inos_to_free); ceph_assert(mds->inotable->get_version() == piv); } diff --git a/src/mds/Server.h b/src/mds/Server.h index 5d9daf335c0a..0074c4ff1ead 100644 --- a/src/mds/Server.h +++ b/src/mds/Server.h @@ -118,9 +118,9 @@ public: } void handle_client_session(const cref_t &m); - void _session_logged(Session *session, uint64_t state_seq, - bool open, version_t pv, const interval_set& inos,version_t piv, - const interval_set& purge_inos, LogSegment *ls); + void _session_logged(Session *session, uint64_t state_seq, bool open, version_t pv, + const interval_set& inos_to_free, version_t piv, + const interval_set& inos_to_purge, LogSegment *ls); version_t prepare_force_open_sessions(map &cm, map& cmm, map >& smap); diff --git a/src/mds/events/EPurged.h b/src/mds/events/EPurged.h index beaf10d415b7..cda1b2ecf2df 100644 --- a/src/mds/events/EPurged.h +++ b/src/mds/events/EPurged.h @@ -21,30 +21,25 @@ #include "../LogEvent.h" class EPurged : public LogEvent { - - protected: - interval_set inos; - version_t inotablev{0}; - LogSegment::seq_t seq; - public: - EPurged() : LogEvent(EVENT_PURGED) { - } - EPurged(interval_set i, version_t iv, LogSegment::seq_t _seq = 0) : - LogEvent(EVENT_PURGED), inos(std::move(i)), inotablev(iv), seq(_seq) { - } - void encode(bufferlist& bl, uint64_t features) const override; - void decode(bufferlist::const_iterator& bl) override; - void dump(Formatter *f) const override; - void print(ostream& out) const override { - - if (inotablev) - out << "Eurge complete"; - else - out << "Eurge inodes "; - } - - void update_segment() override; - void replay(MDSRank *mds) override; +public: + EPurged() : LogEvent(EVENT_PURGED) { } + EPurged(const interval_set& _inos, LogSegment::seq_t _seq, version_t iv) + : LogEvent(EVENT_PURGED), inos(_inos), seq(_seq), inotablev(iv) { + } + void encode(bufferlist& bl, uint64_t features) const override; + void decode(bufferlist::const_iterator& bl) override; + void dump(Formatter *f) const override; + void print(ostream& out) const override { + out << "Eurged " << inos.size() << " inos, inotable v" << inotablev; + } + + void update_segment() override; + void replay(MDSRank *mds) override; + +protected: + interval_set inos; + LogSegment::seq_t seq; + version_t inotablev{0}; }; WRITE_CLASS_ENCODER_FEATURES(EPurged) diff --git a/src/mds/events/ESession.h b/src/mds/events/ESession.h index d3e07982e385..c6586e3b5756 100644 --- a/src/mds/events/ESession.h +++ b/src/mds/events/ESession.h @@ -26,10 +26,10 @@ class ESession : public LogEvent { bool open; // open or close version_t cmapv{0}; // client map version - interval_set inos; + interval_set inos_to_free; version_t inotablev{0}; - interval_set purge_inos; + interval_set inos_to_purge; // Client metadata stored during open client_metadata_t client_metadata; @@ -42,11 +42,10 @@ class ESession : public LogEvent { client_inst(inst), open(o), cmapv(v), inotablev(0), client_metadata(cm) { } ESession(const entity_inst_t& inst, bool o, version_t v, - interval_set i, version_t iv, - interval_set _purge_inos) : - LogEvent(EVENT_SESSION), - client_inst(inst), open(o), cmapv(v), inos(std::move(i)), inotablev(iv), - purge_inos(std::move(_purge_inos)) {} + const interval_set& to_free, version_t iv, + const interval_set& to_purge) : + LogEvent(EVENT_SESSION), client_inst(inst), open(o), cmapv(v), + inos_to_free(to_free), inotablev(iv), inos_to_purge(to_purge) {} void encode(bufferlist& bl, uint64_t features) const override; void decode(bufferlist::const_iterator& bl) override; @@ -58,8 +57,9 @@ class ESession : public LogEvent { out << "ESession " << client_inst << " open cmapv " << cmapv; else out << "ESession " << client_inst << " close cmapv " << cmapv; - if (inos.size()) - out << " (" << inos.size() << " inos, v" << inotablev << ")"; + if (inos_to_free.size() || inos_to_purge.size()) + out << " (" << inos_to_free.size() << " to free, v" << inotablev + << ", " << inos_to_purge.size() << " to purge)"; } void update_segment() override; diff --git a/src/mds/journal.cc b/src/mds/journal.cc index e17874650663..67a9d6375a00 100644 --- a/src/mds/journal.cc +++ b/src/mds/journal.cc @@ -312,8 +312,8 @@ void LogSegment::try_to_expire(MDSRank *mds, MDSGatherBuilder &gather_bld, int o (*p)->add_waiter(CInode::WAIT_TRUNC, gather_bld.new_sub()); } // purge inodes - dout(10) << "try_to_expire waiting for purge of " << purge_inodes << dendl; - if (purge_inodes.size()) + dout(10) << "try_to_expire waiting for purge of " << purging_inodes << dendl; + if (purging_inodes.size()) set_purged_cb(gather_bld.new_sub()); if (gather_bld.has_subs()) { @@ -1720,9 +1720,9 @@ void EPurged::replay(MDSRank *mds) { if (inos.size()) { LogSegment *ls = mds->mdlog->get_segment(seq); - if (ls) { - ls->purge_inodes.subtract(inos); - } + if (ls) + ls->purging_inodes.subtract(inos); + if (mds->inotable->get_version() >= inotablev) { dout(10) << "EPurged.replay inotable " << mds->inotable->get_version() << " >= " << inotablev << ", noop" << dendl; @@ -1767,14 +1767,14 @@ void EPurged::dump(Formatter *f) const void ESession::update_segment() { get_segment()->sessionmapv = cmapv; - if (inos.size() && inotablev) + if (inos_to_free.size() && inotablev) get_segment()->inotablev = inotablev; } void ESession::replay(MDSRank *mds) { - if (purge_inos.size()) - get_segment()->purge_inodes.insert(purge_inos); + if (inos_to_purge.size()) + get_segment()->purging_inodes.insert(inos_to_purge); if (mds->sessionmap.get_version() >= cmapv) { dout(10) << "ESession.replay sessionmap " << mds->sessionmap.get_version() @@ -1818,7 +1818,7 @@ void ESession::replay(MDSRank *mds) mds->sessionmap.set_version(cmapv); } - if (inos.size() && inotablev) { + if (inos_to_free.size() && inotablev) { if (mds->inotable->get_version() >= inotablev) { dout(10) << "ESession.replay inotable " << mds->inotable->get_version() << " >= " << inotablev << ", noop" << dendl; @@ -1826,7 +1826,7 @@ void ESession::replay(MDSRank *mds) dout(10) << "ESession.replay inotable " << mds->inotable->get_version() << " < " << inotablev << " " << (open ? "add":"remove") << dendl; ceph_assert(!open); // for now - mds->inotable->replay_release_ids(inos); + mds->inotable->replay_release_ids(inos_to_free); ceph_assert(mds->inotable->get_version() == inotablev); } } @@ -1841,10 +1841,10 @@ void ESession::encode(bufferlist &bl, uint64_t features) const encode(client_inst, bl, features); encode(open, bl); encode(cmapv, bl); - encode(inos, bl); + encode(inos_to_free, bl); encode(inotablev, bl); encode(client_metadata, bl); - encode(purge_inos, bl); + encode(inos_to_purge, bl); ENCODE_FINISH(bl); } @@ -1856,7 +1856,7 @@ void ESession::decode(bufferlist::const_iterator &bl) decode(client_inst, bl); decode(open, bl); decode(cmapv, bl); - decode(inos, bl); + decode(inos_to_free, bl); decode(inotablev, bl); if (struct_v == 4) { decode(client_metadata.kv_map, bl); @@ -1864,7 +1864,7 @@ void ESession::decode(bufferlist::const_iterator &bl) decode(client_metadata, bl); } if (struct_v >= 6){ - decode(purge_inos, bl); + decode(inos_to_purge, bl); } DECODE_FINISH(bl); @@ -1875,9 +1875,10 @@ void ESession::dump(Formatter *f) const f->dump_stream("client instance") << client_inst; f->dump_string("open", open ? "true" : "false"); f->dump_int("client map version", cmapv); - f->dump_stream("inos") << inos; + f->dump_stream("inos_to_free") << inos_to_free; f->dump_int("inotable version", inotablev); f->open_object_section("client_metadata"); + f->dump_stream("inos_to_purge") << inos_to_purge; client_metadata.dump(f); f->close_section(); // client_metadata }