diff options
author | Darrick J. Wong <darrick.wong@oracle.com> | 2015-10-17 21:33:24 -0400 |
---|---|---|
committer | Theodore Ts'o <tytso@mit.edu> | 2015-10-17 21:33:24 -0400 |
commit | 9008a58e5dcee014f5de69d154e2620870f9224e (patch) | |
tree | 0959450c94f921c0080a5f9ee2f62e3ea9bfcf6e /fs/ext4/mballoc.c | |
parent | 56316a0d28f251dae6a3bc2b6d50e7c25389871f (diff) |
ext4: make the bitmap read routines return real error codes
Make the bitmap reaading routines return real error codes (EIO,
EFSCORRUPTED, EFSBADCRC) which can then be reflected back to
userspace for more precise diagnosis work.
In particular, this means that mballoc no longer claims that we're out
of memory if the block bitmaps become corrupt.
Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
Signed-off-by: Theodore Ts'o <tytso@mit.edu>
Diffstat (limited to 'fs/ext4/mballoc.c')
-rw-r--r-- | fs/ext4/mballoc.c | 46 |
1 files changed, 30 insertions, 16 deletions
diff --git a/fs/ext4/mballoc.c b/fs/ext4/mballoc.c index b0f7ee57630b..6794ff47cfaf 100644 --- a/fs/ext4/mballoc.c +++ b/fs/ext4/mballoc.c | |||
@@ -874,8 +874,10 @@ static int ext4_mb_init_cache(struct page *page, char *incore) | |||
874 | bh[i] = NULL; | 874 | bh[i] = NULL; |
875 | continue; | 875 | continue; |
876 | } | 876 | } |
877 | if (!(bh[i] = ext4_read_block_bitmap_nowait(sb, group))) { | 877 | bh[i] = ext4_read_block_bitmap_nowait(sb, group); |
878 | err = -ENOMEM; | 878 | if (IS_ERR(bh[i])) { |
879 | err = PTR_ERR(bh[i]); | ||
880 | bh[i] = NULL; | ||
879 | goto out; | 881 | goto out; |
880 | } | 882 | } |
881 | mb_debug(1, "read bitmap for group %u\n", group); | 883 | mb_debug(1, "read bitmap for group %u\n", group); |
@@ -883,8 +885,13 @@ static int ext4_mb_init_cache(struct page *page, char *incore) | |||
883 | 885 | ||
884 | /* wait for I/O completion */ | 886 | /* wait for I/O completion */ |
885 | for (i = 0, group = first_group; i < groups_per_page; i++, group++) { | 887 | for (i = 0, group = first_group; i < groups_per_page; i++, group++) { |
886 | if (bh[i] && ext4_wait_block_bitmap(sb, group, bh[i])) | 888 | int err2; |
887 | err = -EIO; | 889 | |
890 | if (!bh[i]) | ||
891 | continue; | ||
892 | err2 = ext4_wait_block_bitmap(sb, group, bh[i]); | ||
893 | if (!err) | ||
894 | err = err2; | ||
888 | } | 895 | } |
889 | 896 | ||
890 | first_block = page->index * blocks_per_page; | 897 | first_block = page->index * blocks_per_page; |
@@ -2447,7 +2454,7 @@ int ext4_mb_add_groupinfo(struct super_block *sb, ext4_group_t group, | |||
2447 | kmalloc(sb->s_blocksize, GFP_NOFS); | 2454 | kmalloc(sb->s_blocksize, GFP_NOFS); |
2448 | BUG_ON(meta_group_info[i]->bb_bitmap == NULL); | 2455 | BUG_ON(meta_group_info[i]->bb_bitmap == NULL); |
2449 | bh = ext4_read_block_bitmap(sb, group); | 2456 | bh = ext4_read_block_bitmap(sb, group); |
2450 | BUG_ON(bh == NULL); | 2457 | BUG_ON(IS_ERR_OR_NULL(bh)); |
2451 | memcpy(meta_group_info[i]->bb_bitmap, bh->b_data, | 2458 | memcpy(meta_group_info[i]->bb_bitmap, bh->b_data, |
2452 | sb->s_blocksize); | 2459 | sb->s_blocksize); |
2453 | put_bh(bh); | 2460 | put_bh(bh); |
@@ -2889,10 +2896,12 @@ ext4_mb_mark_diskspace_used(struct ext4_allocation_context *ac, | |||
2889 | sb = ac->ac_sb; | 2896 | sb = ac->ac_sb; |
2890 | sbi = EXT4_SB(sb); | 2897 | sbi = EXT4_SB(sb); |
2891 | 2898 | ||
2892 | err = -EIO; | ||
2893 | bitmap_bh = ext4_read_block_bitmap(sb, ac->ac_b_ex.fe_group); | 2899 | bitmap_bh = ext4_read_block_bitmap(sb, ac->ac_b_ex.fe_group); |
2894 | if (!bitmap_bh) | 2900 | if (IS_ERR(bitmap_bh)) { |
2901 | err = PTR_ERR(bitmap_bh); | ||
2902 | bitmap_bh = NULL; | ||
2895 | goto out_err; | 2903 | goto out_err; |
2904 | } | ||
2896 | 2905 | ||
2897 | BUFFER_TRACE(bitmap_bh, "getting write access"); | 2906 | BUFFER_TRACE(bitmap_bh, "getting write access"); |
2898 | err = ext4_journal_get_write_access(handle, bitmap_bh); | 2907 | err = ext4_journal_get_write_access(handle, bitmap_bh); |
@@ -3836,8 +3845,10 @@ ext4_mb_discard_group_preallocations(struct super_block *sb, | |||
3836 | return 0; | 3845 | return 0; |
3837 | 3846 | ||
3838 | bitmap_bh = ext4_read_block_bitmap(sb, group); | 3847 | bitmap_bh = ext4_read_block_bitmap(sb, group); |
3839 | if (bitmap_bh == NULL) { | 3848 | if (IS_ERR(bitmap_bh)) { |
3840 | ext4_error(sb, "Error reading block bitmap for %u", group); | 3849 | err = PTR_ERR(bitmap_bh); |
3850 | ext4_error(sb, "Error %d reading block bitmap for %u", | ||
3851 | err, group); | ||
3841 | return 0; | 3852 | return 0; |
3842 | } | 3853 | } |
3843 | 3854 | ||
@@ -4008,9 +4019,10 @@ repeat: | |||
4008 | } | 4019 | } |
4009 | 4020 | ||
4010 | bitmap_bh = ext4_read_block_bitmap(sb, group); | 4021 | bitmap_bh = ext4_read_block_bitmap(sb, group); |
4011 | if (bitmap_bh == NULL) { | 4022 | if (IS_ERR(bitmap_bh)) { |
4012 | ext4_error(sb, "Error reading block bitmap for %u", | 4023 | err = PTR_ERR(bitmap_bh); |
4013 | group); | 4024 | ext4_error(sb, "Error %d reading block bitmap for %u", |
4025 | err, group); | ||
4014 | ext4_mb_unload_buddy(&e4b); | 4026 | ext4_mb_unload_buddy(&e4b); |
4015 | continue; | 4027 | continue; |
4016 | } | 4028 | } |
@@ -4754,8 +4766,9 @@ do_more: | |||
4754 | } | 4766 | } |
4755 | count_clusters = EXT4_NUM_B2C(sbi, count); | 4767 | count_clusters = EXT4_NUM_B2C(sbi, count); |
4756 | bitmap_bh = ext4_read_block_bitmap(sb, block_group); | 4768 | bitmap_bh = ext4_read_block_bitmap(sb, block_group); |
4757 | if (!bitmap_bh) { | 4769 | if (IS_ERR(bitmap_bh)) { |
4758 | err = -EIO; | 4770 | err = PTR_ERR(bitmap_bh); |
4771 | bitmap_bh = NULL; | ||
4759 | goto error_return; | 4772 | goto error_return; |
4760 | } | 4773 | } |
4761 | gdp = ext4_get_group_desc(sb, block_group, &gd_bh); | 4774 | gdp = ext4_get_group_desc(sb, block_group, &gd_bh); |
@@ -4924,8 +4937,9 @@ int ext4_group_add_blocks(handle_t *handle, struct super_block *sb, | |||
4924 | } | 4937 | } |
4925 | 4938 | ||
4926 | bitmap_bh = ext4_read_block_bitmap(sb, block_group); | 4939 | bitmap_bh = ext4_read_block_bitmap(sb, block_group); |
4927 | if (!bitmap_bh) { | 4940 | if (IS_ERR(bitmap_bh)) { |
4928 | err = -EIO; | 4941 | err = PTR_ERR(bitmap_bh); |
4942 | bitmap_bh = NULL; | ||
4929 | goto error_return; | 4943 | goto error_return; |
4930 | } | 4944 | } |
4931 | 4945 | ||