From: Milind Changire Date: Tue, 10 Jun 2025 14:40:30 +0000 (+0530) Subject: mds: add ref counting to LogSegment X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=fe3b4159b82f65ef3ba7df1b123f126d50954a78;p=ceph.git mds: add ref counting to LogSegment Fixes: https://tracker.ceph.com/issues/70723 Signed-off-by: Milind Changire --- diff --git a/src/mds/CDentry.cc b/src/mds/CDentry.cc index 280da26eebb..d373f82aa22 100644 --- a/src/mds/CDentry.cc +++ b/src/mds/CDentry.cc @@ -233,7 +233,7 @@ version_t CDentry::pre_dirty(version_t min) } -void CDentry::_mark_dirty(LogSegment *ls) +void CDentry::_mark_dirty(LogSegmentRef const& ls) { // state+pin if (!state_test(STATE_DIRTY)) { @@ -247,7 +247,7 @@ void CDentry::_mark_dirty(LogSegment *ls) ls->dirty_dentries.push_back(&item_dirty); } -void CDentry::mark_dirty(version_t pv, LogSegment *ls) +void CDentry::mark_dirty(version_t pv, LogSegmentRef const& ls) { dout(10) << __func__ << " " << *this << dendl; diff --git a/src/mds/CDentry.h b/src/mds/CDentry.h index 07766fbaf78..26c56fc2d3b 100644 --- a/src/mds/CDentry.h +++ b/src/mds/CDentry.h @@ -28,6 +28,7 @@ #include "MDSCacheObject.h" #include "SimpleLock.h" #include "LocalLockC.h" +#include "LogSegmentRef.h" class filepath; class BatchOp; @@ -263,8 +264,8 @@ public: mds_authority_t authority() const override; version_t pre_dirty(version_t min=0); - void _mark_dirty(LogSegment *ls); - void mark_dirty(version_t pv, LogSegment *ls); + void _mark_dirty(LogSegmentRef const& ls); + void mark_dirty(version_t pv, LogSegmentRef const& ls); void mark_clean(); void mark_new(); @@ -302,7 +303,7 @@ public: void abort_export() { put(PIN_TEMPEXPORTING); } - void decode_import(ceph::buffer::list::const_iterator& blp, LogSegment *ls) { + void decode_import(ceph::buffer::list::const_iterator& blp, LogSegmentRef const& ls) { DECODE_START(1, blp); decode(first, blp); __u32 nstate; diff --git a/src/mds/CDir.cc b/src/mds/CDir.cc index b5a694a5c48..321d059af71 100644 --- a/src/mds/CDir.cc +++ b/src/mds/CDir.cc @@ -1515,7 +1515,7 @@ CDir::fnode_ptr CDir::project_fnode(const MutationRef& mut) return pf; } -void CDir::pop_and_dirty_projected_fnode(LogSegment *ls, const MutationRef& mut) +void CDir::pop_and_dirty_projected_fnode(LogSegmentRef const& ls, const MutationRef& mut) { ceph_assert(!projected_fnode.empty()); auto pf = std::move(projected_fnode.front()); @@ -1538,7 +1538,7 @@ version_t CDir::pre_dirty(version_t min) return projected_version; } -void CDir::mark_dirty(LogSegment *ls, version_t pv) +void CDir::mark_dirty(LogSegmentRef const& ls, version_t pv) { ceph_assert(is_auth()); @@ -1552,7 +1552,7 @@ void CDir::mark_dirty(LogSegment *ls, version_t pv) _mark_dirty(ls); } -void CDir::_mark_dirty(LogSegment *ls) +void CDir::_mark_dirty(LogSegmentRef const& ls) { if (!state_test(STATE_DIRTY)) { dout(10) << __func__ << " (was clean) " << *this << " version " << get_version() << dendl; @@ -1570,7 +1570,7 @@ void CDir::_mark_dirty(LogSegment *ls) } } -void CDir::mark_new(LogSegment *ls) +void CDir::mark_new(LogSegmentRef const& ls) { ls->new_dirfrags.push_back(&item_new); state_clear(STATE_CREATING); @@ -3189,7 +3189,7 @@ void CDir::finish_export() dirty_old_rstat.clear(); } -void CDir::decode_import(bufferlist::const_iterator& blp, LogSegment *ls) +void CDir::decode_import(bufferlist::const_iterator& blp, LogSegmentRef const& ls) { DECODE_START(1, blp); decode(first, blp); diff --git a/src/mds/CDir.h b/src/mds/CDir.h index c98b893e0f7..0088ca8fcad 100644 --- a/src/mds/CDir.h +++ b/src/mds/CDir.h @@ -33,6 +33,7 @@ #include "CInode.h" #include "MDSCacheObject.h" #include "Mutation.h" // for struct MDLockCache +#include "LogSegmentRef.h" struct DirStat; struct session_info_t; @@ -280,21 +281,21 @@ public: fnode_ptr project_fnode(const MutationRef& mut); - void pop_and_dirty_projected_fnode(LogSegment *ls, const MutationRef& mut); + void pop_and_dirty_projected_fnode(LogSegmentRef const& ls, const MutationRef& mut); bool is_projected() const { return !projected_fnode.empty(); } version_t pre_dirty(version_t min=0); - void _mark_dirty(LogSegment *ls); + void _mark_dirty(LogSegmentRef const& ls); void _set_dirty_flag() { if (!state_test(STATE_DIRTY)) { state_set(STATE_DIRTY); get(PIN_DIRTY); } } - void mark_dirty(LogSegment *ls, version_t pv=0); + void mark_dirty(LogSegmentRef const& ls, version_t pv=0); void mark_clean(); bool is_new() { return item_new.is_on_list(); } - void mark_new(LogSegment *ls); + void mark_new(LogSegmentRef const& ls); bool is_bad() { return state_test(STATE_BADFRAG); } @@ -524,7 +525,7 @@ public: void abort_export() { put(PIN_TEMPEXPORTING); } - void decode_import(ceph::buffer::list::const_iterator& blp, LogSegment *ls); + void decode_import(ceph::buffer::list::const_iterator& blp, LogSegmentRef const& ls); void abort_import(); // -- auth pins -- diff --git a/src/mds/CInode.cc b/src/mds/CInode.cc index e538a759f95..493f99472ef 100644 --- a/src/mds/CInode.cc +++ b/src/mds/CInode.cc @@ -515,7 +515,7 @@ CInode::projected_inode CInode::project_inode(const MutationRef& mut, return projected_inode(std::move(pi), std::move(px), ps); } -void CInode::pop_and_dirty_projected_inode(LogSegment *ls, const MutationRef& mut) +void CInode::pop_and_dirty_projected_inode(LogSegmentRef const& ls, const MutationRef& mut) { ceph_assert(!projected_nodes.empty()); auto front = std::move(projected_nodes.front()); @@ -1157,7 +1157,7 @@ version_t CInode::pre_dirty() return pv; } -void CInode::_mark_dirty(LogSegment *ls) +void CInode::_mark_dirty(LogSegmentRef const& ls) { if (!state_test(STATE_DIRTY)) { state_set(STATE_DIRTY); @@ -1170,7 +1170,7 @@ void CInode::_mark_dirty(LogSegment *ls) ls->dirty_inodes.push_back(&item_dirty); } -void CInode::mark_dirty(LogSegment *ls) { +void CInode::mark_dirty(LogSegmentRef const& ls) { dout(10) << __func__ << " " << *this << dendl; @@ -1553,7 +1553,7 @@ void CInode::fetch_backtrace(Context *fin, bufferlist *backtrace) mdcache->fetch_backtrace(ino(), get_backtrace_pool(), *backtrace, fin); } -void CInode::mark_dirty_parent(LogSegment *ls, bool dirty_pool) +void CInode::mark_dirty_parent(LogSegmentRef const& ls, bool dirty_pool) { if (!state_test(STATE_DIRTYPARENT)) { dout(10) << __func__ << dendl; @@ -4587,7 +4587,7 @@ void CInode::finish_export() } void CInode::decode_import(bufferlist::const_iterator& p, - LogSegment *ls) + LogSegmentRef const& ls) { DECODE_START(5, p); diff --git a/src/mds/CInode.h b/src/mds/CInode.h index bddba4c7f19..aeab0aa8a37 100644 --- a/src/mds/CInode.h +++ b/src/mds/CInode.h @@ -41,6 +41,7 @@ #include "ScatterLock.h" #include "LocalLockC.h" #include "Capability.h" +#include "LogSegmentRef.h" #include @@ -512,7 +513,7 @@ class CInode : public MDSCacheObject, public InodeStoreBase, public Counterversion; } version_t pre_dirty(); - void _mark_dirty(LogSegment *ls); - void mark_dirty(LogSegment *ls); + void _mark_dirty(LogSegmentRef const& ls); + void mark_dirty(LogSegmentRef const& ls); void mark_clean(); void store(MDSContext *fin); @@ -765,7 +766,7 @@ class CInode : public MDSCacheObject, public InodeStoreBase, public Counter #include #include @@ -117,8 +119,7 @@ public: virtual EMetaBlob *get_metablob() { return NULL; } protected: - LogSegment* get_segment() { return _segment; } - LogSegment const* get_segment() const { return _segment; } + LogSegmentRef const& get_segment() const { return _segment; } utime_t stamp; @@ -129,7 +130,7 @@ private: EventType _type = 0; uint64_t _start_off = 0; - LogSegment *_segment = nullptr; + LogSegmentRef _segment = nullptr; }; #endif diff --git a/src/mds/LogSegmentRef.h b/src/mds/LogSegmentRef.h new file mode 100644 index 00000000000..971a48e7c56 --- /dev/null +++ b/src/mds/LogSegmentRef.h @@ -0,0 +1,19 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab +/* + * Ceph - scalable distributed file system + * + * Copyright (C) 2004-2006 Sage Weil + * + * This is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software + * Foundation. See file COPYING. + * + */ + +#pragma once +#include + +class LogSegment; +using LogSegmentRef = std::shared_ptr; diff --git a/src/mds/MDCache.cc b/src/mds/MDCache.cc index 5c85587899c..f743db55943 100644 --- a/src/mds/MDCache.cc +++ b/src/mds/MDCache.cc @@ -528,7 +528,7 @@ void MDCache::create_mydir_hierarchy(MDSGather *gather) adjust_subtree_auth(mydir, mds->get_nodeid()); - LogSegment *ls = mds->mdlog->get_current_segment(); + auto&& ls = mds->mdlog->get_current_segment(); // stray dir for (int i = 0; i < NUM_STRAY; ++i) { @@ -834,7 +834,7 @@ void MDCache::populate_mydir() // it before dirtying any of the strays we create within it. mds->clog->warn() << "fragment " << mydir->dirfrag() << " was unreadable, " "recreating it now"; - LogSegment *ls = mds->mdlog->get_current_segment(); + auto&& ls = mds->mdlog->get_current_segment(); mydir->state_clear(CDir::STATE_BADFRAG); mydir->mark_complete(); mydir->_get_fnode()->version = mydir->pre_dirty(); @@ -3548,7 +3548,7 @@ void MDCache::handle_resolve_ack(const cref_t &ack) } } -void MDCache::add_uncommitted_peer(metareqid_t reqid, LogSegment *ls, mds_rank_t leader, MDPeerUpdate *su) +void MDCache::add_uncommitted_peer(metareqid_t reqid, LogSegmentRef const& ls, mds_rank_t leader, MDPeerUpdate *su) { auto const &ret = uncommitted_peers.emplace(std::piecewise_construct, std::forward_as_tuple(reqid), @@ -5895,7 +5895,7 @@ void MDCache::clean_open_file_lists() for (auto p = mds->mdlog->segments.begin(); p != mds->mdlog->segments.end(); ++p) { - LogSegment *ls = p->second; + auto&& ls = p->second; auto q = ls->open_files.begin(member_offset(CInode, item_open_file)); while (!q.end()) { @@ -5920,7 +5920,7 @@ void MDCache::dump_openfiles(Formatter *f) for (auto p = mds->mdlog->segments.begin(); p != mds->mdlog->segments.end(); ++p) { - LogSegment *ls = p->second; + auto&& ls = p->second; auto q = ls->open_files.begin(member_offset(CInode, item_open_file)); while (!q.end()) { @@ -6615,16 +6615,16 @@ void MDCache::do_file_recover() class C_MDC_RetryTruncate : public MDCacheContext { CInode *in; - LogSegment *ls; + LogSegmentRef ls; public: - C_MDC_RetryTruncate(MDCache *c, CInode *i, LogSegment *l) : + C_MDC_RetryTruncate(MDCache *c, CInode *i, LogSegmentRef const& l) : MDCacheContext(c), in(i), ls(l) {} void finish(int r) override { mdcache->_truncate_inode(in, ls); } }; -void MDCache::truncate_inode(CInode *in, LogSegment *ls) +void MDCache::truncate_inode(CInode *in, LogSegmentRef const& ls) { const auto& pi = in->get_projected_inode(); dout(10) << "truncate_inode " @@ -6649,9 +6649,9 @@ void MDCache::truncate_inode(CInode *in, LogSegment *ls) struct C_IO_MDC_TruncateWriteFinish : public MDCacheIOContext { CInode *in; - LogSegment *ls; + LogSegmentRef ls; uint32_t block_size; - C_IO_MDC_TruncateWriteFinish(MDCache *c, CInode *i, LogSegment *l, uint32_t bs) : + C_IO_MDC_TruncateWriteFinish(MDCache *c, CInode *i, LogSegmentRef const& l, uint32_t bs) : MDCacheIOContext(c, false), in(i), ls(l), block_size(bs) { } void finish(int r) override { @@ -6665,8 +6665,8 @@ struct C_IO_MDC_TruncateWriteFinish : public MDCacheIOContext { struct C_IO_MDC_TruncateFinish : public MDCacheIOContext { CInode *in; - LogSegment *ls; - C_IO_MDC_TruncateFinish(MDCache *c, CInode *i, LogSegment *l) : + LogSegmentRef ls; + C_IO_MDC_TruncateFinish(MDCache *c, CInode *i, LogSegmentRef const& l) : MDCacheIOContext(c, false), in(i), ls(l) { } void finish(int r) override { @@ -6678,7 +6678,7 @@ struct C_IO_MDC_TruncateFinish : public MDCacheIOContext { } }; -void MDCache::_truncate_inode(CInode *in, LogSegment *ls) +void MDCache::_truncate_inode(CInode *in, LogSegmentRef const& ls) { const auto& pi = in->get_inode(); dout(10) << "_truncate_inode " @@ -6775,7 +6775,7 @@ struct C_MDC_TruncateLogged : public MDCacheLogContext { } }; -void MDCache::truncate_inode_write_finish(CInode *in, LogSegment *ls, +void MDCache::truncate_inode_write_finish(CInode *in, LogSegmentRef const& ls, uint32_t block_size) { const auto& pi = in->get_inode(); @@ -6819,7 +6819,7 @@ void MDCache::truncate_inode_write_finish(CInode *in, LogSegment *ls, mds->finisher)); } -void MDCache::truncate_inode_finish(CInode *in, LogSegment *ls) +void MDCache::truncate_inode_finish(CInode *in, LogSegmentRef const& ls) { dout(10) << "truncate_inode_finish " << *in << dendl; @@ -6866,7 +6866,7 @@ void MDCache::truncate_inode_logged(CInode *in, MutationRef& mut) } -void MDCache::add_recovered_truncate(CInode *in, LogSegment *ls) +void MDCache::add_recovered_truncate(CInode *in, LogSegmentRef const& ls) { dout(20) << "add_recovered_truncate " << *in << " in log segment " << ls->seq << "/" << ls->offset << dendl; @@ -6874,7 +6874,7 @@ void MDCache::add_recovered_truncate(CInode *in, LogSegment *ls) in->get(CInode::PIN_TRUNCATING); } -void MDCache::remove_recovered_truncate(CInode *in, LogSegment *ls) +void MDCache::remove_recovered_truncate(CInode *in, LogSegmentRef const& ls) { dout(20) << "remove_recovered_truncate " << *in << " in log segment " << ls->seq << "/" << ls->offset << dendl; @@ -6891,7 +6891,7 @@ void MDCache::start_recovered_truncates() for (auto p = mds->mdlog->segments.begin(); p != mds->mdlog->segments.end(); ++p) { - LogSegment *ls = p->second; + auto&& ls = p->second; for (auto q = ls->truncating_inodes.begin(); q != ls->truncating_inodes.end(); ++q) { @@ -6915,11 +6915,11 @@ void MDCache::start_recovered_truncates() class C_MDS_purge_completed_finish : public MDCacheLogContext { interval_set inos; - LogSegment *ls; + LogSegmentRef ls; version_t inotablev; public: C_MDS_purge_completed_finish(MDCache *m, const interval_set& _inos, - LogSegment *_ls, version_t iv) + LogSegmentRef const& _ls, version_t iv) : MDCacheLogContext(m), inos(_inos), ls(_ls), inotablev(iv) {} void finish(int r) override { ceph_assert(r == 0); @@ -6934,14 +6934,14 @@ public: void MDCache::start_purge_inodes(){ dout(10) << "start_purge_inodes" << dendl; for (auto& p : mds->mdlog->segments){ - LogSegment *ls = p.second; + auto&& ls = p.second; if (ls->purging_inodes.size()){ purge_inodes(ls->purging_inodes, ls); } } } -void MDCache::purge_inodes(const interval_set& inos, LogSegment *ls) +void MDCache::purge_inodes(const interval_set& inos, LogSegmentRef const& ls) { dout(10) << __func__ << " purging inos " << inos << " logseg " << ls->seq << dendl; // FIXME: handle non-default data pool and namespace @@ -7707,7 +7707,7 @@ void MDCache::try_trim_non_auth_subtree(CDir *dir) show_subtrees(); } -void MDCache::standby_trim_segment(LogSegment *ls) +void MDCache::standby_trim_segment(LogSegmentRef const& ls) { ls->new_dirfrags.clear_list(); ls->open_files.clear_list(); @@ -12817,7 +12817,7 @@ void MDCache::handle_fragment_notify(const cref_t ¬ify) } void MDCache::add_uncommitted_fragment(dirfrag_t basedirfrag, int bits, const frag_vec_t& old_frags, - LogSegment *ls, bufferlist *rollback) + LogSegmentRef const& ls, bufferlist *rollback) { dout(10) << "add_uncommitted_fragment: base dirfrag " << basedirfrag << " bits " << bits << dendl; ceph_assert(!uncommitted_fragments.count(basedirfrag)); diff --git a/src/mds/MDCache.h b/src/mds/MDCache.h index dc655903e18..a87acb2cfaa 100644 --- a/src/mds/MDCache.h +++ b/src/mds/MDCache.h @@ -38,6 +38,7 @@ #include "OpenFileTable.h" #include "MDSContext.h" #include "Mutation.h" +#include "LogSegmentRef.h" class EMetaBlob; class MCacheExpire; @@ -452,7 +453,7 @@ class MDCache { snapid_t follows=CEPH_NOSNAP); // peers - void add_uncommitted_leader(metareqid_t reqid, LogSegment *ls, std::set &peers, bool safe=false) { + void add_uncommitted_leader(metareqid_t reqid, LogSegmentRef const& ls, std::set &peers, bool safe=false) { uncommitted_leaders[reqid].ls = ls; uncommitted_leaders[reqid].peers = peers; uncommitted_leaders[reqid].safe = safe; @@ -470,7 +471,7 @@ class MDCache { void committed_leader_peer(metareqid_t r, mds_rank_t from); void finish_committed_leaders(); - void add_uncommitted_peer(metareqid_t reqid, LogSegment*, mds_rank_t, MDPeerUpdate *su=nullptr); + void add_uncommitted_peer(metareqid_t reqid, LogSegmentRef const& , mds_rank_t, MDPeerUpdate *su=nullptr); void wait_for_uncommitted_peer(metareqid_t reqid, MDSContext *c) { uncommitted_peers.at(reqid).waiters.push_back(c); } @@ -787,7 +788,7 @@ private: std::pair trim(uint64_t count=0); bool trim_non_auth_subtree(CDir *directory); - void standby_trim_segment(LogSegment *ls); + void standby_trim_segment(LogSegmentRef const& ls); void try_trim_non_auth_subtree(CDir *dir); bool can_trim_non_auth_dirfrag(CDir *dir) { return my_ambiguous_imports.count((dir)->dirfrag()) == 0 && @@ -902,20 +903,20 @@ private: } // truncate - void truncate_inode(CInode *in, LogSegment *ls); - void _truncate_inode(CInode *in, LogSegment *ls); - void truncate_inode_finish(CInode *in, LogSegment *ls); - void truncate_inode_write_finish(CInode *in, LogSegment *ls, + void truncate_inode(CInode *in, LogSegmentRef const& ls); + void _truncate_inode(CInode *in, LogSegmentRef const& ls); + void truncate_inode_finish(CInode *in, LogSegmentRef const& ls); + void truncate_inode_write_finish(CInode *in, LogSegmentRef const& ls, uint32_t block_size); void truncate_inode_logged(CInode *in, MutationRef& mut); - void add_recovered_truncate(CInode *in, LogSegment *ls); - void remove_recovered_truncate(CInode *in, LogSegment *ls); + void add_recovered_truncate(CInode *in, LogSegmentRef const& ls); + void remove_recovered_truncate(CInode *in, LogSegmentRef const& ls); void start_recovered_truncates(); // purge unsafe inodes void start_purge_inodes(); - void purge_inodes(const interval_set& i, LogSegment *ls); + void purge_inodes(const interval_set& i, LogSegmentRef const& ls); CDir *get_auth_container(CDir *in); CDir *get_export_container(CDir *dir); @@ -1207,7 +1208,7 @@ private: struct uleader { uleader() {} std::set peers; - LogSegment *ls = nullptr; + LogSegmentRef ls = nullptr; std::vector waiters; bool safe = false; bool committing = false; @@ -1217,7 +1218,7 @@ private: struct upeer { upeer() {} mds_rank_t leader; - LogSegment *ls = nullptr; + LogSegmentRef ls = nullptr; MDPeerUpdate *su = nullptr; std::vector waiters; }; @@ -1440,7 +1441,7 @@ private: ufragment() {} int bits = 0; bool committed = false; - LogSegment *ls = nullptr; + LogSegmentRef ls = nullptr; std::vector waiters; frag_vec_t old_frags; bufferlist rollback; @@ -1539,7 +1540,7 @@ private: void handle_fragment_notify_ack(const cref_t &m); void add_uncommitted_fragment(dirfrag_t basedirfrag, int bits, const frag_vec_t& old_frag, - LogSegment *ls, bufferlist *rollback=NULL); + LogSegmentRef const& ls, bufferlist *rollback=NULL); void finish_uncommitted_fragment(dirfrag_t basedirfrag, int op); void rollback_uncommitted_fragment(dirfrag_t basedirfrag, frag_vec_t&& old_frags); diff --git a/src/mds/MDLog.cc b/src/mds/MDLog.cc index faf69795b1c..23293571158 100644 --- a/src/mds/MDLog.cc +++ b/src/mds/MDLog.cc @@ -370,11 +370,11 @@ void MDLog::append() // ------------------------------------------------- -LogSegment* MDLog::_start_new_segment(SegmentBoundary* sb) +LogSegmentRef const& MDLog::_start_new_segment(SegmentBoundary* sb) { ceph_assert(ceph_mutex_is_locked_by_me(mds->mds_lock)); - auto ls = new LogSegment(event_seq); + auto ls = std::make_shared(event_seq); segments[event_seq] = ls; logger->inc(l_mdl_segadd); logger->set(l_mdl_seg, segments.size()); @@ -386,7 +386,7 @@ LogSegment* MDLog::_start_new_segment(SegmentBoundary* sb) if (!mds->is_stopping()) { mds->mdcache->advance_stray(); } - return ls; + return segments[event_seq]; } LogSegment::seq_t MDLog::_submit_entry(LogEvent *le, MDSLogContextBase* c) @@ -419,7 +419,7 @@ LogSegment::seq_t MDLog::_submit_entry(LogEvent *le, MDSLogContextBase* c) // let the event register itself in the segment ceph_assert(!segments.empty()); - LogSegment *ls = segments.rbegin()->second; + auto&& ls = segments.rbegin()->second; ls->num_events++; le->_segment = ls; @@ -518,7 +518,7 @@ void MDLog::_submit_thread() if (data.le) { LogEvent *le = data.le; - LogSegment *ls = le->_segment; + auto&& ls = le->_segment; // encode it, with event type bufferlist bl; le->encode_with_header(bl, features); @@ -759,7 +759,7 @@ void MDLog::trim() ceph_assert(segments.size() >= pre_segments_size); } - map::iterator p = segments.begin(); + map::iterator p = segments.begin(); auto trim_start = ceph::coarse_mono_clock::now(); std::optional trim_end; @@ -793,7 +793,7 @@ void MDLog::trim() } // look at first segment - LogSegment *ls = p->second; + auto&& ls = p->second; ceph_assert(ls); ++p; @@ -834,10 +834,10 @@ void MDLog::trim() class C_MaybeExpiredSegment : public MDSInternalContext { MDLog *mdlog; - LogSegment *ls; + LogSegmentRef ls; int op_prio; public: - C_MaybeExpiredSegment(MDLog *mdl, LogSegment *s, int p) : + C_MaybeExpiredSegment(MDLog *mdl, LogSegmentRef const& s, int p) : MDSInternalContext(mdl->mds), mdlog(mdl), ls(s), op_prio(p) {} void finish(int res) override { dout(10) << __func__ << ": ls=" << *ls << ", r=" << res << dendl; @@ -867,11 +867,11 @@ int MDLog::trim_to(SegmentBoundary::seq_t seq) try_to_commit_open_file_table(last_seq); } - map::iterator p = segments.begin(); + map::iterator p = segments.begin(); while (p != segments.end() && p->first < last_seq && p->second->end < safe_pos) { // next segment should have been started - LogSegment *ls = p->second; + auto&& ls = p->second; ++p; // Caller should have flushed journaler before calling this @@ -905,7 +905,7 @@ int MDLog::trim_to(SegmentBoundary::seq_t seq) } -void MDLog::try_expire(LogSegment *ls, int op_prio) +void MDLog::try_expire(LogSegmentRef const& ls, int op_prio) { ceph_assert(ceph_mutex_is_locked(mds->mds_lock)); MDSGatherBuilder gather_bld(g_ceph_context); @@ -929,7 +929,7 @@ void MDLog::try_expire(LogSegment *ls, int op_prio) logger->set(l_mdl_evexg, expiring_events); } -void MDLog::_maybe_expired(LogSegment *ls, int op_prio) +void MDLog::_maybe_expired(LogSegmentRef const& ls, int op_prio) { if (mds->mdcache->is_readonly()) { dout(10) << "_maybe_expired, ignoring read-only FS" << dendl; @@ -967,7 +967,6 @@ void MDLog::_trim_expired_segments(auto& locker, MDSContext* ctx) logger->inc(l_mdl_evtrm, ls2->num_events); logger->inc(l_mdl_segtrm); expire_pos = ls2->end; - delete ls2; } segments.erase(segments.begin(), it); logger->set(l_mdl_seg, segments.size()); @@ -997,7 +996,7 @@ void MDLog::_trim_expired_segments(auto& locker, MDSContext* ctx) write_head(ctx); } -void MDLog::_expired(LogSegment *ls) +void MDLog::_expired(LogSegmentRef const& ls) { ceph_assert(ceph_mutex_is_locked_by_me(submit_mutex)); @@ -1537,7 +1536,7 @@ void MDLog::_replay_thread() } else { event_seq = pos; } - segments[event_seq] = new LogSegment(event_seq, pos); + segments[event_seq] = std::make_shared(event_seq, pos); logger->set(l_mdl_seg, segments.size()); if (sb->is_major_segment_boundary()) { major_segments.insert(event_seq); @@ -1622,7 +1621,7 @@ void MDLog::standby_trim_segments() bool removed_segment = false; while (have_any_segments()) { - LogSegment *ls = get_oldest_segment(); + auto&& ls = get_oldest_segment(); dout(10) << " maybe trim " << *ls << dendl; if (ls->end > expire_pos) { diff --git a/src/mds/MDLog.h b/src/mds/MDLog.h index 2dc657bec61..3599e2bf25a 100644 --- a/src/mds/MDLog.h +++ b/src/mds/MDLog.h @@ -51,6 +51,7 @@ enum { #include "LogSegment.h" #include "SegmentBoundary.h" #include "mdstypes.h" +#include "LogSegmentRef.h" #include #include @@ -71,7 +72,7 @@ public: MDLog(MDSRank *m); ~MDLog(); - const std::set &get_expiring_segments() const + const std::set &get_expiring_segments() const { return expiring_segments; } @@ -79,21 +80,23 @@ public: void create_logger(); void set_write_iohint(unsigned iohint_flags); - LogSegment *peek_current_segment() { - return segments.empty() ? NULL : segments.rbegin()->second; + LogSegmentRef const& peek_current_segment() { + static LogSegmentRef const nullsegment = nullptr; + return segments.empty() ? nullsegment : segments.rbegin()->second; } - LogSegment *get_current_segment() { + LogSegmentRef const& get_current_segment() { ceph_assert(!segments.empty()); return segments.rbegin()->second; } - LogSegment *get_segment(LogSegment::seq_t seq) { + LogSegmentRef const& get_segment(LogSegment::seq_t seq) { + static LogSegmentRef const nullsegment = nullptr; auto it = segments.find(seq); if (it != segments.end()) { return it->second; } else { - return nullptr; + return nullsegment; } } @@ -247,13 +250,12 @@ protected: void _submit_thread(); - LogSegment *get_oldest_segment() { + LogSegmentRef const& get_oldest_segment() { return segments.begin()->second; } void remove_oldest_segment() { - std::map::iterator p = segments.begin(); - delete p->second; - segments.erase(p); + ceph_assert(!segments.empty()); + segments.erase(segments.begin()); } uint64_t num_events = 0; // in events @@ -275,7 +277,7 @@ protected: std::vector waitfor_replay; // -- segments -- - std::map segments; + std::map segments; std::size_t pre_segments_size = 0; // the num of segments when the mds finished replay-journal, to calc the num of segments growing LogSegment::seq_t event_seq = 0; uint64_t expiring_events = 0; @@ -292,13 +294,13 @@ private: friend class C_OFT_Committed; void try_to_commit_open_file_table(uint64_t last_seq); - LogSegment* _start_new_segment(SegmentBoundary* sb); + LogSegmentRef const& _start_new_segment(SegmentBoundary* sb); void _segment_upkeep(); LogSegment::seq_t _submit_entry(LogEvent* e, MDSLogContextBase* c); - void try_expire(LogSegment *ls, int op_prio); - void _maybe_expired(LogSegment *ls, int op_prio); - void _expired(LogSegment *ls); + void try_expire(LogSegmentRef const& ls, int op_prio); + void _maybe_expired(LogSegmentRef const& ls, int op_prio); + void _expired(LogSegmentRef const& ls); void _trim_expired_segments(auto& locker, MDSContext* ctx=nullptr); void write_head(MDSContext *onfinish); @@ -316,8 +318,8 @@ private: bool skip_unbounded_events; std::set major_segments; - std::set expired_segments; - std::set expiring_segments; + std::set expired_segments; + std::set expiring_segments; uint64_t minor_segments_since_last_major_segment = 0; double log_warn_factor; diff --git a/src/mds/MDSTableClient.cc b/src/mds/MDSTableClient.cc index 0f96028d754..d7201dff2ba 100644 --- a/src/mds/MDSTableClient.cc +++ b/src/mds/MDSTableClient.cc @@ -183,7 +183,7 @@ void MDSTableClient::_prepare(bufferlist& mutation, version_t *ptid, bufferlist dout(10) << "tableserver is not ready yet, deferring request" << dendl; } -void MDSTableClient::commit(version_t tid, LogSegment *ls) +void MDSTableClient::commit(version_t tid, LogSegmentRef const& ls) { dout(10) << "commit " << tid << dendl; @@ -210,7 +210,7 @@ void MDSTableClient::commit(version_t tid, LogSegment *ls) // recovery -void MDSTableClient::got_journaled_agree(version_t tid, LogSegment *ls) +void MDSTableClient::got_journaled_agree(version_t tid, LogSegmentRef const& ls) { dout(10) << "got_journaled_agree " << tid << dendl; ls->pending_commit_tids[table].insert(tid); diff --git a/src/mds/MDSTableClient.h b/src/mds/MDSTableClient.h index 7b96b50222d..22cd5d4b3ab 100644 --- a/src/mds/MDSTableClient.h +++ b/src/mds/MDSTableClient.h @@ -19,6 +19,7 @@ #include "mds_table_types.h" #include "mdstypes.h" // for mds_rank_t #include "common/ref.h" // for cref_t +#include "LogSegmentRef.h" #include #include @@ -39,13 +40,13 @@ public: void handle_request(const cref_t &m); void _prepare(bufferlist& mutation, version_t *ptid, bufferlist *pbl, MDSContext *onfinish); - void commit(version_t tid, LogSegment *ls); + void commit(version_t tid, LogSegmentRef const& ls); void resend_commits(); void resend_prepares(); // for recovery (by me) - void got_journaled_agree(version_t tid, LogSegment *ls); + void got_journaled_agree(version_t tid, LogSegmentRef const& ls); void got_journaled_ack(version_t tid); bool has_committed(version_t tid) const { @@ -103,7 +104,7 @@ protected: std::list<_pending_prepare> waiting_for_reqid; // pending commits - std::map pending_commit; + std::map pending_commit; std::map > ack_waiters; }; #endif diff --git a/src/mds/Migrator.cc b/src/mds/Migrator.cc index 444db550c47..d23acc7c0ce 100644 --- a/src/mds/Migrator.cc +++ b/src/mds/Migrator.cc @@ -3324,7 +3324,7 @@ void Migrator::dump_export_states(Formatter *f) } void Migrator::decode_import_inode(CDentry *dn, bufferlist::const_iterator& blp, - mds_rank_t oldauth, LogSegment *ls, + mds_rank_t oldauth, LogSegmentRef const& ls, map >& peer_exports, list& updated_scatterlocks) { @@ -3509,7 +3509,7 @@ void Migrator::decode_import_dir(bufferlist::const_iterator& blp, mds_rank_t oldauth, CDir *import_root, EImportStart *le, - LogSegment *ls, + LogSegmentRef const& ls, map >& peer_exports, list& updated_scatterlocks, int &num_imported) { diff --git a/src/mds/Migrator.h b/src/mds/Migrator.h index 61adf4c0e76..d768e46fbd0 100644 --- a/src/mds/Migrator.h +++ b/src/mds/Migrator.h @@ -21,6 +21,7 @@ #include "Capability.h" #include "Mutation.h" // for MDRequestRef +#include "LogSegmentRef.h" #include #include @@ -234,7 +235,7 @@ public: void export_caps(CInode *in); void decode_import_inode(CDentry *dn, bufferlist::const_iterator& blp, - mds_rank_t oldauth, LogSegment *ls, + mds_rank_t oldauth, LogSegmentRef const& ls, std::map >& cap_imports, std::list& updated_scatterlocks); void decode_import_inode_caps(CInode *in, bool auth_cap, bufferlist::const_iterator &blp, @@ -247,7 +248,7 @@ public: mds_rank_t oldauth, CDir *import_root, EImportStart *le, - LogSegment *ls, + LogSegmentRef const& ls, std::map >& cap_imports, std::list& updated_scatterlocks, int &num_imported); diff --git a/src/mds/Mutation.h b/src/mds/Mutation.h index dd80d1e26f9..7f0e527be6d 100644 --- a/src/mds/Mutation.h +++ b/src/mds/Mutation.h @@ -28,6 +28,7 @@ #include "include/filepath.h" #include "Capability.h" +#include "LogSegmentRef.h" #include "common/StackStringStream.h" #include "common/TrackedOp.h" @@ -241,7 +242,7 @@ public: metareqid_t reqid; std::optional result; __u32 attempt = 0; // which attempt for this request - LogSegment *ls = nullptr; // the log segment i'm committing to + LogSegmentRef ls = nullptr; // the log segment i'm committing to // flag mutation as peer mds_rank_t peer_to_mds = MDS_RANK_NONE; // this is a peer request if >= 0. diff --git a/src/mds/Server.cc b/src/mds/Server.cc index 65033c052af..86f03f0df08 100644 --- a/src/mds/Server.cc +++ b/src/mds/Server.cc @@ -425,14 +425,14 @@ class C_MDS_session_finish : public ServerLogContext { interval_set inos_to_free; version_t inotablev; interval_set inos_to_purge; - LogSegment *ls = nullptr; + LogSegmentRef ls = nullptr; Context *fin; 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, - const interval_set& to_purge, LogSegment *_ls, Context *fin_ = nullptr) : + const interval_set& to_purge, LogSegmentRef const& _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 { @@ -911,7 +911,7 @@ 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_to_free, version_t piv, - const interval_set& inos_to_purge, LogSegment *ls) + const interval_set& inos_to_purge, LogSegmentRef const& ls) { dout(10) << "_session_logged " << session->info.inst << " state_seq " << state_seq diff --git a/src/mds/Server.h b/src/mds/Server.h index 41f73523b32..7e8d0eab414 100644 --- a/src/mds/Server.h +++ b/src/mds/Server.h @@ -31,6 +31,8 @@ #include "common/perf_counters_collection.h" #endif +#include "LogSegmentRef.h" + #include #include @@ -127,6 +129,7 @@ enum { l_mdss_last, }; + class Server { public: using clock = ceph::coarse_mono_clock; @@ -161,7 +164,7 @@ 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_to_free, version_t piv, - const interval_set& inos_to_purge, LogSegment *ls); + const interval_set& inos_to_purge, LogSegmentRef const& ls); version_t prepare_force_open_sessions(std::map &cm, std::map& cmm, std::map >& smap); diff --git a/src/mds/events/EMetaBlob.h b/src/mds/events/EMetaBlob.h index de5921e5647..9bb3fe4beb7 100644 --- a/src/mds/events/EMetaBlob.h +++ b/src/mds/events/EMetaBlob.h @@ -21,6 +21,8 @@ #include "../CDir.h" #include "../CDentry.h" #include "../LogSegment.h" +#include "../LogSegmentRef.h" + #include "include/interval_set.h" #include "common/strescape.h" @@ -44,7 +46,6 @@ struct MDPeerUpdate; * */ - class EMetaBlob { public: @@ -626,8 +627,8 @@ private: out << "]"; } - void update_segment(LogSegment *ls); - void replay(MDSRank *mds, LogSegment *ls, int type, MDPeerUpdate *su=NULL); + void update_segment(LogSegmentRef const& ls); + void replay(MDSRank *mds, LogSegmentRef const& ls, int type, MDPeerUpdate *su=NULL); }; WRITE_CLASS_ENCODER_FEATURES(EMetaBlob) WRITE_CLASS_ENCODER_FEATURES(EMetaBlob::fullbit) diff --git a/src/mds/journal.cc b/src/mds/journal.cc index 94c215d344a..e031e358b84 100644 --- a/src/mds/journal.cc +++ b/src/mds/journal.cc @@ -58,6 +58,7 @@ #include "MDSTableServer.h" #include "Locker.h" +#include "LogSegmentRef.h" #define dout_context g_ceph_context #define dout_subsys ceph_subsys_mds @@ -72,6 +73,7 @@ using std::set; using std::string; using std::vector; + // ----------------------- // LogSegment @@ -213,8 +215,8 @@ void LogSegment::try_to_expire(MDSRank *mds, MDSGatherBuilder &gather_bld, int o if (!open_files.empty()) { ceph_assert(!mds->mdlog->is_capped()); // hmm FIXME EOpen *le = 0; - LogSegment *ls = mds->mdlog->get_current_segment(); - ceph_assert(ls != this); + auto&& ls = mds->mdlog->get_current_segment(); + ceph_assert(ls.get() != this); elist::iterator p = open_files.begin(member_offset(CInode, item_open_file)); while (!p.end()) { CInode *in = *p; @@ -474,7 +476,7 @@ void EMetaBlob::add_dir_context(CDir *dir, int mode) } } -void EMetaBlob::update_segment(LogSegment *ls) +void EMetaBlob::update_segment(LogSegmentRef const &ls) { // dirty inode mtimes // -> handled directly by Server.cc, replay() @@ -1260,7 +1262,7 @@ void EMetaBlob::generate_test_instances(std::list& ls) ls.push_back(new EMetaBlob()); } -void EMetaBlob::replay(MDSRank *mds, LogSegment *logseg, int type, MDPeerUpdate *peerup) +void EMetaBlob::replay(MDSRank *mds, LogSegmentRef const& logseg, int type, MDPeerUpdate *peerup) { dout(10) << "EMetaBlob.replay " << lump_map.size() << " dirlumps by " << client_name << dendl; @@ -1841,7 +1843,7 @@ void EMetaBlob::replay(MDSRank *mds, LogSegment *logseg, int type, MDPeerUpdate mds->heartbeat_reset(); } for (const auto& p : truncate_finish) { - LogSegment *ls = mds->mdlog->get_segment(p.second); + auto&& ls = mds->mdlog->get_segment(p.second); if (ls) { CInode *in = mds->mdcache->get_inode(p.first); ceph_assert(in); @@ -1930,7 +1932,7 @@ void EPurged::update_segment() void EPurged::replay(MDSRank *mds) { if (inos.size()) { - LogSegment *ls = mds->mdlog->get_segment(seq); + auto&& ls = mds->mdlog->get_segment(seq); if (ls) ls->purging_inodes.subtract(inos);