@@ -148,6 +148,8 @@ static int __es_remove_extent(struct inode *inode, ext4_lblk_t lblk,
148
148
ext4_lblk_t end );
149
149
static int __es_try_to_reclaim_extents (struct ext4_inode_info * ei ,
150
150
int nr_to_scan );
151
+ static int __ext4_es_shrink (struct ext4_sb_info * sbi , int nr_to_scan ,
152
+ struct ext4_inode_info * locked_ei );
151
153
152
154
int __init ext4_init_es (void )
153
155
{
@@ -665,7 +667,13 @@ int ext4_es_insert_extent(struct inode *inode, ext4_lblk_t lblk,
665
667
err = __es_remove_extent (inode , lblk , end );
666
668
if (err != 0 )
667
669
goto error ;
670
+ retry :
668
671
err = __es_insert_extent (inode , & newes );
672
+ if (err == - ENOMEM && __ext4_es_shrink (EXT4_SB (inode -> i_sb ), 1 ,
673
+ EXT4_I (inode )))
674
+ goto retry ;
675
+ if (err == - ENOMEM && !ext4_es_is_delayed (& newes ))
676
+ err = 0 ;
669
677
670
678
error :
671
679
write_unlock (& EXT4_I (inode )-> i_es_lock );
@@ -744,8 +752,10 @@ static int __es_remove_extent(struct inode *inode, ext4_lblk_t lblk,
744
752
struct extent_status orig_es ;
745
753
ext4_lblk_t len1 , len2 ;
746
754
ext4_fsblk_t block ;
747
- int err = 0 ;
755
+ int err ;
748
756
757
+ retry :
758
+ err = 0 ;
749
759
es = __es_tree_search (& tree -> root , lblk );
750
760
if (!es )
751
761
goto out ;
@@ -780,6 +790,10 @@ static int __es_remove_extent(struct inode *inode, ext4_lblk_t lblk,
780
790
if (err ) {
781
791
es -> es_lblk = orig_es .es_lblk ;
782
792
es -> es_len = orig_es .es_len ;
793
+ if ((err == - ENOMEM ) &&
794
+ __ext4_es_shrink (EXT4_SB (inode -> i_sb ), 1 ,
795
+ EXT4_I (inode )))
796
+ goto retry ;
783
797
goto out ;
784
798
}
785
799
} else {
@@ -889,22 +903,14 @@ static int ext4_inode_touch_time_cmp(void *priv, struct list_head *a,
889
903
return -1 ;
890
904
}
891
905
892
- static int ext4_es_shrink (struct shrinker * shrink , struct shrink_control * sc )
906
+ static int __ext4_es_shrink (struct ext4_sb_info * sbi , int nr_to_scan ,
907
+ struct ext4_inode_info * locked_ei )
893
908
{
894
- struct ext4_sb_info * sbi = container_of (shrink ,
895
- struct ext4_sb_info , s_es_shrinker );
896
909
struct ext4_inode_info * ei ;
897
910
struct list_head * cur , * tmp ;
898
911
LIST_HEAD (skiped );
899
- int nr_to_scan = sc -> nr_to_scan ;
900
912
int ret , nr_shrunk = 0 ;
901
913
902
- ret = percpu_counter_read_positive (& sbi -> s_extent_cache_cnt );
903
- trace_ext4_es_shrink_enter (sbi -> s_sb , nr_to_scan , ret );
904
-
905
- if (!nr_to_scan )
906
- return ret ;
907
-
908
914
spin_lock (& sbi -> s_es_lru_lock );
909
915
910
916
/*
@@ -933,7 +939,7 @@ static int ext4_es_shrink(struct shrinker *shrink, struct shrink_control *sc)
933
939
continue ;
934
940
}
935
941
936
- if (ei -> i_es_lru_nr == 0 )
942
+ if (ei -> i_es_lru_nr == 0 || ei == locked_ei )
937
943
continue ;
938
944
939
945
write_lock (& ei -> i_es_lock );
@@ -952,6 +958,27 @@ static int ext4_es_shrink(struct shrinker *shrink, struct shrink_control *sc)
952
958
list_splice_tail (& skiped , & sbi -> s_es_lru );
953
959
spin_unlock (& sbi -> s_es_lru_lock );
954
960
961
+ if (locked_ei && nr_shrunk == 0 )
962
+ nr_shrunk = __es_try_to_reclaim_extents (ei , nr_to_scan );
963
+
964
+ return nr_shrunk ;
965
+ }
966
+
967
+ static int ext4_es_shrink (struct shrinker * shrink , struct shrink_control * sc )
968
+ {
969
+ struct ext4_sb_info * sbi = container_of (shrink ,
970
+ struct ext4_sb_info , s_es_shrinker );
971
+ int nr_to_scan = sc -> nr_to_scan ;
972
+ int ret , nr_shrunk ;
973
+
974
+ ret = percpu_counter_read_positive (& sbi -> s_extent_cache_cnt );
975
+ trace_ext4_es_shrink_enter (sbi -> s_sb , nr_to_scan , ret );
976
+
977
+ if (!nr_to_scan )
978
+ return ret ;
979
+
980
+ nr_shrunk = __ext4_es_shrink (sbi , nr_to_scan , NULL );
981
+
955
982
ret = percpu_counter_read_positive (& sbi -> s_extent_cache_cnt );
956
983
trace_ext4_es_shrink_exit (sbi -> s_sb , nr_shrunk , ret );
957
984
return ret ;
0 commit comments