}
}
-void Client::trim_caps(MetaSession *s, int max)
+void Client::trim_caps(MetaSession *s, uint64_t max)
{
mds_rank_t mds = s->mds_num;
- int caps_size = s->caps.size();
+ size_t caps_size = s->caps.size();
ldout(cct, 10) << "trim_caps mds." << mds << " max " << max
<< " caps " << caps_size << dendl;
- int trimmed = 0;
- xlist<Cap*>::iterator p = s->caps.begin();
- std::set<InodeRef> anchor; /* prevent put_inode from deleting all caps during traversal */
+ uint64_t trimmed = 0;
+ auto p = s->caps.begin();
+ 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);
// disposable non-auth cap
if (!(get_caps_used(in.get()) & ~oissued & mine)) {
ldout(cct, 20) << " removing unused, unneeded non-auth cap on " << *in << dendl;
- remove_cap(cap, true);
- /* N.B. no need to push onto anchor, as we are only removing one cap */
+ cap = (remove_cap(cap, true), nullptr);
trimmed++;
}
} else {
// 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;
}
}
}
- 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 > max)
void trim_cache(bool trim_kernel_dcache=false);
void trim_cache_for_reconnect(MetaSession *s);
void trim_dentry(Dentry *dn);
- void trim_caps(MetaSession *s, int max);
+ void trim_caps(MetaSession *s, uint64_t max);
void _invalidate_kernel_dcache();
void dump_inode(Formatter *f, Inode *in, set<Inode*>& did, bool disconnected);