]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
client: invalidate kernel dentries one by one 3056/head
authorYan, Zheng <zyan@redhat.com>
Mon, 1 Dec 2014 13:54:52 +0000 (21:54 +0800)
committerYan, Zheng <zyan@redhat.com>
Tue, 2 Dec 2014 13:49:02 +0000 (21:49 +0800)
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: #9997
Signed-off-by: Yan, Zheng <zyan@redhat.com>
src/client/Client.cc
src/client/Client.h

index 6b43ccce38960058a2f641da58ca9010839fc269..42611f0f93da894af0fb7752d4f8344c94079bd1 100644 (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)
index 4afc206077d530150f2907fa2d4a8f84259c3f41..ada58e248081dd2e859b5e61c5845a285c6bcc98 100644 (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