aboutsummaryrefslogtreecommitdiffstats
path: root/fs/dcache.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/dcache.c')
-rw-r--r--fs/dcache.c40
1 files changed, 22 insertions, 18 deletions
diff --git a/fs/dcache.c b/fs/dcache.c
index e368d4f412f9..7d34f04ec7aa 100644
--- a/fs/dcache.c
+++ b/fs/dcache.c
@@ -38,6 +38,8 @@
38#include <linux/prefetch.h> 38#include <linux/prefetch.h>
39#include <linux/ratelimit.h> 39#include <linux/ratelimit.h>
40#include <linux/list_lru.h> 40#include <linux/list_lru.h>
41#include <linux/kasan.h>
42
41#include "internal.h" 43#include "internal.h"
42#include "mount.h" 44#include "mount.h"
43 45
@@ -400,19 +402,20 @@ static void d_shrink_add(struct dentry *dentry, struct list_head *list)
400 * LRU lists entirely, while shrink_move moves it to the indicated 402 * LRU lists entirely, while shrink_move moves it to the indicated
401 * private list. 403 * private list.
402 */ 404 */
403static void d_lru_isolate(struct dentry *dentry) 405static void d_lru_isolate(struct list_lru_one *lru, struct dentry *dentry)
404{ 406{
405 D_FLAG_VERIFY(dentry, DCACHE_LRU_LIST); 407 D_FLAG_VERIFY(dentry, DCACHE_LRU_LIST);
406 dentry->d_flags &= ~DCACHE_LRU_LIST; 408 dentry->d_flags &= ~DCACHE_LRU_LIST;
407 this_cpu_dec(nr_dentry_unused); 409 this_cpu_dec(nr_dentry_unused);
408 list_del_init(&dentry->d_lru); 410 list_lru_isolate(lru, &dentry->d_lru);
409} 411}
410 412
411static void d_lru_shrink_move(struct dentry *dentry, struct list_head *list) 413static void d_lru_shrink_move(struct list_lru_one *lru, struct dentry *dentry,
414 struct list_head *list)
412{ 415{
413 D_FLAG_VERIFY(dentry, DCACHE_LRU_LIST); 416 D_FLAG_VERIFY(dentry, DCACHE_LRU_LIST);
414 dentry->d_flags |= DCACHE_SHRINK_LIST; 417 dentry->d_flags |= DCACHE_SHRINK_LIST;
415 list_move_tail(&dentry->d_lru, list); 418 list_lru_isolate_move(lru, &dentry->d_lru, list);
416} 419}
417 420
418/* 421/*
@@ -869,8 +872,8 @@ static void shrink_dentry_list(struct list_head *list)
869 } 872 }
870} 873}
871 874
872static enum lru_status 875static enum lru_status dentry_lru_isolate(struct list_head *item,
873dentry_lru_isolate(struct list_head *item, spinlock_t *lru_lock, void *arg) 876 struct list_lru_one *lru, spinlock_t *lru_lock, void *arg)
874{ 877{
875 struct list_head *freeable = arg; 878 struct list_head *freeable = arg;
876 struct dentry *dentry = container_of(item, struct dentry, d_lru); 879 struct dentry *dentry = container_of(item, struct dentry, d_lru);
@@ -890,7 +893,7 @@ dentry_lru_isolate(struct list_head *item, spinlock_t *lru_lock, void *arg)
890 * another pass through the LRU. 893 * another pass through the LRU.
891 */ 894 */
892 if (dentry->d_lockref.count) { 895 if (dentry->d_lockref.count) {
893 d_lru_isolate(dentry); 896 d_lru_isolate(lru, dentry);
894 spin_unlock(&dentry->d_lock); 897 spin_unlock(&dentry->d_lock);
895 return LRU_REMOVED; 898 return LRU_REMOVED;
896 } 899 }
@@ -921,7 +924,7 @@ dentry_lru_isolate(struct list_head *item, spinlock_t *lru_lock, void *arg)
921 return LRU_ROTATE; 924 return LRU_ROTATE;
922 } 925 }
923 926
924 d_lru_shrink_move(dentry, freeable); 927 d_lru_shrink_move(lru, dentry, freeable);
925 spin_unlock(&dentry->d_lock); 928 spin_unlock(&dentry->d_lock);
926 929
927 return LRU_REMOVED; 930 return LRU_REMOVED;
@@ -930,30 +933,28 @@ dentry_lru_isolate(struct list_head *item, spinlock_t *lru_lock, void *arg)
930/** 933/**
931 * prune_dcache_sb - shrink the dcache 934 * prune_dcache_sb - shrink the dcache
932 * @sb: superblock 935 * @sb: superblock
933 * @nr_to_scan : number of entries to try to free 936 * @sc: shrink control, passed to list_lru_shrink_walk()
934 * @nid: which node to scan for freeable entities
935 * 937 *
936 * Attempt to shrink the superblock dcache LRU by @nr_to_scan entries. This is 938 * Attempt to shrink the superblock dcache LRU by @sc->nr_to_scan entries. This
937 * done when we need more memory an called from the superblock shrinker 939 * is done when we need more memory and called from the superblock shrinker
938 * function. 940 * function.
939 * 941 *
940 * This function may fail to free any resources if all the dentries are in 942 * This function may fail to free any resources if all the dentries are in
941 * use. 943 * use.
942 */ 944 */
943long prune_dcache_sb(struct super_block *sb, unsigned long nr_to_scan, 945long prune_dcache_sb(struct super_block *sb, struct shrink_control *sc)
944 int nid)
945{ 946{
946 LIST_HEAD(dispose); 947 LIST_HEAD(dispose);
947 long freed; 948 long freed;
948 949
949 freed = list_lru_walk_node(&sb->s_dentry_lru, nid, dentry_lru_isolate, 950 freed = list_lru_shrink_walk(&sb->s_dentry_lru, sc,
950 &dispose, &nr_to_scan); 951 dentry_lru_isolate, &dispose);
951 shrink_dentry_list(&dispose); 952 shrink_dentry_list(&dispose);
952 return freed; 953 return freed;
953} 954}
954 955
955static enum lru_status dentry_lru_isolate_shrink(struct list_head *item, 956static enum lru_status dentry_lru_isolate_shrink(struct list_head *item,
956 spinlock_t *lru_lock, void *arg) 957 struct list_lru_one *lru, spinlock_t *lru_lock, void *arg)
957{ 958{
958 struct list_head *freeable = arg; 959 struct list_head *freeable = arg;
959 struct dentry *dentry = container_of(item, struct dentry, d_lru); 960 struct dentry *dentry = container_of(item, struct dentry, d_lru);
@@ -966,7 +967,7 @@ static enum lru_status dentry_lru_isolate_shrink(struct list_head *item,
966 if (!spin_trylock(&dentry->d_lock)) 967 if (!spin_trylock(&dentry->d_lock))
967 return LRU_SKIP; 968 return LRU_SKIP;
968 969
969 d_lru_shrink_move(dentry, freeable); 970 d_lru_shrink_move(lru, dentry, freeable);
970 spin_unlock(&dentry->d_lock); 971 spin_unlock(&dentry->d_lock);
971 972
972 return LRU_REMOVED; 973 return LRU_REMOVED;
@@ -1430,6 +1431,9 @@ struct dentry *__d_alloc(struct super_block *sb, const struct qstr *name)
1430 } 1431 }
1431 atomic_set(&p->u.count, 1); 1432 atomic_set(&p->u.count, 1);
1432 dname = p->name; 1433 dname = p->name;
1434 if (IS_ENABLED(CONFIG_DCACHE_WORD_ACCESS))
1435 kasan_unpoison_shadow(dname,
1436 round_up(name->len + 1, sizeof(unsigned long)));
1433 } else { 1437 } else {
1434 dname = dentry->d_iname; 1438 dname = dentry->d_iname;
1435 } 1439 }