4.9-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Konstantin Khlebnikov <khlebni...@yandex-team.ru>


[ Upstream commit 9651e6b2e20648d04d5e1fe6479a3056047e8781 ]

I've got another report about breaking ext4 by ENOMEM error returned from
ext4_mb_load_buddy() caused by memory shortage in memory cgroup.
This time inside ext4_discard_preallocations().

This patch replaces ext4_error() with ext4_warning() where errors returned
from ext4_mb_load_buddy() are not fatal and handled by caller:
* ext4_mb_discard_group_preallocations() - called before generating ENOSPC,
  we'll try to discard other group or return ENOSPC into user-space.
* ext4_trim_all_free() - just stop trimming and return ENOMEM from ioctl.

Some callers cannot handle errors, thus __GFP_NOFAIL is used for them:
* ext4_discard_preallocations()
* ext4_mb_discard_lg_preallocations()

Fixes: adb7ef600cc9 ("ext4: use __GFP_NOFAIL in ext4_free_blocks()")
Signed-off-by: Konstantin Khlebnikov <khlebni...@yandex-team.ru>
Signed-off-by: Theodore Ts'o <ty...@mit.edu>
Signed-off-by: Sasha Levin <alexander.le...@microsoft.com>
Signed-off-by: Greg Kroah-Hartman <gre...@linuxfoundation.org>
---
 fs/ext4/mballoc.c |   23 ++++++++++++++---------
 1 file changed, 14 insertions(+), 9 deletions(-)

--- a/fs/ext4/mballoc.c
+++ b/fs/ext4/mballoc.c
@@ -3877,7 +3877,8 @@ ext4_mb_discard_group_preallocations(str
 
        err = ext4_mb_load_buddy(sb, group, &e4b);
        if (err) {
-               ext4_error(sb, "Error loading buddy information for %u", group);
+               ext4_warning(sb, "Error %d loading buddy information for %u",
+                            err, group);
                put_bh(bitmap_bh);
                return 0;
        }
@@ -4034,10 +4035,11 @@ repeat:
                BUG_ON(pa->pa_type != MB_INODE_PA);
                group = ext4_get_group_number(sb, pa->pa_pstart);
 
-               err = ext4_mb_load_buddy(sb, group, &e4b);
+               err = ext4_mb_load_buddy_gfp(sb, group, &e4b,
+                                            GFP_NOFS|__GFP_NOFAIL);
                if (err) {
-                       ext4_error(sb, "Error loading buddy information for %u",
-                                       group);
+                       ext4_error(sb, "Error %d loading buddy information for 
%u",
+                                  err, group);
                        continue;
                }
 
@@ -4293,11 +4295,14 @@ ext4_mb_discard_lg_preallocations(struct
        spin_unlock(&lg->lg_prealloc_lock);
 
        list_for_each_entry_safe(pa, tmp, &discard_list, u.pa_tmp_list) {
+               int err;
 
                group = ext4_get_group_number(sb, pa->pa_pstart);
-               if (ext4_mb_load_buddy(sb, group, &e4b)) {
-                       ext4_error(sb, "Error loading buddy information for %u",
-                                       group);
+               err = ext4_mb_load_buddy_gfp(sb, group, &e4b,
+                                            GFP_NOFS|__GFP_NOFAIL);
+               if (err) {
+                       ext4_error(sb, "Error %d loading buddy information for 
%u",
+                                  err, group);
                        continue;
                }
                ext4_lock_group(sb, group);
@@ -5117,8 +5122,8 @@ ext4_trim_all_free(struct super_block *s
 
        ret = ext4_mb_load_buddy(sb, group, &e4b);
        if (ret) {
-               ext4_error(sb, "Error in loading buddy "
-                               "information for %u", group);
+               ext4_warning(sb, "Error %d loading buddy information for %u",
+                            ret, group);
                return ret;
        }
        bitmap = e4b.bd_bitmap;


Reply via email to