@@ -379,21 +379,22 @@ static struct extent_tree *__grab_extent_tree(struct inode *inode,
379379}
380380
381381static unsigned int __free_extent_tree (struct f2fs_sb_info * sbi ,
382- struct extent_tree * et )
382+ struct extent_tree * et , unsigned int nr_shrink )
383383{
384384 struct rb_node * node , * next ;
385385 struct extent_node * en ;
386- unsigned int count = atomic_read ( & et -> node_cnt ) ;
386+ unsigned int count ;
387387
388388 node = rb_first_cached (& et -> root );
389- while (node ) {
389+
390+ for (count = 0 ; node && count < nr_shrink ; count ++ ) {
390391 next = rb_next (node );
391392 en = rb_entry (node , struct extent_node , rb_node );
392393 __release_extent_node (sbi , et , en );
393394 node = next ;
394395 }
395396
396- return count - atomic_read ( & et -> node_cnt ) ;
397+ return count ;
397398}
398399
399400static void __drop_largest_extent (struct extent_tree * et ,
@@ -622,6 +623,30 @@ static struct extent_node *__insert_extent_tree(struct f2fs_sb_info *sbi,
622623 return en ;
623624}
624625
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+
625650static void __update_extent_tree_range (struct inode * inode ,
626651 struct extent_info * tei , enum extent_type type )
627652{
@@ -760,9 +785,6 @@ static void __update_extent_tree_range(struct inode *inode,
760785 }
761786 }
762787
763- if (is_inode_flag_set (inode , FI_NO_EXTENT ))
764- __free_extent_tree (sbi , et );
765-
766788 if (et -> largest_updated ) {
767789 et -> largest_updated = false;
768790 updated = true;
@@ -780,6 +802,9 @@ static void __update_extent_tree_range(struct inode *inode,
780802out_read_extent_cache :
781803 write_unlock (& et -> lock );
782804
805+ if (is_inode_flag_set (inode , FI_NO_EXTENT ))
806+ __destroy_extent_node (inode , EX_READ );
807+
783808 if (updated )
784809 f2fs_mark_inode_dirty_sync (inode , true);
785810}
@@ -942,10 +967,14 @@ static unsigned int __shrink_extent_tree(struct f2fs_sb_info *sbi, int nr_shrink
942967 list_for_each_entry_safe (et , next , & eti -> zombie_list , list ) {
943968 if (atomic_read (& et -> node_cnt )) {
944969 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 );
946972 write_unlock (& et -> lock );
947973 }
948- f2fs_bug_on (sbi , atomic_read (& et -> node_cnt ));
974+
975+ if (atomic_read (& et -> node_cnt ))
976+ goto unlock_out ;
977+
949978 list_del_init (& et -> list );
950979 radix_tree_delete (& eti -> extent_tree_root , et -> ino );
951980 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
10841113 return __shrink_extent_tree (sbi , nr_shrink , EX_BLOCK_AGE );
10851114}
10861115
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-
11041116void f2fs_destroy_extent_node (struct inode * inode )
11051117{
11061118 __destroy_extent_node (inode , EX_READ );
@@ -1109,15 +1121,13 @@ void f2fs_destroy_extent_node(struct inode *inode)
11091121
11101122static void __drop_extent_tree (struct inode * inode , enum extent_type type )
11111123{
1112- struct f2fs_sb_info * sbi = F2FS_I_SB (inode );
11131124 struct extent_tree * et = F2FS_I (inode )-> extent_tree [type ];
11141125 bool updated = false;
11151126
11161127 if (!__may_extent_tree (inode , type ))
11171128 return ;
11181129
11191130 write_lock (& et -> lock );
1120- __free_extent_tree (sbi , et );
11211131 if (type == EX_READ ) {
11221132 set_inode_flag (inode , FI_NO_EXTENT );
11231133 if (et -> largest .len ) {
@@ -1126,6 +1136,9 @@ static void __drop_extent_tree(struct inode *inode, enum extent_type type)
11261136 }
11271137 }
11281138 write_unlock (& et -> lock );
1139+
1140+ __destroy_extent_node (inode , type );
1141+
11291142 if (updated )
11301143 f2fs_mark_inode_dirty_sync (inode , true);
11311144}
0 commit comments