1
0
mirror of https://github.com/ceph/ceph synced 2025-03-30 23:40:09 +00:00

client: invalidate kernel dentries one by one

Our trick to trim the whole kernel dentry tree does not work for 3.18+ kernel.
The fix is trim kernel dentries one by one.

Fixes: 
Signed-off-by: Yan, Zheng <zyan@redhat.com>
This commit is contained in:
Yan, Zheng 2014-12-01 21:54:52 +08:00
parent 25fc21b837
commit 491da5173f
2 changed files with 15 additions and 21 deletions

View File

@ -543,7 +543,7 @@ void Client::trim_cache_for_reconnect(MetaSession *s)
<< " trimmed " << trimmed << " dentries" << dendl;
if (s->caps.size() > 0)
_invalidate_kernel_dcache();
_invalidate_kernel_dcache(s);
}
void Client::trim_dentry(Dentry *dn)
@ -3277,16 +3277,19 @@ void Client::remove_session_caps(MetaSession *s)
sync_cond.Signal();
}
void Client::_invalidate_kernel_dcache()
void Client::_invalidate_kernel_dcache(MetaSession *s)
{
// notify kernel to invalidate top level directory entries. As a side effect,
// unused inodes underneath these entries get pruned.
if (dentry_invalidate_cb && root->dir) {
for (ceph::unordered_map<string, Dentry*>::iterator p = root->dir->dentries.begin();
p != root->dir->dentries.end();
++p) {
if (p->second->inode)
_schedule_invalidate_dentry_callback(p->second, false);
if (!dentry_invalidate_cb)
return;
for (xlist<Cap*>::iterator p = s->caps.begin(); !p.end(); ++p) {
Inode *in = (*p)->inode;
if (in->dn_set.empty())
continue;
for (set<Dentry*>::iterator q = in->dn_set.begin();
q != in->dn_set.end();
++q) {
_schedule_invalidate_dentry_callback(*q, false);
}
}
}
@ -3320,14 +3323,8 @@ void Client::trim_caps(MetaSession *s, int max)
while (q != in->dn_set.end()) {
Dentry *dn = *q++;
if (dn->lru_is_expireable()) {
if (dn->dir->parent_inode->ino == MDS_INO_ROOT) {
// Only issue one of these per DN for inodes in root: handle
// others more efficiently by calling for root-child DNs at
// the end of this function.
_schedule_invalidate_dentry_callback(dn, true);
}
_schedule_invalidate_dentry_callback(dn, false);
trim_dentry(dn);
} else {
ldout(cct, 20) << " not expirable: " << dn->name << dendl;
all = false;
@ -3348,9 +3345,6 @@ void Client::trim_caps(MetaSession *s, int max)
}
}
s->s_cap_iterator = NULL;
if (s->caps.size() > max)
_invalidate_kernel_dcache();
}
void Client::mark_caps_dirty(Inode *in, int caps)

View File

@ -429,7 +429,7 @@ protected:
void trim_cache_for_reconnect(MetaSession *s);
void trim_dentry(Dentry *dn);
void trim_caps(MetaSession *s, int max);
void _invalidate_kernel_dcache();
void _invalidate_kernel_dcache(MetaSession *s);
void dump_inode(Formatter *f, Inode *in, set<Inode*>& did, bool disconnected);
void dump_cache(Formatter *f); // debug