提交 9651e6b2 编写于 作者: K Konstantin Khlebnikov 提交者: Theodore Ts'o

ext4: handle the rest of ext4_mb_load_buddy() ENOMEM errors

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: adb7ef60 ("ext4: use __GFP_NOFAIL in ext4_free_blocks()")
Signed-off-by: NKonstantin Khlebnikov <khlebnikov@yandex-team.ru>
Signed-off-by: NTheodore Ts'o <tytso@mit.edu>
上级 3f1d5bad
...@@ -3887,7 +3887,8 @@ ext4_mb_discard_group_preallocations(struct super_block *sb, ...@@ -3887,7 +3887,8 @@ ext4_mb_discard_group_preallocations(struct super_block *sb,
err = ext4_mb_load_buddy(sb, group, &e4b); err = ext4_mb_load_buddy(sb, group, &e4b);
if (err) { 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); put_bh(bitmap_bh);
return 0; return 0;
} }
...@@ -4044,10 +4045,11 @@ void ext4_discard_preallocations(struct inode *inode) ...@@ -4044,10 +4045,11 @@ void ext4_discard_preallocations(struct inode *inode)
BUG_ON(pa->pa_type != MB_INODE_PA); BUG_ON(pa->pa_type != MB_INODE_PA);
group = ext4_get_group_number(sb, pa->pa_pstart); 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) { if (err) {
ext4_error(sb, "Error loading buddy information for %u", ext4_error(sb, "Error %d loading buddy information for %u",
group); err, group);
continue; continue;
} }
...@@ -4303,11 +4305,14 @@ ext4_mb_discard_lg_preallocations(struct super_block *sb, ...@@ -4303,11 +4305,14 @@ ext4_mb_discard_lg_preallocations(struct super_block *sb,
spin_unlock(&lg->lg_prealloc_lock); spin_unlock(&lg->lg_prealloc_lock);
list_for_each_entry_safe(pa, tmp, &discard_list, u.pa_tmp_list) { list_for_each_entry_safe(pa, tmp, &discard_list, u.pa_tmp_list) {
int err;
group = ext4_get_group_number(sb, pa->pa_pstart); group = ext4_get_group_number(sb, pa->pa_pstart);
if (ext4_mb_load_buddy(sb, group, &e4b)) { err = ext4_mb_load_buddy_gfp(sb, group, &e4b,
ext4_error(sb, "Error loading buddy information for %u", GFP_NOFS|__GFP_NOFAIL);
group); if (err) {
ext4_error(sb, "Error %d loading buddy information for %u",
err, group);
continue; continue;
} }
ext4_lock_group(sb, group); ext4_lock_group(sb, group);
...@@ -5127,8 +5132,8 @@ ext4_trim_all_free(struct super_block *sb, ext4_group_t group, ...@@ -5127,8 +5132,8 @@ ext4_trim_all_free(struct super_block *sb, ext4_group_t group,
ret = ext4_mb_load_buddy(sb, group, &e4b); ret = ext4_mb_load_buddy(sb, group, &e4b);
if (ret) { if (ret) {
ext4_error(sb, "Error in loading buddy " ext4_warning(sb, "Error %d loading buddy information for %u",
"information for %u", group); ret, group);
return ret; return ret;
} }
bitmap = e4b.bd_bitmap; bitmap = e4b.bd_bitmap;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册