aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/dcache.c99
1 files changed, 78 insertions, 21 deletions
diff --git a/fs/dcache.c b/fs/dcache.c
index e989ecb44a65..509b49410943 100644
--- a/fs/dcache.c
+++ b/fs/dcache.c
@@ -356,7 +356,7 @@ static void dentry_unlink_inode(struct dentry * dentry)
356} 356}
357 357
358/* 358/*
359 * dentry_lru_(add|del|prune|move_tail) must be called with d_lock held. 359 * dentry_lru_(add|del|move_list) must be called with d_lock held.
360 */ 360 */
361static void dentry_lru_add(struct dentry *dentry) 361static void dentry_lru_add(struct dentry *dentry)
362{ 362{
@@ -373,16 +373,26 @@ static void dentry_lru_add(struct dentry *dentry)
373static void __dentry_lru_del(struct dentry *dentry) 373static void __dentry_lru_del(struct dentry *dentry)
374{ 374{
375 list_del_init(&dentry->d_lru); 375 list_del_init(&dentry->d_lru);
376 dentry->d_flags &= ~(DCACHE_SHRINK_LIST | DCACHE_LRU_LIST); 376 dentry->d_flags &= ~DCACHE_LRU_LIST;
377 dentry->d_sb->s_nr_dentry_unused--; 377 dentry->d_sb->s_nr_dentry_unused--;
378 this_cpu_dec(nr_dentry_unused); 378 this_cpu_dec(nr_dentry_unused);
379} 379}
380 380
381/* 381/*
382 * Remove a dentry with references from the LRU. 382 * Remove a dentry with references from the LRU.
383 *
384 * If we are on the shrink list, then we can get to try_prune_one_dentry() and
385 * lose our last reference through the parent walk. In this case, we need to
386 * remove ourselves from the shrink list, not the LRU.
383 */ 387 */
384static void dentry_lru_del(struct dentry *dentry) 388static void dentry_lru_del(struct dentry *dentry)
385{ 389{
390 if (dentry->d_flags & DCACHE_SHRINK_LIST) {
391 list_del_init(&dentry->d_lru);
392 dentry->d_flags &= ~DCACHE_SHRINK_LIST;
393 return;
394 }
395
386 if (!list_empty(&dentry->d_lru)) { 396 if (!list_empty(&dentry->d_lru)) {
387 spin_lock(&dentry->d_sb->s_dentry_lru_lock); 397 spin_lock(&dentry->d_sb->s_dentry_lru_lock);
388 __dentry_lru_del(dentry); 398 __dentry_lru_del(dentry);
@@ -392,14 +402,16 @@ static void dentry_lru_del(struct dentry *dentry)
392 402
393static void dentry_lru_move_list(struct dentry *dentry, struct list_head *list) 403static void dentry_lru_move_list(struct dentry *dentry, struct list_head *list)
394{ 404{
405 BUG_ON(dentry->d_flags & DCACHE_SHRINK_LIST);
406
395 spin_lock(&dentry->d_sb->s_dentry_lru_lock); 407 spin_lock(&dentry->d_sb->s_dentry_lru_lock);
396 if (list_empty(&dentry->d_lru)) { 408 if (list_empty(&dentry->d_lru)) {
397 dentry->d_flags |= DCACHE_LRU_LIST; 409 dentry->d_flags |= DCACHE_LRU_LIST;
398 list_add_tail(&dentry->d_lru, list); 410 list_add_tail(&dentry->d_lru, list);
399 dentry->d_sb->s_nr_dentry_unused++;
400 this_cpu_inc(nr_dentry_unused);
401 } else { 411 } else {
402 list_move_tail(&dentry->d_lru, list); 412 list_move_tail(&dentry->d_lru, list);
413 dentry->d_sb->s_nr_dentry_unused--;
414 this_cpu_dec(nr_dentry_unused);
403 } 415 }
404 spin_unlock(&dentry->d_sb->s_dentry_lru_lock); 416 spin_unlock(&dentry->d_sb->s_dentry_lru_lock);
405} 417}
@@ -497,7 +509,8 @@ EXPORT_SYMBOL(d_drop);
497 * If ref is non-zero, then decrement the refcount too. 509 * If ref is non-zero, then decrement the refcount too.
498 * Returns dentry requiring refcount drop, or NULL if we're done. 510 * Returns dentry requiring refcount drop, or NULL if we're done.
499 */ 511 */
500static inline struct dentry *dentry_kill(struct dentry *dentry) 512static inline struct dentry *
513dentry_kill(struct dentry *dentry, int unlock_on_failure)
501 __releases(dentry->d_lock) 514 __releases(dentry->d_lock)
502{ 515{
503 struct inode *inode; 516 struct inode *inode;
@@ -506,8 +519,10 @@ static inline struct dentry *dentry_kill(struct dentry *dentry)
506 inode = dentry->d_inode; 519 inode = dentry->d_inode;
507 if (inode && !spin_trylock(&inode->i_lock)) { 520 if (inode && !spin_trylock(&inode->i_lock)) {
508relock: 521relock:
509 spin_unlock(&dentry->d_lock); 522 if (unlock_on_failure) {
510 cpu_relax(); 523 spin_unlock(&dentry->d_lock);
524 cpu_relax();
525 }
511 return dentry; /* try again with same dentry */ 526 return dentry; /* try again with same dentry */
512 } 527 }
513 if (IS_ROOT(dentry)) 528 if (IS_ROOT(dentry))
@@ -590,7 +605,7 @@ repeat:
590 return; 605 return;
591 606
592kill_it: 607kill_it:
593 dentry = dentry_kill(dentry); 608 dentry = dentry_kill(dentry, 1);
594 if (dentry) 609 if (dentry)
595 goto repeat; 610 goto repeat;
596} 611}
@@ -810,12 +825,12 @@ EXPORT_SYMBOL(d_prune_aliases);
810 * 825 *
811 * This may fail if locks cannot be acquired no problem, just try again. 826 * This may fail if locks cannot be acquired no problem, just try again.
812 */ 827 */
813static void try_prune_one_dentry(struct dentry *dentry) 828static struct dentry * try_prune_one_dentry(struct dentry *dentry)
814 __releases(dentry->d_lock) 829 __releases(dentry->d_lock)
815{ 830{
816 struct dentry *parent; 831 struct dentry *parent;
817 832
818 parent = dentry_kill(dentry); 833 parent = dentry_kill(dentry, 0);
819 /* 834 /*
820 * If dentry_kill returns NULL, we have nothing more to do. 835 * If dentry_kill returns NULL, we have nothing more to do.
821 * if it returns the same dentry, trylocks failed. In either 836 * if it returns the same dentry, trylocks failed. In either
@@ -827,17 +842,18 @@ static void try_prune_one_dentry(struct dentry *dentry)
827 * fragmentation. 842 * fragmentation.
828 */ 843 */
829 if (!parent) 844 if (!parent)
830 return; 845 return NULL;
831 if (parent == dentry) 846 if (parent == dentry)
832 return; 847 return dentry;
833 848
834 /* Prune ancestors. */ 849 /* Prune ancestors. */
835 dentry = parent; 850 dentry = parent;
836 while (dentry) { 851 while (dentry) {
837 if (lockref_put_or_lock(&dentry->d_lockref)) 852 if (lockref_put_or_lock(&dentry->d_lockref))
838 return; 853 return NULL;
839 dentry = dentry_kill(dentry); 854 dentry = dentry_kill(dentry, 1);
840 } 855 }
856 return NULL;
841} 857}
842 858
843static void shrink_dentry_list(struct list_head *list) 859static void shrink_dentry_list(struct list_head *list)
@@ -856,21 +872,31 @@ static void shrink_dentry_list(struct list_head *list)
856 } 872 }
857 873
858 /* 874 /*
875 * The dispose list is isolated and dentries are not accounted
876 * to the LRU here, so we can simply remove it from the list
877 * here regardless of whether it is referenced or not.
878 */
879 list_del_init(&dentry->d_lru);
880 dentry->d_flags &= ~DCACHE_SHRINK_LIST;
881
882 /*
859 * We found an inuse dentry which was not removed from 883 * We found an inuse dentry which was not removed from
860 * the LRU because of laziness during lookup. Do not free 884 * the LRU because of laziness during lookup. Do not free it.
861 * it - just keep it off the LRU list.
862 */ 885 */
863 if (dentry->d_lockref.count) { 886 if (dentry->d_lockref.count) {
864 dentry_lru_del(dentry);
865 spin_unlock(&dentry->d_lock); 887 spin_unlock(&dentry->d_lock);
866 continue; 888 continue;
867 } 889 }
868
869 rcu_read_unlock(); 890 rcu_read_unlock();
870 891
871 try_prune_one_dentry(dentry); 892 dentry = try_prune_one_dentry(dentry);
872 893
873 rcu_read_lock(); 894 rcu_read_lock();
895 if (dentry) {
896 dentry->d_flags |= DCACHE_SHRINK_LIST;
897 list_add(&dentry->d_lru, list);
898 spin_unlock(&dentry->d_lock);
899 }
874 } 900 }
875 rcu_read_unlock(); 901 rcu_read_unlock();
876} 902}
@@ -911,8 +937,10 @@ relock:
911 list_move(&dentry->d_lru, &referenced); 937 list_move(&dentry->d_lru, &referenced);
912 spin_unlock(&dentry->d_lock); 938 spin_unlock(&dentry->d_lock);
913 } else { 939 } else {
914 list_move_tail(&dentry->d_lru, &tmp); 940 list_move(&dentry->d_lru, &tmp);
915 dentry->d_flags |= DCACHE_SHRINK_LIST; 941 dentry->d_flags |= DCACHE_SHRINK_LIST;
942 this_cpu_dec(nr_dentry_unused);
943 sb->s_nr_dentry_unused--;
916 spin_unlock(&dentry->d_lock); 944 spin_unlock(&dentry->d_lock);
917 if (!--count) 945 if (!--count)
918 break; 946 break;
@@ -926,6 +954,27 @@ relock:
926 shrink_dentry_list(&tmp); 954 shrink_dentry_list(&tmp);
927} 955}
928 956
957/*
958 * Mark all the dentries as on being the dispose list so we don't think they are
959 * still on the LRU if we try to kill them from ascending the parent chain in
960 * try_prune_one_dentry() rather than directly from the dispose list.
961 */
962static void
963shrink_dcache_list(
964 struct list_head *dispose)
965{
966 struct dentry *dentry;
967
968 rcu_read_lock();
969 list_for_each_entry_rcu(dentry, dispose, d_lru) {
970 spin_lock(&dentry->d_lock);
971 dentry->d_flags |= DCACHE_SHRINK_LIST;
972 spin_unlock(&dentry->d_lock);
973 }
974 rcu_read_unlock();
975 shrink_dentry_list(dispose);
976}
977
929/** 978/**
930 * shrink_dcache_sb - shrink dcache for a superblock 979 * shrink_dcache_sb - shrink dcache for a superblock
931 * @sb: superblock 980 * @sb: superblock
@@ -939,9 +988,17 @@ void shrink_dcache_sb(struct super_block *sb)
939 988
940 spin_lock(&sb->s_dentry_lru_lock); 989 spin_lock(&sb->s_dentry_lru_lock);
941 while (!list_empty(&sb->s_dentry_lru)) { 990 while (!list_empty(&sb->s_dentry_lru)) {
991 /*
992 * account for removal here so we don't need to handle it later
993 * even though the dentry is no longer on the lru list.
994 */
942 list_splice_init(&sb->s_dentry_lru, &tmp); 995 list_splice_init(&sb->s_dentry_lru, &tmp);
996 this_cpu_sub(nr_dentry_unused, sb->s_nr_dentry_unused);
997 sb->s_nr_dentry_unused = 0;
943 spin_unlock(&sb->s_dentry_lru_lock); 998 spin_unlock(&sb->s_dentry_lru_lock);
944 shrink_dentry_list(&tmp); 999
1000 shrink_dcache_list(&tmp);
1001
945 spin_lock(&sb->s_dentry_lru_lock); 1002 spin_lock(&sb->s_dentry_lru_lock);
946 } 1003 }
947 spin_unlock(&sb->s_dentry_lru_lock); 1004 spin_unlock(&sb->s_dentry_lru_lock);