]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
3.14-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 14 Aug 2015 16:48:18 +0000 (09:48 -0700)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 14 Aug 2015 16:48:18 +0000 (09:48 -0700)
added patches:
fold-try_prune_one_dentry.patch

queue-3.14/fold-try_prune_one_dentry.patch [new file with mode: 0644]
queue-3.14/series

diff --git a/queue-3.14/fold-try_prune_one_dentry.patch b/queue-3.14/fold-try_prune_one_dentry.patch
new file mode 100644 (file)
index 0000000..46d9f3b
--- /dev/null
@@ -0,0 +1,115 @@
+From 5c47e6d0ad608987b91affbcf7d1fc12dfbe8fb4 Mon Sep 17 00:00:00 2001
+From: Al Viro <viro@zeniv.linux.org.uk>
+Date: Tue, 29 Apr 2014 16:13:18 -0400
+Subject: fold try_prune_one_dentry()
+
+From: Al Viro <viro@zeniv.linux.org.uk>
+
+commit 5c47e6d0ad608987b91affbcf7d1fc12dfbe8fb4 upstream.
+
+Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
+Cc: "Nicholas A. Bellinger" <nab@linux-iscsi.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/dcache.c |   75 ++++++++++++++++++++----------------------------------------
+ 1 file changed, 25 insertions(+), 50 deletions(-)
+
+--- a/fs/dcache.c
++++ b/fs/dcache.c
+@@ -788,47 +788,9 @@ restart:
+ }
+ EXPORT_SYMBOL(d_prune_aliases);
+-/*
+- * Try to throw away a dentry - free the inode, dput the parent.
+- * Requires dentry->d_lock is held, and dentry->d_count == 0.
+- * Releases dentry->d_lock.
+- *
+- * This may fail if locks cannot be acquired no problem, just try again.
+- */
+-static struct dentry * try_prune_one_dentry(struct dentry *dentry)
+-      __releases(dentry->d_lock)
+-{
+-      struct dentry *parent;
+-
+-      parent = dentry_kill(dentry, 0);
+-      /*
+-       * If dentry_kill returns NULL, we have nothing more to do.
+-       * if it returns the same dentry, trylocks failed. In either
+-       * case, just loop again.
+-       *
+-       * Otherwise, we need to prune ancestors too. This is necessary
+-       * to prevent quadratic behavior of shrink_dcache_parent(), but
+-       * is also expected to be beneficial in reducing dentry cache
+-       * fragmentation.
+-       */
+-      if (!parent)
+-              return NULL;
+-      if (parent == dentry)
+-              return dentry;
+-
+-      /* Prune ancestors. */
+-      dentry = parent;
+-      while (dentry) {
+-              if (lockref_put_or_lock(&dentry->d_lockref))
+-                      return NULL;
+-              dentry = dentry_kill(dentry, 1);
+-      }
+-      return NULL;
+-}
+-
+ static void shrink_dentry_list(struct list_head *list)
+ {
+-      struct dentry *dentry;
++      struct dentry *dentry, *parent;
+       rcu_read_lock();
+       for (;;) {
+@@ -864,22 +826,35 @@ static void shrink_dentry_list(struct li
+               }
+               rcu_read_unlock();
++              parent = dentry_kill(dentry, 0);
+               /*
+-               * If 'try_to_prune()' returns a dentry, it will
+-               * be the same one we passed in, and d_lock will
+-               * have been held the whole time, so it will not
+-               * have been added to any other lists. We failed
+-               * to get the inode lock.
+-               *
+-               * We just add it back to the shrink list.
++               * If dentry_kill returns NULL, we have nothing more to do.
+                */
+-              dentry = try_prune_one_dentry(dentry);
+-
+-              rcu_read_lock();
+-              if (dentry) {
++              if (!parent) {
++                      rcu_read_lock();
++                      continue;
++              }
++              if (unlikely(parent == dentry)) {
++                      /*
++                       * trylocks have failed and d_lock has been held the
++                       * whole time, so it could not have been added to any
++                       * other lists. Just add it back to the shrink list.
++                       */
++                      rcu_read_lock();
+                       d_shrink_add(dentry, list);
+                       spin_unlock(&dentry->d_lock);
++                      continue;
+               }
++              /*
++               * We need to prune ancestors too. This is necessary to prevent
++               * quadratic behavior of shrink_dcache_parent(), but is also
++               * expected to be beneficial in reducing dentry cache
++               * fragmentation.
++               */
++              dentry = parent;
++              while (dentry && !lockref_put_or_lock(&dentry->d_lockref))
++                      dentry = dentry_kill(dentry, 1);
++              rcu_read_lock();
+       }
+       rcu_read_unlock();
+ }
index 930341d8450d464e72fb5ed19374c0408e0075cb..faaa532ba6f69d469ace63db9ba2b7f3b0717cce 100644 (file)
@@ -31,3 +31,4 @@ signalfd-fix-information-leak-in-signalfd_copyinfo.patch
 signal-fix-information-leak-in-copy_siginfo_to_user.patch
 signal-fix-information-leak-in-copy_siginfo_from_user32.patch
 fold-d_kill-and-d_free.patch
+fold-try_prune_one_dentry.patch