From 71e1785821970f5d15b99941c83283f90db772f6 Mon Sep 17 00:00:00 2001 From: Xiubo Li Date: Mon, 21 Feb 2022 22:59:53 +0800 Subject: [PATCH] mds: reset heartbeat when fetching or committing dentries Fixes: https://tracker.ceph.com/issues/54345 Signed-off-by: Xiubo Li (cherry picked from commit 5a71139246fc3e99ec3133a543d2a1b34d098f0d) Conflicts: src/mds/CDir.cc --- src/mds/CDir.cc | 36 ++++++++++++++++++++++++++++++++++-- 1 file changed, 34 insertions(+), 2 deletions(-) diff --git a/src/mds/CDir.cc b/src/mds/CDir.cc index 9983d86f3c08f..50ce6b15f214d 100644 --- a/src/mds/CDir.cc +++ b/src/mds/CDir.cc @@ -2031,6 +2031,7 @@ void CDir::_omap_fetched(bufferlist& hdrbl, map& omap, } } + int count = 0; unsigned pos = omap.size() - 1; double rand_threshold = get_inode()->get_ephemeral_rand(); for (map::reverse_iterator p = omap.rbegin(); @@ -2040,6 +2041,9 @@ void CDir::_omap_fetched(bufferlist& hdrbl, map& omap, snapid_t last; dentry_key_t::decode_helper(p->first, dname, last); + if (!(++count % mdcache->mds->heartbeat_reset_grace(2))) + mdcache->mds->heartbeat_reset(); + CDentry *dn = NULL; try { dn = _load_dentry( @@ -2091,6 +2095,9 @@ void CDir::_omap_fetched(bufferlist& hdrbl, map& omap, undef_inodes.pop_front(); in->state_clear(CInode::STATE_REJOINUNDEF); mdcache->opened_undef_inode(in); + + if (!(++count % mdcache->mds->heartbeat_reset_grace())) + mdcache->mds->heartbeat_reset(); } // dirty myself to remove stale snap dentries @@ -2322,6 +2329,7 @@ void CDir::_omap_commit_ops(int r, int op_prio, int64_t metapool, version_t vers _rm.clear(); }; + int count = 0; for (auto &key : stales) { unsigned size = key.length() + sizeof(__u32); if (write_size + size > max_write_size) @@ -2329,6 +2337,9 @@ void CDir::_omap_commit_ops(int r, int op_prio, int64_t metapool, version_t vers write_size += size; _rm.emplace(key); + + if (!(++count % mdcache->mds->heartbeat_reset_grace(2))) + mdcache->mds->heartbeat_reset(); } for (auto &key : to_remove) { @@ -2338,6 +2349,9 @@ void CDir::_omap_commit_ops(int r, int op_prio, int64_t metapool, version_t vers write_size += size; _rm.emplace(std::move(key)); + + if (!(++count % mdcache->mds->heartbeat_reset_grace(2))) + mdcache->mds->heartbeat_reset(); } uint64_t off = 0; @@ -2365,6 +2379,9 @@ void CDir::_omap_commit_ops(int r, int op_prio, int64_t metapool, version_t vers write_size += size; _set[std::move(item.key)].swap(bl); + + if (!(++count % mdcache->mds->heartbeat_reset_grace())) + mdcache->mds->heartbeat_reset(); } commit_one(true); @@ -2443,6 +2460,7 @@ void CDir::_omap_commit(int op_prio) } }; + int count = 0; if (state_test(CDir::STATE_FRAGMENTING) && is_new()) { assert(committed_version == 0); for (auto p = items.begin(); p != items.end(); ) { @@ -2451,12 +2469,18 @@ void CDir::_omap_commit(int op_prio) if (dn->get_linkage()->is_null()) continue; write_one(dn); + + if (!(++count % mdcache->mds->heartbeat_reset_grace())) + mdcache->mds->heartbeat_reset(); } } else { for (auto p = dirty_dentries.begin(); !p.end(); ) { CDentry *dn = *p; ++p; write_one(dn); + + if (!(++count % mdcache->mds->heartbeat_reset_grace())) + mdcache->mds->heartbeat_reset(); } } @@ -2608,6 +2632,8 @@ void CDir::_committed(int r, version_t v) if (committed_version == get_version()) mark_clean(); + int count = 0; + // dentries clean? for (auto p = dirty_dentries.begin(); !p.end(); ) { CDentry *dn = *p; @@ -2645,11 +2671,14 @@ void CDir::_committed(int r, version_t v) dout(15) << " dir " << committed_version << " < dn " << dn->get_version() << " still dirty " << *dn << dendl; ceph_assert(dn->is_dirty()); } + + if (!(++count % mdcache->mds->heartbeat_reset_grace())) + mdcache->mds->heartbeat_reset(); } // finishers? bool were_waiters = !waiting_for_commit.empty(); - + auto it = waiting_for_commit.begin(); while (it != waiting_for_commit.end()) { auto _it = it; @@ -2665,7 +2694,10 @@ void CDir::_committed(int r, version_t v) mdcache->mds->queue_waiters(t); waiting_for_commit.erase(it); it = _it; - } + + if (!(++count % mdcache->mds->heartbeat_reset_grace())) + mdcache->mds->heartbeat_reset(); + } // try drop dentries in this dirfrag if it's about to be purged if (!inode->is_base() && get_parent_dir()->inode->is_stray() && -- 2.39.5