diff options
Diffstat (limited to 'fs/ext4/extents_status.c')
-rw-r--r-- | fs/ext4/extents_status.c | 33 |
1 files changed, 24 insertions, 9 deletions
diff --git a/fs/ext4/extents_status.c b/fs/ext4/extents_status.c index 2d1bdbe78c04..3981ff783950 100644 --- a/fs/ext4/extents_status.c +++ b/fs/ext4/extents_status.c | |||
@@ -931,13 +931,15 @@ static int __ext4_es_shrink(struct ext4_sb_info *sbi, int nr_to_scan, | |||
931 | struct ext4_inode_info *ei; | 931 | struct ext4_inode_info *ei; |
932 | struct list_head *cur, *tmp; | 932 | struct list_head *cur, *tmp; |
933 | LIST_HEAD(skipped); | 933 | LIST_HEAD(skipped); |
934 | int ret, nr_shrunk = 0; | 934 | int nr_shrunk = 0; |
935 | int retried = 0, skip_precached = 1, nr_skipped = 0; | 935 | int retried = 0, skip_precached = 1, nr_skipped = 0; |
936 | 936 | ||
937 | spin_lock(&sbi->s_es_lru_lock); | 937 | spin_lock(&sbi->s_es_lru_lock); |
938 | 938 | ||
939 | retry: | 939 | retry: |
940 | list_for_each_safe(cur, tmp, &sbi->s_es_lru) { | 940 | list_for_each_safe(cur, tmp, &sbi->s_es_lru) { |
941 | int shrunk; | ||
942 | |||
941 | /* | 943 | /* |
942 | * If we have already reclaimed all extents from extent | 944 | * If we have already reclaimed all extents from extent |
943 | * status tree, just stop the loop immediately. | 945 | * status tree, just stop the loop immediately. |
@@ -964,13 +966,13 @@ retry: | |||
964 | continue; | 966 | continue; |
965 | 967 | ||
966 | write_lock(&ei->i_es_lock); | 968 | write_lock(&ei->i_es_lock); |
967 | ret = __es_try_to_reclaim_extents(ei, nr_to_scan); | 969 | shrunk = __es_try_to_reclaim_extents(ei, nr_to_scan); |
968 | if (ei->i_es_lru_nr == 0) | 970 | if (ei->i_es_lru_nr == 0) |
969 | list_del_init(&ei->i_es_lru); | 971 | list_del_init(&ei->i_es_lru); |
970 | write_unlock(&ei->i_es_lock); | 972 | write_unlock(&ei->i_es_lock); |
971 | 973 | ||
972 | nr_shrunk += ret; | 974 | nr_shrunk += shrunk; |
973 | nr_to_scan -= ret; | 975 | nr_to_scan -= shrunk; |
974 | if (nr_to_scan == 0) | 976 | if (nr_to_scan == 0) |
975 | break; | 977 | break; |
976 | } | 978 | } |
@@ -1007,7 +1009,20 @@ retry: | |||
1007 | return nr_shrunk; | 1009 | return nr_shrunk; |
1008 | } | 1010 | } |
1009 | 1011 | ||
1010 | static int ext4_es_shrink(struct shrinker *shrink, struct shrink_control *sc) | 1012 | static unsigned long ext4_es_count(struct shrinker *shrink, |
1013 | struct shrink_control *sc) | ||
1014 | { | ||
1015 | unsigned long nr; | ||
1016 | struct ext4_sb_info *sbi; | ||
1017 | |||
1018 | sbi = container_of(shrink, struct ext4_sb_info, s_es_shrinker); | ||
1019 | nr = percpu_counter_read_positive(&sbi->s_extent_cache_cnt); | ||
1020 | trace_ext4_es_shrink_enter(sbi->s_sb, sc->nr_to_scan, nr); | ||
1021 | return nr; | ||
1022 | } | ||
1023 | |||
1024 | static unsigned long ext4_es_scan(struct shrinker *shrink, | ||
1025 | struct shrink_control *sc) | ||
1011 | { | 1026 | { |
1012 | struct ext4_sb_info *sbi = container_of(shrink, | 1027 | struct ext4_sb_info *sbi = container_of(shrink, |
1013 | struct ext4_sb_info, s_es_shrinker); | 1028 | struct ext4_sb_info, s_es_shrinker); |
@@ -1022,9 +1037,8 @@ static int ext4_es_shrink(struct shrinker *shrink, struct shrink_control *sc) | |||
1022 | 1037 | ||
1023 | nr_shrunk = __ext4_es_shrink(sbi, nr_to_scan, NULL); | 1038 | nr_shrunk = __ext4_es_shrink(sbi, nr_to_scan, NULL); |
1024 | 1039 | ||
1025 | ret = percpu_counter_read_positive(&sbi->s_extent_cache_cnt); | ||
1026 | trace_ext4_es_shrink_exit(sbi->s_sb, nr_shrunk, ret); | 1040 | trace_ext4_es_shrink_exit(sbi->s_sb, nr_shrunk, ret); |
1027 | return ret; | 1041 | return nr_shrunk; |
1028 | } | 1042 | } |
1029 | 1043 | ||
1030 | void ext4_es_register_shrinker(struct ext4_sb_info *sbi) | 1044 | void ext4_es_register_shrinker(struct ext4_sb_info *sbi) |
@@ -1032,7 +1046,8 @@ void ext4_es_register_shrinker(struct ext4_sb_info *sbi) | |||
1032 | INIT_LIST_HEAD(&sbi->s_es_lru); | 1046 | INIT_LIST_HEAD(&sbi->s_es_lru); |
1033 | spin_lock_init(&sbi->s_es_lru_lock); | 1047 | spin_lock_init(&sbi->s_es_lru_lock); |
1034 | sbi->s_es_last_sorted = 0; | 1048 | sbi->s_es_last_sorted = 0; |
1035 | sbi->s_es_shrinker.shrink = ext4_es_shrink; | 1049 | sbi->s_es_shrinker.scan_objects = ext4_es_scan; |
1050 | sbi->s_es_shrinker.count_objects = ext4_es_count; | ||
1036 | sbi->s_es_shrinker.seeks = DEFAULT_SEEKS; | 1051 | sbi->s_es_shrinker.seeks = DEFAULT_SEEKS; |
1037 | register_shrinker(&sbi->s_es_shrinker); | 1052 | register_shrinker(&sbi->s_es_shrinker); |
1038 | } | 1053 | } |
@@ -1076,7 +1091,7 @@ static int __es_try_to_reclaim_extents(struct ext4_inode_info *ei, | |||
1076 | struct ext4_es_tree *tree = &ei->i_es_tree; | 1091 | struct ext4_es_tree *tree = &ei->i_es_tree; |
1077 | struct rb_node *node; | 1092 | struct rb_node *node; |
1078 | struct extent_status *es; | 1093 | struct extent_status *es; |
1079 | int nr_shrunk = 0; | 1094 | unsigned long nr_shrunk = 0; |
1080 | static DEFINE_RATELIMIT_STATE(_rs, DEFAULT_RATELIMIT_INTERVAL, | 1095 | static DEFINE_RATELIMIT_STATE(_rs, DEFAULT_RATELIMIT_INTERVAL, |
1081 | DEFAULT_RATELIMIT_BURST); | 1096 | DEFAULT_RATELIMIT_BURST); |
1082 | 1097 | ||