client: delay dentry trimming until after cap traversal

Fixes: http://tracker.ceph.com/issues/24137

Signed-off-by: Patrick Donnelly <pdonnell@redhat.com>
This commit is contained in:
Patrick Donnelly 2018-05-17 17:06:52 -07:00
parent abb2fa4d5b
commit 9199179799
No known key found for this signature in database
GPG Key ID: 3A2A7E25BEA8AADB

View File

@ -4089,7 +4089,8 @@ void Client::trim_caps(MetaSession *s, uint64_t max)
uint64_t trimmed = 0;
auto p = s->caps.begin();
std::set<InodeRef> anchor; /* prevent put_inode from deleting all caps during traversal */
std::set<Dentry *> 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)