lkml.org 
[lkml]   [2018]   [Mar]   [19]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH AUTOSEL for 4.9 087/281] ext4: handle the rest of ext4_mb_load_buddy() ENOMEM errors
    Date
    From: Konstantin Khlebnikov <khlebnikov@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 <khlebnikov@yandex-team.ru>
    Signed-off-by: Theodore Ts'o <tytso@mit.edu>
    Signed-off-by: Sasha Levin <alexander.levin@microsoft.com>
    ---
    fs/ext4/mballoc.c | 23 ++++++++++++++---------
    1 file changed, 14 insertions(+), 9 deletions(-)

    diff --git a/fs/ext4/mballoc.c b/fs/ext4/mballoc.c
    index 64056c6eb857..14bd37041e1a 100644
    --- a/fs/ext4/mballoc.c
    +++ b/fs/ext4/mballoc.c
    @@ -3877,7 +3877,8 @@ ext4_mb_discard_group_preallocations(struct super_block *sb,

    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 @@ void ext4_discard_preallocations(struct inode *inode)
    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 super_block *sb,
    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 *sb, ext4_group_t group,

    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;
    --
    2.14.1
    \
     
     \ /
      Last update: 2018-03-19 22:23    [W:4.322 / U:0.028 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site