summaryrefslogtreecommitdiffstats
path: root/src/mds
diff options
context:
space:
mode:
authorVenky Shankar <vshankar@redhat.com>2024-09-17 13:18:03 +0200
committerVenky Shankar <vshankar@redhat.com>2024-09-17 13:18:03 +0200
commit8bd63f881858fbe57b9714e7e54da4bbeb68e910 (patch)
tree440dcf757d3e682177f4cf944b77c7b7cdbe8a42 /src/mds
parentMerge pull request #59093 from joscollin/wip-fix-get-set-dirty-snap-id (diff)
parentqa/cephfs: add test to verify backtrace update failure on deleted data pool (diff)
downloadceph-8bd63f881858fbe57b9714e7e54da4bbeb68e910.tar.xz
ceph-8bd63f881858fbe57b9714e7e54da4bbeb68e910.zip
Merge PR #55421 into main
* refs/pull/55421/head: qa/cephfs: add test to verify backtrace update failure on deleted data pool mds: batch backtrace updates by pool-id when expiring a log segment mds: dump log segment in segment expiry callback mds: dump log segment end along with offset Reviewed-by: Xiubo Li <xiubli@redhat.com> Reviewed-by: Patrick Donnelly <pdonnell@redhat.com>
Diffstat (limited to 'src/mds')
-rw-r--r--src/mds/CInode.cc14
-rw-r--r--src/mds/CInode.h21
-rw-r--r--src/mds/LogSegment.h2
-rw-r--r--src/mds/MDLog.cc1
-rw-r--r--src/mds/journal.cc44
5 files changed, 56 insertions, 26 deletions
diff --git a/src/mds/CInode.cc b/src/mds/CInode.cc
index faf9f408688..0e9b6996ad2 100644
--- a/src/mds/CInode.cc
+++ b/src/mds/CInode.cc
@@ -1386,7 +1386,7 @@ void CInode::_commit_ops(int r, C_GatherBuilder &gather_bld,
}
void CInode::_store_backtrace(std::vector<CInodeCommitOperation> &ops_vec,
- inode_backtrace_t &bt, int op_prio)
+ inode_backtrace_t &bt, int op_prio, bool ignore_old_pools)
{
dout(10) << __func__ << " on " << *this << dendl;
ceph_assert(is_dirty_parent());
@@ -1407,8 +1407,8 @@ void CInode::_store_backtrace(std::vector<CInodeCommitOperation> &ops_vec,
ops_vec.emplace_back(op_prio, pool, get_inode()->layout,
mdcache->mds->mdsmap->get_up_features(), slink);
- if (!state_test(STATE_DIRTYPOOL) || get_inode()->old_pools.empty()) {
- dout(20) << __func__ << ": no dirtypool or no old pools" << dendl;
+ if (!state_test(STATE_DIRTYPOOL) || get_inode()->old_pools.empty() || ignore_old_pools) {
+ dout(20) << __func__ << ": no dirtypool or no old pools or ignore_old_pools" << dendl;
return;
}
@@ -1431,7 +1431,7 @@ void CInode::store_backtrace(MDSContext *fin, int op_prio)
inode_backtrace_t bt;
auto version = get_inode()->backtrace_version;
- _store_backtrace(ops_vec, bt, op_prio);
+ _store_backtrace(ops_vec, bt, op_prio, false);
C_GatherBuilder gather(g_ceph_context,
new C_OnFinisher(
@@ -1442,12 +1442,14 @@ void CInode::store_backtrace(MDSContext *fin, int op_prio)
gather.activate();
}
-void CInode::store_backtrace(CInodeCommitOperations &op, int op_prio)
+void CInode::store_backtrace(CInodeCommitOperations &op, int op_prio,
+ bool ignore_old_pools)
{
op.version = get_inode()->backtrace_version;
op.in = this;
- _store_backtrace(op.ops_vec, op.bt, op_prio);
+ // update backtraces in old pools
+ _store_backtrace(op.ops_vec, op.bt, op_prio, ignore_old_pools);
}
void CInode::_stored_backtrace(int r, version_t v, Context *fin)
diff --git a/src/mds/CInode.h b/src/mds/CInode.h
index d55b6442107..8ae1d5f7168 100644
--- a/src/mds/CInode.h
+++ b/src/mds/CInode.h
@@ -754,8 +754,9 @@ class CInode : public MDSCacheObject, public InodeStoreBase, public Counter<CIno
inode_backtrace_t &bt);
void build_backtrace(int64_t pool, inode_backtrace_t& bt);
void _store_backtrace(std::vector<CInodeCommitOperation> &ops_vec,
- inode_backtrace_t &bt, int op_prio);
- void store_backtrace(CInodeCommitOperations &op, int op_prio);
+ inode_backtrace_t &bt, int op_prio, bool ignore_old_pools);
+ void store_backtrace(CInodeCommitOperations &op, int op_prio,
+ bool ignore_old_pools=false);
void store_backtrace(MDSContext *fin, int op_prio=-1);
void _stored_backtrace(int r, version_t v, Context *fin);
void fetch_backtrace(Context *fin, ceph::buffer::list *backtrace);
@@ -1142,6 +1143,14 @@ class CInode : public MDSCacheObject, public InodeStoreBase, public Counter<CIno
// client caps
client_t loner_cap = -1, want_loner_cap = -1;
+ /**
+ * Return the pool ID where we currently write backtraces for
+ * this inode (in addition to inode.old_pools)
+ *
+ * @returns a pool ID >=0
+ */
+ int64_t get_backtrace_pool() const;
+
protected:
ceph_lock_state_t *get_fcntl_lock_state() {
if (!fcntl_locks)
@@ -1192,14 +1201,6 @@ protected:
clear_flock_lock_state();
}
- /**
- * Return the pool ID where we currently write backtraces for
- * this inode (in addition to inode.old_pools)
- *
- * @returns a pool ID >=0
- */
- int64_t get_backtrace_pool() const;
-
// parent dentries in cache
CDentry *parent = nullptr; // primary link
mempool::mds_co::compact_set<CDentry*> remote_parents; // if hard linked
diff --git a/src/mds/LogSegment.h b/src/mds/LogSegment.h
index e6d8a2ca883..04427ad8be8 100644
--- a/src/mds/LogSegment.h
+++ b/src/mds/LogSegment.h
@@ -108,7 +108,7 @@ class LogSegment {
static inline std::ostream& operator<<(std::ostream& out, const LogSegment& ls) {
return out << "LogSegment(" << ls.seq << "/0x" << std::hex << ls.offset
- << std::dec << " events=" << ls.num_events << ")";
+ << "~" << ls.end << std::dec << " events=" << ls.num_events << ")";
}
#endif
diff --git a/src/mds/MDLog.cc b/src/mds/MDLog.cc
index cd274f8edc4..40d893d6262 100644
--- a/src/mds/MDLog.cc
+++ b/src/mds/MDLog.cc
@@ -749,6 +749,7 @@ class C_MaybeExpiredSegment : public MDSInternalContext {
C_MaybeExpiredSegment(MDLog *mdl, LogSegment *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;
if (res < 0)
mdlog->mds->handle_write_error(res);
mdlog->_maybe_expired(ls, op_prio);
diff --git a/src/mds/journal.cc b/src/mds/journal.cc
index e080b117610..40400ff4054 100644
--- a/src/mds/journal.cc
+++ b/src/mds/journal.cc
@@ -237,27 +237,53 @@ void LogSegment::try_to_expire(MDSRank *mds, MDSGatherBuilder &gather_bld, int o
ceph_assert(g_conf()->mds_kill_journal_expire_at != 3);
- size_t count = 0;
- for (elist<CInode*>::iterator it = dirty_parent_inodes.begin(); !it.end(); ++it)
- count++;
-
- std::vector<CInodeCommitOperations> ops_vec;
- ops_vec.reserve(count);
+ std::map<int64_t, std::vector<CInodeCommitOperations>> ops_vec_map;
// backtraces to be stored/updated
for (elist<CInode*>::iterator p = dirty_parent_inodes.begin(); !p.end(); ++p) {
CInode *in = *p;
ceph_assert(in->is_auth());
if (in->can_auth_pin()) {
dout(15) << "try_to_expire waiting for storing backtrace on " << *in << dendl;
- ops_vec.resize(ops_vec.size() + 1);
- in->store_backtrace(ops_vec.back(), op_prio);
+ auto pool_id = in->get_backtrace_pool();
+
+ // this is for the default data pool
+ dout(20) << __func__ << ": updating pool=" << pool_id << dendl;
+ ops_vec_map[pool_id].push_back(CInodeCommitOperations());
+ in->store_backtrace(ops_vec_map[pool_id].back(), op_prio, true);
+
+
+ if (!in->state_test(CInode::STATE_DIRTYPOOL)) {
+ dout(20) << __func__ << ": no dirtypool" << dendl;
+ continue;
+ }
+
+ // dispatch separate ops for backtrace updates for old pools
+ for (auto _pool_id : in->get_inode()->old_pools) {
+ if (_pool_id == pool_id) {
+ continue;
+ }
+
+ in->auth_pin(in); // CInode::_stored_backtrace() does auth_unpin()
+ dout(20) << __func__ << ": updating old_pool=" << _pool_id << dendl;
+
+ auto cco = CInodeCommitOperations();
+ cco.in = in;
+ // use backtrace from the main pool so as to pickup the main
+ // pool-id for old pool updates.
+ cco.bt = ops_vec_map[pool_id].back().bt;
+ cco.ops_vec.emplace_back(op_prio, _pool_id);
+ cco.version = in->get_inode()->backtrace_version;
+ ops_vec_map[_pool_id].push_back(cco);
+ }
} else {
dout(15) << "try_to_expire waiting for unfreeze on " << *in << dendl;
in->add_waiter(CInode::WAIT_UNFREEZE, gather_bld.new_sub());
}
}
- if (!ops_vec.empty())
+
+ for (auto& [pool_id, ops_vec] : ops_vec_map) {
mds->finisher->queue(new BatchCommitBacktrace(mds, gather_bld.new_sub(), std::move(ops_vec)));
+ }
ceph_assert(g_conf()->mds_kill_journal_expire_at != 4);