add patch fix-fdatasync-after-extent-manipulation-operations
[ext4-patch-queue.git] / handle-the-rest-of-ext4_mb_load_buddy-ENOMEM-errors
blobc6d3edf1ed6a5b29efc9cb8249f4b4fc67ec4ce4
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>
22 ---
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);
33         if (err) {
34 -               ext4_error(sb, "Error loading buddy information for %u", group);
35 +               ext4_warning(sb, "Error %d loading buddy information for %u",
36 +                            err, group);
37                 put_bh(bitmap_bh);
38                 return 0;
39         }
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);
47                 if (err) {
48 -                       ext4_error(sb, "Error loading buddy information for %u",
49 -                                       group);
50 +                       ext4_error(sb, "Error %d loading buddy information for %u",
51 +                                  err, group);
52                         continue;
53                 }
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) {
59 +               int err;
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",
64 -                                       group);
65 +               err = ext4_mb_load_buddy_gfp(sb, group, &e4b,
66 +                                            GFP_NOFS|__GFP_NOFAIL);
67 +               if (err) {
68 +                       ext4_error(sb, "Error %d loading buddy information for %u",
69 +                                  err, group);
70                         continue;
71                 }
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);
76         if (ret) {
77 -               ext4_error(sb, "Error in loading buddy "
78 -                               "information for %u", group);
79 +               ext4_warning(sb, "Error %d loading buddy information for %u",
80 +                            ret, group);
81                 return ret;
82         }
83         bitmap = e4b.bd_bitmap;