summaryrefslogtreecommitdiffstats
path: root/deal-with-deadlock-in-d_walk.patch
diff options
context:
space:
mode:
authorJosh Boyer <jwboyer@fedoraproject.org>2014-12-17 08:27:20 -0500
committerJosh Boyer <jwboyer@fedoraproject.org>2014-12-17 08:27:20 -0500
commita6cbe7f978e03814060cc48a3d9ecaa7b1ce7d2e (patch)
tree074f885e6d392e2040c800f52ec52bd4e59d7f02 /deal-with-deadlock-in-d_walk.patch
parentc21e6b2370cd2d6455299bb2641452b99071dbed (diff)
downloadkernel-a6cbe7f978e03814060cc48a3d9ecaa7b1ce7d2e.tar.gz
kernel-a6cbe7f978e03814060cc48a3d9ecaa7b1ce7d2e.tar.xz
kernel-a6cbe7f978e03814060cc48a3d9ecaa7b1ce7d2e.zip
Linux v3.18.1
Diffstat (limited to 'deal-with-deadlock-in-d_walk.patch')
-rw-r--r--deal-with-deadlock-in-d_walk.patch86
1 files changed, 0 insertions, 86 deletions
diff --git a/deal-with-deadlock-in-d_walk.patch b/deal-with-deadlock-in-d_walk.patch
deleted file mode 100644
index fd0e21c33..000000000
--- a/deal-with-deadlock-in-d_walk.patch
+++ /dev/null
@@ -1,86 +0,0 @@
-From: Al Viro <viro@zeniv.linux.org.uk>
-Date: Sun, 26 Oct 2014 19:31:10 -0400
-Subject: [PATCH] deal with deadlock in d_walk()
-
-... by not hitting rename_retry for reasons other than rename having
-happened. In other words, do _not_ restart when finding that
-between unlocking the child and locking the parent the former got
-into __dentry_kill(). Skip the killed siblings instead...
-
-Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
----
- fs/dcache.c | 31 ++++++++++++++++---------------
- 1 file changed, 16 insertions(+), 15 deletions(-)
-
-diff --git a/fs/dcache.c b/fs/dcache.c
-index c3ea5b765f6a..71acf8d6f2be 100644
---- a/fs/dcache.c
-+++ b/fs/dcache.c
-@@ -495,7 +495,7 @@ static void __dentry_kill(struct dentry *dentry)
- }
- /* if it was on the hash then remove it */
- __d_drop(dentry);
-- list_del(&dentry->d_child);
-+ __list_del_entry(&dentry->d_child);
- /*
- * Inform d_walk() that we are no longer attached to the
- * dentry tree
-@@ -1082,33 +1082,31 @@ resume:
- /*
- * All done at this level ... ascend and resume the search.
- */
-+ rcu_read_lock();
-+ascend:
- if (this_parent != parent) {
- struct dentry *child = this_parent;
- this_parent = child->d_parent;
-
-- rcu_read_lock();
- spin_unlock(&child->d_lock);
- spin_lock(&this_parent->d_lock);
-
-- /*
-- * might go back up the wrong parent if we have had a rename
-- * or deletion
-- */
-- if (this_parent != child->d_parent ||
-- (child->d_flags & DCACHE_DENTRY_KILLED) ||
-- need_seqretry(&rename_lock, seq)) {
-- spin_unlock(&this_parent->d_lock);
-- rcu_read_unlock();
-+ /* might go back up the wrong parent if we have had a rename. */
-+ if (need_seqretry(&rename_lock, seq))
- goto rename_retry;
-+ next = child->d_child.next;
-+ while (unlikely(child->d_flags & DCACHE_DENTRY_KILLED)) {
-+ if (next == &this_parent->d_subdirs)
-+ goto ascend;
-+ child = list_entry(next, struct dentry, d_child);
-+ next = next->next;
- }
- rcu_read_unlock();
-- next = child->d_child.next;
- goto resume;
- }
-- if (need_seqretry(&rename_lock, seq)) {
-- spin_unlock(&this_parent->d_lock);
-+ if (need_seqretry(&rename_lock, seq))
- goto rename_retry;
-- }
-+ rcu_read_unlock();
- if (finish)
- finish(data);
-
-@@ -1118,6 +1116,9 @@ out_unlock:
- return;
-
- rename_retry:
-+ spin_unlock(&this_parent->d_lock);
-+ rcu_read_unlock();
-+ BUG_ON(seq & 1);
- if (!retry)
- return;
- seq = 1;
---
-2.1.0
-