From 9199179799b41d9534b27bcceefc1bc9f2763bac Mon Sep 17 00:00:00 2001 From: Patrick Donnelly Date: Thu, 17 May 2018 17:06:52 -0700 Subject: [PATCH] client: delay dentry trimming until after cap traversal Fixes: http://tracker.ceph.com/issues/24137 Signed-off-by: Patrick Donnelly --- src/client/Client.cc | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/src/client/Client.cc b/src/client/Client.cc index e1be4e27626..9030cfef9e9 100644 --- a/src/client/Client.cc +++ b/src/client/Client.cc @@ -4089,7 +4089,8 @@ void Client::trim_caps(MetaSession *s, uint64_t max) uint64_t trimmed = 0; auto p = s->caps.begin(); - std::set anchor; /* prevent put_inode from deleting all caps during traversal */ + std::set to_trim; /* this avoids caps other than the one we're + * looking at from getting deleted during traversal. */ while ((caps_size - trimmed) > max && !p.end()) { Cap *cap = *p; InodeRef in(cap->inode); @@ -4105,7 +4106,6 @@ void Client::trim_caps(MetaSession *s, uint64_t max) if (!(get_caps_used(in.get()) & ~oissued & mine)) { ldout(cct, 20) << " removing unused, unneeded non-auth cap on " << *in << dendl; cap = (remove_cap(cap, true), nullptr); - /* N.B. no need to push onto anchor, as we are only removing one cap */ trimmed++; } } else { @@ -4124,9 +4124,8 @@ void Client::trim_caps(MetaSession *s, uint64_t max) // the end of this function. _schedule_invalidate_dentry_callback(dn, true); } - ldout(cct, 20) << " anchoring inode: " << in->ino << dendl; - anchor.insert(in); - trim_dentry(dn); + ldout(cct, 20) << " queueing dentry for trimming: " << dn->name << dendl; + to_trim.insert(dn); } else { ldout(cct, 20) << " not expirable: " << dn->name << dendl; all = false; @@ -4138,8 +4137,11 @@ void Client::trim_caps(MetaSession *s, uint64_t max) } } } - ldout(cct, 20) << " clearing anchored inodes" << dendl; - anchor.clear(); + ldout(cct, 20) << " trimming queued dentries: " << dendl; + for (const auto &dn : to_trim) { + trim_dentry(dn); + } + to_trim.clear(); caps_size = s->caps.size(); if (caps_size > (size_t)max)