Patch "split dentry_kill()" has been added to the 3.14-stable tree
Subsystems (2)
This is a note to let you know that I've just added the patch titled
split dentry_kill()
to the 3.14-stable tree which can be found at:
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary
The filename of the patch is:
split-dentry_kill.patch
and it can be found in the queue-3.14 subdirectory.
If you, or anyone else, feels it should not be added to the stable tree, please let <[email protected]> know about it.
Quoted 1 line
From
e55fd011549eae01a230e3cace6f4d031b6a3453Mon Sep 17 00:00:00 2001
From: Al Viro <[email protected]>
Date: Wed, 28 May 2014 13:51:12 -0400
Subject: split dentry_kill()
From: Al Viro <[email protected]>
commit e55fd011549eae01a230e3cace6f4d031b6a3453 upstream.
... into trylocks and everything else. The latter (actual killing) is __dentry_kill().
--- fs/dcache.c | 62 ++++++++++++++++++++++++++++++++++-------------------------- 1 file changed, 36 insertions(+), 26 deletions(-)
fs/dcache.c +36 -26
@@ -439,36 +439,12 @@ void d_drop(struct dentry *dentry) }EXPORT_SYMBOL (d_drop); -/* -* Finish off a dentry we've decided to kill. -* dentry->d_lock must be held, returns with it unlocked. -* If ref is non-zero, then decrement the refcount too. -* Returns dentry requiring refcount drop, or NULL if we're done. -*/ -static struct dentry * -dentry_kill (struct dentry *dentry,int unlock_on_failure) - __releases(dentry->d_lock) +static void __dentry_kill (struct dentry *dentry) { -struct inode *inode;struct dentry *parent =NULL ;bool can_free = true; - - inode = dentry->d_inode; -if (inode && !spin_trylock (&inode->i_lock)) { -relock: -if (unlock_on_failure) { -spin_unlock (&dentry->d_lock); -cpu_relax (); - } -return dentry;/* try again with same dentry */ - }if (!IS_ROOT (dentry)) parent = dentry->d_parent; -if (parent && !spin_trylock (&parent->d_lock)) { -if (inode) -spin_unlock (&inode->i_lock); - goto relock; - }/* * The dentry is now unrecoverably dead to the world.
@@ -512,10 +488,44 @@ relock: can_free = false; }spin_unlock (&dentry->d_lock); -out:if (likely (can_free))dentry_free (dentry); +} + +/* +* Finish off a dentry we've decided to kill. +* dentry->d_lock must be held, returns with it unlocked. +* If ref is non-zero, then decrement the refcount too. +* Returns dentry requiring refcount drop, or NULL if we're done. +*/ +static struct dentry * +dentry_kill (struct dentry *dentry,int unlock_on_failure) + __releases(dentry->d_lock) +{ +struct inode *inode = dentry->d_inode; +struct dentry *parent =NULL ; + +if (inode &&unlikely (!spin_trylock (&inode->i_lock))) + goto failed; + +if (!IS_ROOT (dentry)) { + parent = dentry->d_parent; +if (unlikely (!spin_trylock (&parent->d_lock))) { +if (inode) +spin_unlock (&inode->i_lock); + goto failed; + } + } + +__dentry_kill (dentry);return parent; + +failed: +if (unlock_on_failure) { +spin_unlock (&dentry->d_lock); +cpu_relax (); + } +return dentry;/* try again with same dentry */ }/*
Patches currently in stable-queue which might be from [email protected] are
queue-3.14/lock_parent-don-t-step-on-stale-d_parent-of-all-but-freed-one.patch queue-3.14/lift-the-already-marked-killed-case-into-shrink_dentry_list.patch queue-3.14/expand-dentry_kill-dentry-0-in-shrink_dentry_list.patch queue-3.14/bcache-fix-a-leak-in-bch_cached_dev_run.patch queue-3.14/dcache-add-missing-lockdep-annotation.patch queue-3.14/dealing-with-the-rest-of-shrink_dentry_list-livelock.patch queue-3.14/split-dentry_kill.patch queue-3.14/shrink_dentry_list-take-parent-s-d_lock-earlier.patch queue-3.14/dentry_kill-doesn-t-need-the-second-argument-now.patch