aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ext4
diff options
context:
space:
mode:
authorTheodore Ts'o <tytso@mit.edu>2013-07-13 00:40:35 -0400
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2013-07-21 21:21:33 -0400
commit7557d8d5a46aaa4d0ec98bffdeedf9f3c7464088 (patch)
tree6606be5385d264bfb902f499c16540676dbba802 /fs/ext4
parentbbb1d9216c9d8f5ac0aca90719512deae7f989ea (diff)
ext4: don't allow ext4_free_blocks() to fail due to ENOMEM
commit e7676a704ee0a1ef71a6b23760b5a8f6896cb1a1 upstream. The filesystem should not be marked inconsistent if ext4_free_blocks() is not able to allocate memory. Unfortunately some callers (most notably ext4_truncate) don't have a way to reflect an error back up to the VFS. And even if we did, most userspace applications won't deal with most system calls returning ENOMEM anyway. Reported-by: Nagachandra P <nagachandra@gmail.com> Signed-off-by: "Theodore Ts'o" <tytso@mit.edu> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'fs/ext4')
-rw-r--r--fs/ext4/mballoc.c11
1 files changed, 8 insertions, 3 deletions
diff --git a/fs/ext4/mballoc.c b/fs/ext4/mballoc.c
index def84082a9a9..59c6750b894f 100644
--- a/fs/ext4/mballoc.c
+++ b/fs/ext4/mballoc.c
@@ -4735,11 +4735,16 @@ do_more:
4735 * blocks being freed are metadata. these blocks shouldn't 4735 * blocks being freed are metadata. these blocks shouldn't
4736 * be used until this transaction is committed 4736 * be used until this transaction is committed
4737 */ 4737 */
4738 retry:
4738 new_entry = kmem_cache_alloc(ext4_free_data_cachep, GFP_NOFS); 4739 new_entry = kmem_cache_alloc(ext4_free_data_cachep, GFP_NOFS);
4739 if (!new_entry) { 4740 if (!new_entry) {
4740 ext4_mb_unload_buddy(&e4b); 4741 /*
4741 err = -ENOMEM; 4742 * We use a retry loop because
4742 goto error_return; 4743 * ext4_free_blocks() is not allowed to fail.
4744 */
4745 cond_resched();
4746 congestion_wait(BLK_RW_ASYNC, HZ/50);
4747 goto retry;
4743 } 4748 }
4744 new_entry->efd_start_cluster = bit; 4749 new_entry->efd_start_cluster = bit;
4745 new_entry->efd_group = block_group; 4750 new_entry->efd_group = block_group;