@@ -188,13 +188,25 @@ int btrfs_alloc_stripe_hash_table(struct btrfs_fs_info *info)
188
188
struct btrfs_stripe_hash * h ;
189
189
int num_entries = 1 << BTRFS_STRIPE_HASH_TABLE_BITS ;
190
190
int i ;
191
+ int table_size ;
191
192
192
193
if (info -> stripe_hash_table )
193
194
return 0 ;
194
195
195
- table = kzalloc (sizeof (* table ) + sizeof (* h ) * num_entries , GFP_NOFS );
196
- if (!table )
197
- return - ENOMEM ;
196
+ /*
197
+ * The table is large, starting with order 4 and can go as high as
198
+ * order 7 in case lock debugging is turned on.
199
+ *
200
+ * Try harder to allocate and fallback to vmalloc to lower the chance
201
+ * of a failing mount.
202
+ */
203
+ table_size = sizeof (* table ) + sizeof (* h ) * num_entries ;
204
+ table = kzalloc (table_size , GFP_KERNEL | __GFP_NOWARN | __GFP_REPEAT );
205
+ if (!table ) {
206
+ table = vzalloc (table_size );
207
+ if (!table )
208
+ return - ENOMEM ;
209
+ }
198
210
199
211
spin_lock_init (& table -> cache_lock );
200
212
INIT_LIST_HEAD (& table -> stripe_cache );
@@ -209,8 +221,12 @@ int btrfs_alloc_stripe_hash_table(struct btrfs_fs_info *info)
209
221
}
210
222
211
223
x = cmpxchg (& info -> stripe_hash_table , NULL , table );
212
- if (x )
213
- kfree (x );
224
+ if (x ) {
225
+ if (is_vmalloc_addr (x ))
226
+ vfree (x );
227
+ else
228
+ kfree (x );
229
+ }
214
230
return 0 ;
215
231
}
216
232
@@ -420,7 +436,10 @@ void btrfs_free_stripe_hash_table(struct btrfs_fs_info *info)
420
436
if (!info -> stripe_hash_table )
421
437
return ;
422
438
btrfs_clear_rbio_cache (info );
423
- kfree (info -> stripe_hash_table );
439
+ if (is_vmalloc_addr (info -> stripe_hash_table ))
440
+ vfree (info -> stripe_hash_table );
441
+ else
442
+ kfree (info -> stripe_hash_table );
424
443
info -> stripe_hash_table = NULL ;
425
444
}
426
445
0 commit comments