From: Xiubo Li Date: Wed, 19 Aug 2020 04:53:51 +0000 (-0400) Subject: Client: defer puting the inode X-Git-Tag: v16.1.0~1189^2 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=7a921c0df43dee18b920e61debccc005e2711df6;p=ceph.git Client: defer puting the inode To make sure the code is under client_lock when puting the inodes. Fixes: https://tracker.ceph.com/issues/46882 Signed-off-by: Xiubo Li --- diff --git a/src/client/Client.cc b/src/client/Client.cc index 2a96ea71eef8..6d9a047695f7 100755 --- a/src/client/Client.cc +++ b/src/client/Client.cc @@ -3081,9 +3081,10 @@ void Client::handle_lease(const MConstRef& m) } } -void Client::put_inode(Inode *in, int n) +void Client::_put_inode(Inode *in, int n) { ldout(cct, 10) << __func__ << " on " << *in << dendl; + int left = in->_put(n); if (left == 0) { // release any caps @@ -3107,6 +3108,31 @@ void Client::put_inode(Inode *in, int n) } } +void Client::delay_put_inodes(bool wakeup) +{ + ceph_assert(ceph_mutex_is_locked_by_me(client_lock)); + + std::map release; + { + std::scoped_lock dl(delay_i_lock); + release.swap(delay_i_release); + } + + for (auto &[in, cnt] : release) + _put_inode(in, cnt); + + if (wakeup) + mount_cond.notify_all(); +} + +void Client::put_inode(Inode *in, int n) +{ + ldout(cct, 20) << __func__ << " on " << *in << " n = " << n << dendl; + + std::scoped_lock dl(delay_i_lock); + delay_i_release[in] += n; +} + void Client::close_dir(Dir *dir) { Inode *in = dir->parent_inode; @@ -6301,12 +6327,15 @@ void Client::_unmount(bool abort) // empty lru cache trim_cache(); + delay_put_inodes(); + while (lru.lru_get_size() > 0 || !inode_map.empty()) { ldout(cct, 2) << "cache still has " << lru.lru_get_size() << "+" << inode_map.size() << " items" << ", waiting (for caps to release?)" << dendl; + if (auto r = mount_cond.wait_for(lock, ceph::make_timespan(5)); r == std::cv_status::timeout) { dump_cache(NULL); @@ -6426,6 +6455,7 @@ void Client::tick() if (!mount_aborted) collect_and_send_metrics(); + delay_put_inodes(is_unmounting()); trim_cache(true); if (blocklisted && (is_mounted() || is_unmounting()) && diff --git a/src/client/Client.h b/src/client/Client.h index c1b4f57c1a45..1e52c2aa0ee5 100644 --- a/src/client/Client.h +++ b/src/client/Client.h @@ -867,6 +867,8 @@ protected: // -- metadata cache stuff // decrease inode ref. delete if dangling. + void _put_inode(Inode *in, int n); + void delay_put_inodes(bool wakeup=false); void put_inode(Inode *in, int n=1); void close_dir(Dir *dir); @@ -1413,6 +1415,9 @@ private: uint64_t cap_hits = 0; uint64_t cap_misses = 0; + + ceph::spinlock delay_i_lock; + std::map delay_i_release; }; /**