@@ -379,21 +379,22 @@ static struct extent_tree *__grab_extent_tree(struct inode *inode,
379
379
}
380
380
381
381
static unsigned int __free_extent_tree (struct f2fs_sb_info * sbi ,
382
- struct extent_tree * et )
382
+ struct extent_tree * et , unsigned int nr_shrink )
383
383
{
384
384
struct rb_node * node , * next ;
385
385
struct extent_node * en ;
386
- unsigned int count = atomic_read ( & et -> node_cnt ) ;
386
+ unsigned int count ;
387
387
388
388
node = rb_first_cached (& et -> root );
389
- while (node ) {
389
+
390
+ for (count = 0 ; node && count < nr_shrink ; count ++ ) {
390
391
next = rb_next (node );
391
392
en = rb_entry (node , struct extent_node , rb_node );
392
393
__release_extent_node (sbi , et , en );
393
394
node = next ;
394
395
}
395
396
396
- return count - atomic_read ( & et -> node_cnt ) ;
397
+ return count ;
397
398
}
398
399
399
400
static void __drop_largest_extent (struct extent_tree * et ,
@@ -622,6 +623,30 @@ static struct extent_node *__insert_extent_tree(struct f2fs_sb_info *sbi,
622
623
return en ;
623
624
}
624
625
626
+ static unsigned int __destroy_extent_node (struct inode * inode ,
627
+ enum extent_type type )
628
+ {
629
+ struct f2fs_sb_info * sbi = F2FS_I_SB (inode );
630
+ struct extent_tree * et = F2FS_I (inode )-> extent_tree [type ];
631
+ unsigned int nr_shrink = type == EX_READ ?
632
+ READ_EXTENT_CACHE_SHRINK_NUMBER :
633
+ AGE_EXTENT_CACHE_SHRINK_NUMBER ;
634
+ unsigned int node_cnt = 0 ;
635
+
636
+ if (!et || !atomic_read (& et -> node_cnt ))
637
+ return 0 ;
638
+
639
+ while (atomic_read (& et -> node_cnt )) {
640
+ write_lock (& et -> lock );
641
+ node_cnt += __free_extent_tree (sbi , et , nr_shrink );
642
+ write_unlock (& et -> lock );
643
+ }
644
+
645
+ f2fs_bug_on (sbi , atomic_read (& et -> node_cnt ));
646
+
647
+ return node_cnt ;
648
+ }
649
+
625
650
static void __update_extent_tree_range (struct inode * inode ,
626
651
struct extent_info * tei , enum extent_type type )
627
652
{
@@ -760,9 +785,6 @@ static void __update_extent_tree_range(struct inode *inode,
760
785
}
761
786
}
762
787
763
- if (is_inode_flag_set (inode , FI_NO_EXTENT ))
764
- __free_extent_tree (sbi , et );
765
-
766
788
if (et -> largest_updated ) {
767
789
et -> largest_updated = false;
768
790
updated = true;
@@ -780,6 +802,9 @@ static void __update_extent_tree_range(struct inode *inode,
780
802
out_read_extent_cache :
781
803
write_unlock (& et -> lock );
782
804
805
+ if (is_inode_flag_set (inode , FI_NO_EXTENT ))
806
+ __destroy_extent_node (inode , EX_READ );
807
+
783
808
if (updated )
784
809
f2fs_mark_inode_dirty_sync (inode , true);
785
810
}
@@ -942,10 +967,14 @@ static unsigned int __shrink_extent_tree(struct f2fs_sb_info *sbi, int nr_shrink
942
967
list_for_each_entry_safe (et , next , & eti -> zombie_list , list ) {
943
968
if (atomic_read (& et -> node_cnt )) {
944
969
write_lock (& et -> lock );
945
- node_cnt += __free_extent_tree (sbi , et );
970
+ node_cnt += __free_extent_tree (sbi , et ,
971
+ nr_shrink - node_cnt - tree_cnt );
946
972
write_unlock (& et -> lock );
947
973
}
948
- f2fs_bug_on (sbi , atomic_read (& et -> node_cnt ));
974
+
975
+ if (atomic_read (& et -> node_cnt ))
976
+ goto unlock_out ;
977
+
949
978
list_del_init (& et -> list );
950
979
radix_tree_delete (& eti -> extent_tree_root , et -> ino );
951
980
kmem_cache_free (extent_tree_slab , et );
@@ -1084,23 +1113,6 @@ unsigned int f2fs_shrink_age_extent_tree(struct f2fs_sb_info *sbi, int nr_shrink
1084
1113
return __shrink_extent_tree (sbi , nr_shrink , EX_BLOCK_AGE );
1085
1114
}
1086
1115
1087
- static unsigned int __destroy_extent_node (struct inode * inode ,
1088
- enum extent_type type )
1089
- {
1090
- struct f2fs_sb_info * sbi = F2FS_I_SB (inode );
1091
- struct extent_tree * et = F2FS_I (inode )-> extent_tree [type ];
1092
- unsigned int node_cnt = 0 ;
1093
-
1094
- if (!et || !atomic_read (& et -> node_cnt ))
1095
- return 0 ;
1096
-
1097
- write_lock (& et -> lock );
1098
- node_cnt = __free_extent_tree (sbi , et );
1099
- write_unlock (& et -> lock );
1100
-
1101
- return node_cnt ;
1102
- }
1103
-
1104
1116
void f2fs_destroy_extent_node (struct inode * inode )
1105
1117
{
1106
1118
__destroy_extent_node (inode , EX_READ );
@@ -1109,15 +1121,13 @@ void f2fs_destroy_extent_node(struct inode *inode)
1109
1121
1110
1122
static void __drop_extent_tree (struct inode * inode , enum extent_type type )
1111
1123
{
1112
- struct f2fs_sb_info * sbi = F2FS_I_SB (inode );
1113
1124
struct extent_tree * et = F2FS_I (inode )-> extent_tree [type ];
1114
1125
bool updated = false;
1115
1126
1116
1127
if (!__may_extent_tree (inode , type ))
1117
1128
return ;
1118
1129
1119
1130
write_lock (& et -> lock );
1120
- __free_extent_tree (sbi , et );
1121
1131
if (type == EX_READ ) {
1122
1132
set_inode_flag (inode , FI_NO_EXTENT );
1123
1133
if (et -> largest .len ) {
@@ -1126,6 +1136,9 @@ static void __drop_extent_tree(struct inode *inode, enum extent_type type)
1126
1136
}
1127
1137
}
1128
1138
write_unlock (& et -> lock );
1139
+
1140
+ __destroy_extent_node (inode , type );
1141
+
1129
1142
if (updated )
1130
1143
f2fs_mark_inode_dirty_sync (inode , true);
1131
1144
}
0 commit comments