From: Yan, Zheng Date: Tue, 9 Dec 2014 06:16:01 +0000 (+0800) Subject: Revert "client: invalidate kernel dentries one by one" X-Git-Tag: v0.91~18^2~2 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=2f52202955444a0508dee15e4a29d9708b3d9d87;p=ceph.git Revert "client: invalidate kernel dentries one by one" This reverts commit 491da5173fc33fec944865f0e2e9a506ec71fc5b. Since 3.18 kernel, d_invalidate() unhash dentry even when it's in use. If dentry of process' working directory is invalidated, calling getcwd(3) will return -ENOENT. Signed-off-by: Yan, Zheng --- diff --git a/src/client/Client.cc b/src/client/Client.cc index 5cd6e861c30c..bcff69de1e02 100644 --- a/src/client/Client.cc +++ b/src/client/Client.cc @@ -543,7 +543,7 @@ void Client::trim_cache_for_reconnect(MetaSession *s) << " trimmed " << trimmed << " dentries" << dendl; if (s->caps.size() > 0) - _invalidate_kernel_dcache(s); + _invalidate_kernel_dcache(); } void Client::trim_dentry(Dentry *dn) @@ -3277,19 +3277,16 @@ void Client::remove_session_caps(MetaSession *s) sync_cond.Signal(); } -void Client::_invalidate_kernel_dcache(MetaSession *s) +void Client::_invalidate_kernel_dcache() { - if (!dentry_invalidate_cb) - return; - - for (xlist::iterator p = s->caps.begin(); !p.end(); ++p) { - Inode *in = (*p)->inode; - if (in->dn_set.empty()) - continue; - for (set::iterator q = in->dn_set.begin(); - q != in->dn_set.end(); - ++q) { - _schedule_invalidate_dentry_callback(*q, false); + // 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::iterator p = root->dir->dentries.begin(); + p != root->dir->dentries.end(); + ++p) { + if (p->second->inode) + _schedule_invalidate_dentry_callback(p->second, false); } } } @@ -3323,8 +3320,14 @@ void Client::trim_caps(MetaSession *s, int max) while (q != in->dn_set.end()) { Dentry *dn = *q++; if (dn->lru_is_expireable()) { - _schedule_invalidate_dentry_callback(dn, false); + 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); + } trim_dentry(dn); + } else { ldout(cct, 20) << " not expirable: " << dn->name << dendl; all = false; @@ -3345,6 +3348,9 @@ 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) diff --git a/src/client/Client.h b/src/client/Client.h index ada58e248081..4afc206077d5 100644 --- a/src/client/Client.h +++ b/src/client/Client.h @@ -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(MetaSession *s); + void _invalidate_kernel_dcache(); void dump_inode(Formatter *f, Inode *in, set& did, bool disconnected); void dump_cache(Formatter *f); // debug