]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
Revert "client: invalidate kernel dentries one by one"
authorYan, Zheng <zyan@redhat.com>
Tue, 9 Dec 2014 06:16:01 +0000 (14:16 +0800)
committerYan, Zheng <zyan@redhat.com>
Tue, 9 Dec 2014 06:25:45 +0000 (14:25 +0800)
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 <zyan@redhat.com>
src/client/Client.cc
src/client/Client.h

index 5cd6e861c30c0a170b22e8e9147902e606e26322..bcff69de1e0220c896749f68a1c6634b8dd5219e 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(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<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);
+  // 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);
     }
   }
 }
@@ -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)
index ada58e248081dd2e859b5e61c5845a285c6bcc98..4afc206077d530150f2907fa2d4a8f84259c3f41 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(MetaSession *s);
+  void _invalidate_kernel_dcache();
   
   void dump_inode(Formatter *f, Inode *in, set<Inode*>& did, bool disconnected);
   void dump_cache(Formatter *f);  // debug