diff --git a/fs/ext4/mballoc.c b/fs/ext4/mballoc.c index a9ff5e5137ca85306f408eda2cab09669962f603..4bbbf13bd7435fd2181aee091dfd6212347463da 100644 --- a/fs/ext4/mballoc.c +++ b/fs/ext4/mballoc.c @@ -4740,11 +4740,16 @@ void ext4_free_blocks(handle_t *handle, struct inode *inode, * blocks being freed are metadata. these blocks shouldn't * be used until this transaction is committed */ + retry: new_entry = kmem_cache_alloc(ext4_free_data_cachep, GFP_NOFS); if (!new_entry) { - ext4_mb_unload_buddy(&e4b); - err = -ENOMEM; - goto error_return; + /* + * We use a retry loop because + * ext4_free_blocks() is not allowed to fail. + */ + cond_resched(); + congestion_wait(BLK_RW_ASYNC, HZ/50); + goto retry; } new_entry->efd_start_cluster = bit; new_entry->efd_group = block_group;