aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorAl Viro <viro@zeniv.linux.org.uk>2014-04-29 16:13:18 -0400
committerAl Viro <viro@zeniv.linux.org.uk>2014-04-30 18:02:51 -0400
commit5c47e6d0ad608987b91affbcf7d1fc12dfbe8fb4 (patch)
tree5d9845fc2c92f7d5178fcab54cae6cd7426f972c /fs
parent03b3b889e79cdb6b806fc0ba9be0d71c186bbfaa (diff)
fold try_prune_one_dentry()
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'fs')
-rw-r--r--fs/dcache.c75
1 files changed, 25 insertions, 50 deletions
diff --git a/fs/dcache.c b/fs/dcache.c
index 9b15c5c37277..a5540d491954 100644
--- a/fs/dcache.c
+++ b/fs/dcache.c
@@ -787,47 +787,9 @@ restart:
787} 787}
788EXPORT_SYMBOL(d_prune_aliases); 788EXPORT_SYMBOL(d_prune_aliases);
789 789
790/*
791 * Try to throw away a dentry - free the inode, dput the parent.
792 * Requires dentry->d_lock is held, and dentry->d_count == 0.
793 * Releases dentry->d_lock.
794 *
795 * This may fail if locks cannot be acquired no problem, just try again.
796 */
797static struct dentry * try_prune_one_dentry(struct dentry *dentry)
798 __releases(dentry->d_lock)
799{
800 struct dentry *parent;
801
802 parent = dentry_kill(dentry, 0);
803 /*
804 * If dentry_kill returns NULL, we have nothing more to do.
805 * if it returns the same dentry, trylocks failed. In either
806 * case, just loop again.
807 *
808 * Otherwise, we need to prune ancestors too. This is necessary
809 * to prevent quadratic behavior of shrink_dcache_parent(), but
810 * is also expected to be beneficial in reducing dentry cache
811 * fragmentation.
812 */
813 if (!parent)
814 return NULL;
815 if (parent == dentry)
816 return dentry;
817
818 /* Prune ancestors. */
819 dentry = parent;
820 while (dentry) {
821 if (lockref_put_or_lock(&dentry->d_lockref))
822 return NULL;
823 dentry = dentry_kill(dentry, 1);
824 }
825 return NULL;
826}
827
828static void shrink_dentry_list(struct list_head *list) 790static void shrink_dentry_list(struct list_head *list)
829{ 791{
830 struct dentry *dentry; 792 struct dentry *dentry, *parent;
831 793
832 rcu_read_lock(); 794 rcu_read_lock();
833 for (;;) { 795 for (;;) {
@@ -863,22 +825,35 @@ static void shrink_dentry_list(struct list_head *list)
863 } 825 }
864 rcu_read_unlock(); 826 rcu_read_unlock();
865 827
828 parent = dentry_kill(dentry, 0);
866 /* 829 /*
867 * If 'try_to_prune()' returns a dentry, it will 830 * If dentry_kill returns NULL, we have nothing more to do.
868 * be the same one we passed in, and d_lock will
869 * have been held the whole time, so it will not
870 * have been added to any other lists. We failed
871 * to get the inode lock.
872 *
873 * We just add it back to the shrink list.
874 */ 831 */
875 dentry = try_prune_one_dentry(dentry); 832 if (!parent) {
876 833 rcu_read_lock();
877 rcu_read_lock(); 834 continue;
878 if (dentry) { 835 }
836 if (unlikely(parent == dentry)) {
837 /*
838 * trylocks have failed and d_lock has been held the
839 * whole time, so it could not have been added to any
840 * other lists. Just add it back to the shrink list.
841 */
842 rcu_read_lock();
879 d_shrink_add(dentry, list); 843 d_shrink_add(dentry, list);
880 spin_unlock(&dentry->d_lock); 844 spin_unlock(&dentry->d_lock);
845 continue;
881 } 846 }
847 /*
848 * We need to prune ancestors too. This is necessary to prevent
849 * quadratic behavior of shrink_dcache_parent(), but is also
850 * expected to be beneficial in reducing dentry cache
851 * fragmentation.
852 */
853 dentry = parent;
854 while (dentry && !lockref_put_or_lock(&dentry->d_lockref))
855 dentry = dentry_kill(dentry, 1);
856 rcu_read_lock();
882 } 857 }
883 rcu_read_unlock(); 858 rcu_read_unlock();
884} 859}