@@ -1935,12 +1935,14 @@ r5l_recovery_replay_one_stripe(struct r5conf *conf,
1935
1935
}
1936
1936
1937
1937
static struct stripe_head *
1938
- r5c_recovery_alloc_stripe (struct r5conf * conf ,
1939
- sector_t stripe_sect )
1938
+ r5c_recovery_alloc_stripe (
1939
+ struct r5conf * conf ,
1940
+ sector_t stripe_sect ,
1941
+ int noblock )
1940
1942
{
1941
1943
struct stripe_head * sh ;
1942
1944
1943
- sh = raid5_get_active_stripe (conf , stripe_sect , 0 , 1 , 0 );
1945
+ sh = raid5_get_active_stripe (conf , stripe_sect , 0 , noblock , 0 );
1944
1946
if (!sh )
1945
1947
return NULL ; /* no more stripe available */
1946
1948
@@ -2150,7 +2152,7 @@ r5c_recovery_analyze_meta_block(struct r5l_log *log,
2150
2152
stripe_sect );
2151
2153
2152
2154
if (!sh ) {
2153
- sh = r5c_recovery_alloc_stripe (conf , stripe_sect );
2155
+ sh = r5c_recovery_alloc_stripe (conf , stripe_sect , 1 );
2154
2156
/*
2155
2157
* cannot get stripe from raid5_get_active_stripe
2156
2158
* try replay some stripes
@@ -2159,20 +2161,29 @@ r5c_recovery_analyze_meta_block(struct r5l_log *log,
2159
2161
r5c_recovery_replay_stripes (
2160
2162
cached_stripe_list , ctx );
2161
2163
sh = r5c_recovery_alloc_stripe (
2162
- conf , stripe_sect );
2164
+ conf , stripe_sect , 1 );
2163
2165
}
2164
2166
if (!sh ) {
2167
+ int new_size = conf -> min_nr_stripes * 2 ;
2165
2168
pr_debug ("md/raid:%s: Increasing stripe cache size to %d to recovery data on journal.\n" ,
2166
2169
mdname (mddev ),
2167
- conf -> min_nr_stripes * 2 );
2168
- raid5_set_cache_size (mddev ,
2169
- conf -> min_nr_stripes * 2 );
2170
- sh = r5c_recovery_alloc_stripe (conf ,
2171
- stripe_sect );
2170
+ new_size );
2171
+ ret = raid5_set_cache_size (mddev , new_size );
2172
+ if (conf -> min_nr_stripes <= new_size / 2 ) {
2173
+ pr_err ("md/raid:%s: Cannot increase cache size, ret=%d, new_size=%d, min_nr_stripes=%d, max_nr_stripes=%d\n" ,
2174
+ mdname (mddev ),
2175
+ ret ,
2176
+ new_size ,
2177
+ conf -> min_nr_stripes ,
2178
+ conf -> max_nr_stripes );
2179
+ return - ENOMEM ;
2180
+ }
2181
+ sh = r5c_recovery_alloc_stripe (
2182
+ conf , stripe_sect , 0 );
2172
2183
}
2173
2184
if (!sh ) {
2174
2185
pr_err ("md/raid:%s: Cannot get enough stripes due to memory pressure. Recovery failed.\n" ,
2175
- mdname (mddev ));
2186
+ mdname (mddev ));
2176
2187
return - ENOMEM ;
2177
2188
}
2178
2189
list_add_tail (& sh -> lru , cached_stripe_list );
0 commit comments