1 ext4: handle the rest of ext4_mb_load_buddy() ENOMEM errors
3 From: Konstantin Khlebnikov <khlebnikov@yandex-team.ru>
5 I've got another report about breaking ext4 by ENOMEM error returned from
6 ext4_mb_load_buddy() caused by memory shortage in memory cgroup.
7 This time inside ext4_discard_preallocations().
9 This patch replaces ext4_error() with ext4_warning() where errors returned
10 from ext4_mb_load_buddy() are not fatal and handled by caller:
11 * ext4_mb_discard_group_preallocations() - called before generating ENOSPC,
12 we'll try to discard other group or return ENOSPC into user-space.
13 * ext4_trim_all_free() - just stop trimming and return ENOMEM from ioctl.
15 Some callers cannot handle errors, thus __GFP_NOFAIL is used for them:
16 * ext4_discard_preallocations()
17 * ext4_mb_discard_lg_preallocations()
19 Fixes: adb7ef600cc9 ("ext4: use __GFP_NOFAIL in ext4_free_blocks()")
20 Signed-off-by: Konstantin Khlebnikov <khlebnikov@yandex-team.ru>
21 Signed-off-by: Theodore Ts'o <tytso@mit.edu>
23 fs/ext4/mballoc.c | 23 ++++++++++++++---------
24 1 file changed, 14 insertions(+), 9 deletions(-)
26 diff --git a/fs/ext4/mballoc.c b/fs/ext4/mballoc.c
27 index 5083bce20ac4..b7928cddd539 100644
28 --- a/fs/ext4/mballoc.c
29 +++ b/fs/ext4/mballoc.c
30 @@ -3887,7 +3887,8 @@ ext4_mb_discard_group_preallocations(struct super_block *sb,
32 err = ext4_mb_load_buddy(sb, group, &e4b);
34 - ext4_error(sb, "Error loading buddy information for %u", group);
35 + ext4_warning(sb, "Error %d loading buddy information for %u",
40 @@ -4044,10 +4045,11 @@ void ext4_discard_preallocations(struct inode *inode)
41 BUG_ON(pa->pa_type != MB_INODE_PA);
42 group = ext4_get_group_number(sb, pa->pa_pstart);
44 - err = ext4_mb_load_buddy(sb, group, &e4b);
45 + err = ext4_mb_load_buddy_gfp(sb, group, &e4b,
46 + GFP_NOFS|__GFP_NOFAIL);
48 - ext4_error(sb, "Error loading buddy information for %u",
50 + ext4_error(sb, "Error %d loading buddy information for %u",
55 @@ -4303,11 +4305,14 @@ ext4_mb_discard_lg_preallocations(struct super_block *sb,
56 spin_unlock(&lg->lg_prealloc_lock);
58 list_for_each_entry_safe(pa, tmp, &discard_list, u.pa_tmp_list) {
61 group = ext4_get_group_number(sb, pa->pa_pstart);
62 - if (ext4_mb_load_buddy(sb, group, &e4b)) {
63 - ext4_error(sb, "Error loading buddy information for %u",
65 + err = ext4_mb_load_buddy_gfp(sb, group, &e4b,
66 + GFP_NOFS|__GFP_NOFAIL);
68 + ext4_error(sb, "Error %d loading buddy information for %u",
72 ext4_lock_group(sb, group);
73 @@ -5127,8 +5132,8 @@ ext4_trim_all_free(struct super_block *sb, ext4_group_t group,
75 ret = ext4_mb_load_buddy(sb, group, &e4b);
77 - ext4_error(sb, "Error in loading buddy "
78 - "information for %u", group);
79 + ext4_warning(sb, "Error %d loading buddy information for %u",
83 bitmap = e4b.bd_bitmap;