diff options
author | Al Viro <viro@zeniv.linux.org.uk> | 2014-05-28 13:59:13 -0400 |
---|---|---|
committer | Al Viro <viro@zeniv.linux.org.uk> | 2014-05-29 08:50:08 -0400 |
commit | ff2fde9929feb2aef45377ce56b8b12df85dda69 (patch) | |
tree | 2dcb10757dca729826a67de777ae81dbe99891be /fs/dcache.c | |
parent | e55fd011549eae01a230e3cace6f4d031b6a3453 (diff) |
expand dentry_kill(dentry, 0) in shrink_dentry_list()
Result will be massaged to saner shape in the next commits. It is
ugly, no questions - the point of that one is to be a provably
equivalent transformation (and it might be worth splitting a bit
more).
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'fs/dcache.c')
-rw-r--r-- | fs/dcache.c | 30 |
1 files changed, 17 insertions, 13 deletions
diff --git a/fs/dcache.c b/fs/dcache.c index 1577c14dfb4e..c23f78a9d156 100644 --- a/fs/dcache.c +++ b/fs/dcache.c | |||
@@ -801,6 +801,7 @@ static void shrink_dentry_list(struct list_head *list) | |||
801 | struct dentry *dentry, *parent; | 801 | struct dentry *dentry, *parent; |
802 | 802 | ||
803 | while (!list_empty(list)) { | 803 | while (!list_empty(list)) { |
804 | struct inode *inode; | ||
804 | dentry = list_entry(list->prev, struct dentry, d_lru); | 805 | dentry = list_entry(list->prev, struct dentry, d_lru); |
805 | spin_lock(&dentry->d_lock); | 806 | spin_lock(&dentry->d_lock); |
806 | /* | 807 | /* |
@@ -828,23 +829,26 @@ static void shrink_dentry_list(struct list_head *list) | |||
828 | continue; | 829 | continue; |
829 | } | 830 | } |
830 | 831 | ||
831 | parent = dentry_kill(dentry, 0); | 832 | inode = dentry->d_inode; |
832 | /* | 833 | if (inode && unlikely(!spin_trylock(&inode->i_lock))) { |
833 | * If dentry_kill returns NULL, we have nothing more to do. | ||
834 | */ | ||
835 | if (!parent) | ||
836 | continue; | ||
837 | |||
838 | if (unlikely(parent == dentry)) { | ||
839 | /* | ||
840 | * trylocks have failed and d_lock has been held the | ||
841 | * whole time, so it could not have been added to any | ||
842 | * other lists. Just add it back to the shrink list. | ||
843 | */ | ||
844 | d_shrink_add(dentry, list); | 834 | d_shrink_add(dentry, list); |
845 | spin_unlock(&dentry->d_lock); | 835 | spin_unlock(&dentry->d_lock); |
846 | continue; | 836 | continue; |
847 | } | 837 | } |
838 | |||
839 | parent = NULL; | ||
840 | if (!IS_ROOT(dentry)) { | ||
841 | parent = dentry->d_parent; | ||
842 | if (unlikely(!spin_trylock(&parent->d_lock))) { | ||
843 | if (inode) | ||
844 | spin_unlock(&inode->i_lock); | ||
845 | d_shrink_add(dentry, list); | ||
846 | spin_unlock(&dentry->d_lock); | ||
847 | continue; | ||
848 | } | ||
849 | } | ||
850 | |||
851 | __dentry_kill(dentry); | ||
848 | /* | 852 | /* |
849 | * We need to prune ancestors too. This is necessary to prevent | 853 | * We need to prune ancestors too. This is necessary to prevent |
850 | * quadratic behavior of shrink_dcache_parent(), but is also | 854 | * quadratic behavior of shrink_dcache_parent(), but is also |