diff options
author | Theodore Ts'o <tytso@mit.edu> | 2013-01-12 16:19:36 -0500 |
---|---|---|
committer | Theodore Ts'o <tytso@mit.edu> | 2013-01-12 16:19:36 -0500 |
commit | 860d21e2c585f7ee8a4ecc06f474fdc33c9474f4 (patch) | |
tree | f4b8f664599f043b7aa7b86a9a135aa275f0a5e2 /fs/ext4 | |
parent | 9931faca02c604c22335f5a935a501bb2ace6e20 (diff) |
ext4: return ENOMEM if sb_getblk() fails
The only reason for sb_getblk() failing is if it can't allocate the
buffer_head. So ENOMEM is more appropriate than EIO. In addition,
make sure that the file system is marked as being inconsistent if
sb_getblk() fails.
Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
Cc: stable@vger.kernel.org
Diffstat (limited to 'fs/ext4')
-rw-r--r-- | fs/ext4/extents.c | 25 | ||||
-rw-r--r-- | fs/ext4/indirect.c | 9 | ||||
-rw-r--r-- | fs/ext4/inline.c | 2 | ||||
-rw-r--r-- | fs/ext4/inode.c | 9 | ||||
-rw-r--r-- | fs/ext4/mmp.c | 2 | ||||
-rw-r--r-- | fs/ext4/resize.c | 8 | ||||
-rw-r--r-- | fs/ext4/xattr.c | 3 |
7 files changed, 32 insertions, 26 deletions
diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c index 5ae1674ec12f..d42a8c49ad69 100644 --- a/fs/ext4/extents.c +++ b/fs/ext4/extents.c | |||
@@ -725,6 +725,7 @@ ext4_ext_find_extent(struct inode *inode, ext4_lblk_t block, | |||
725 | struct ext4_extent_header *eh; | 725 | struct ext4_extent_header *eh; |
726 | struct buffer_head *bh; | 726 | struct buffer_head *bh; |
727 | short int depth, i, ppos = 0, alloc = 0; | 727 | short int depth, i, ppos = 0, alloc = 0; |
728 | int ret; | ||
728 | 729 | ||
729 | eh = ext_inode_hdr(inode); | 730 | eh = ext_inode_hdr(inode); |
730 | depth = ext_depth(inode); | 731 | depth = ext_depth(inode); |
@@ -752,12 +753,15 @@ ext4_ext_find_extent(struct inode *inode, ext4_lblk_t block, | |||
752 | path[ppos].p_ext = NULL; | 753 | path[ppos].p_ext = NULL; |
753 | 754 | ||
754 | bh = sb_getblk(inode->i_sb, path[ppos].p_block); | 755 | bh = sb_getblk(inode->i_sb, path[ppos].p_block); |
755 | if (unlikely(!bh)) | 756 | if (unlikely(!bh)) { |
757 | ret = -ENOMEM; | ||
756 | goto err; | 758 | goto err; |
759 | } | ||
757 | if (!bh_uptodate_or_lock(bh)) { | 760 | if (!bh_uptodate_or_lock(bh)) { |
758 | trace_ext4_ext_load_extent(inode, block, | 761 | trace_ext4_ext_load_extent(inode, block, |
759 | path[ppos].p_block); | 762 | path[ppos].p_block); |
760 | if (bh_submit_read(bh) < 0) { | 763 | ret = bh_submit_read(bh); |
764 | if (ret < 0) { | ||
761 | put_bh(bh); | 765 | put_bh(bh); |
762 | goto err; | 766 | goto err; |
763 | } | 767 | } |
@@ -768,13 +772,15 @@ ext4_ext_find_extent(struct inode *inode, ext4_lblk_t block, | |||
768 | put_bh(bh); | 772 | put_bh(bh); |
769 | EXT4_ERROR_INODE(inode, | 773 | EXT4_ERROR_INODE(inode, |
770 | "ppos %d > depth %d", ppos, depth); | 774 | "ppos %d > depth %d", ppos, depth); |
775 | ret = -EIO; | ||
771 | goto err; | 776 | goto err; |
772 | } | 777 | } |
773 | path[ppos].p_bh = bh; | 778 | path[ppos].p_bh = bh; |
774 | path[ppos].p_hdr = eh; | 779 | path[ppos].p_hdr = eh; |
775 | i--; | 780 | i--; |
776 | 781 | ||
777 | if (ext4_ext_check_block(inode, eh, i, bh)) | 782 | ret = ext4_ext_check_block(inode, eh, i, bh); |
783 | if (ret < 0) | ||
778 | goto err; | 784 | goto err; |
779 | } | 785 | } |
780 | 786 | ||
@@ -796,7 +802,7 @@ err: | |||
796 | ext4_ext_drop_refs(path); | 802 | ext4_ext_drop_refs(path); |
797 | if (alloc) | 803 | if (alloc) |
798 | kfree(path); | 804 | kfree(path); |
799 | return ERR_PTR(-EIO); | 805 | return ERR_PTR(ret); |
800 | } | 806 | } |
801 | 807 | ||
802 | /* | 808 | /* |
@@ -951,7 +957,7 @@ static int ext4_ext_split(handle_t *handle, struct inode *inode, | |||
951 | } | 957 | } |
952 | bh = sb_getblk(inode->i_sb, newblock); | 958 | bh = sb_getblk(inode->i_sb, newblock); |
953 | if (!bh) { | 959 | if (!bh) { |
954 | err = -EIO; | 960 | err = -ENOMEM; |
955 | goto cleanup; | 961 | goto cleanup; |
956 | } | 962 | } |
957 | lock_buffer(bh); | 963 | lock_buffer(bh); |
@@ -1024,7 +1030,7 @@ static int ext4_ext_split(handle_t *handle, struct inode *inode, | |||
1024 | newblock = ablocks[--a]; | 1030 | newblock = ablocks[--a]; |
1025 | bh = sb_getblk(inode->i_sb, newblock); | 1031 | bh = sb_getblk(inode->i_sb, newblock); |
1026 | if (!bh) { | 1032 | if (!bh) { |
1027 | err = -EIO; | 1033 | err = -ENOMEM; |
1028 | goto cleanup; | 1034 | goto cleanup; |
1029 | } | 1035 | } |
1030 | lock_buffer(bh); | 1036 | lock_buffer(bh); |
@@ -1136,11 +1142,8 @@ static int ext4_ext_grow_indepth(handle_t *handle, struct inode *inode, | |||
1136 | return err; | 1142 | return err; |
1137 | 1143 | ||
1138 | bh = sb_getblk(inode->i_sb, newblock); | 1144 | bh = sb_getblk(inode->i_sb, newblock); |
1139 | if (!bh) { | 1145 | if (!bh) |
1140 | err = -EIO; | 1146 | return -ENOMEM; |
1141 | ext4_std_error(inode->i_sb, err); | ||
1142 | return err; | ||
1143 | } | ||
1144 | lock_buffer(bh); | 1147 | lock_buffer(bh); |
1145 | 1148 | ||
1146 | err = ext4_journal_get_create_access(handle, bh); | 1149 | err = ext4_journal_get_create_access(handle, bh); |
diff --git a/fs/ext4/indirect.c b/fs/ext4/indirect.c index 20862f96e8ae..8d83d1e508e4 100644 --- a/fs/ext4/indirect.c +++ b/fs/ext4/indirect.c | |||
@@ -146,6 +146,7 @@ static Indirect *ext4_get_branch(struct inode *inode, int depth, | |||
146 | struct super_block *sb = inode->i_sb; | 146 | struct super_block *sb = inode->i_sb; |
147 | Indirect *p = chain; | 147 | Indirect *p = chain; |
148 | struct buffer_head *bh; | 148 | struct buffer_head *bh; |
149 | int ret = -EIO; | ||
149 | 150 | ||
150 | *err = 0; | 151 | *err = 0; |
151 | /* i_data is not going away, no lock needed */ | 152 | /* i_data is not going away, no lock needed */ |
@@ -154,8 +155,10 @@ static Indirect *ext4_get_branch(struct inode *inode, int depth, | |||
154 | goto no_block; | 155 | goto no_block; |
155 | while (--depth) { | 156 | while (--depth) { |
156 | bh = sb_getblk(sb, le32_to_cpu(p->key)); | 157 | bh = sb_getblk(sb, le32_to_cpu(p->key)); |
157 | if (unlikely(!bh)) | 158 | if (unlikely(!bh)) { |
159 | ret = -ENOMEM; | ||
158 | goto failure; | 160 | goto failure; |
161 | } | ||
159 | 162 | ||
160 | if (!bh_uptodate_or_lock(bh)) { | 163 | if (!bh_uptodate_or_lock(bh)) { |
161 | if (bh_submit_read(bh) < 0) { | 164 | if (bh_submit_read(bh) < 0) { |
@@ -177,7 +180,7 @@ static Indirect *ext4_get_branch(struct inode *inode, int depth, | |||
177 | return NULL; | 180 | return NULL; |
178 | 181 | ||
179 | failure: | 182 | failure: |
180 | *err = -EIO; | 183 | *err = ret; |
181 | no_block: | 184 | no_block: |
182 | return p; | 185 | return p; |
183 | } | 186 | } |
@@ -471,7 +474,7 @@ static int ext4_alloc_branch(handle_t *handle, struct inode *inode, | |||
471 | */ | 474 | */ |
472 | bh = sb_getblk(inode->i_sb, new_blocks[n-1]); | 475 | bh = sb_getblk(inode->i_sb, new_blocks[n-1]); |
473 | if (unlikely(!bh)) { | 476 | if (unlikely(!bh)) { |
474 | err = -EIO; | 477 | err = -ENOMEM; |
475 | goto failed; | 478 | goto failed; |
476 | } | 479 | } |
477 | 480 | ||
diff --git a/fs/ext4/inline.c b/fs/ext4/inline.c index 387c47c6cda9..93a3408fc89b 100644 --- a/fs/ext4/inline.c +++ b/fs/ext4/inline.c | |||
@@ -1188,7 +1188,7 @@ static int ext4_convert_inline_data_nolock(handle_t *handle, | |||
1188 | 1188 | ||
1189 | data_bh = sb_getblk(inode->i_sb, map.m_pblk); | 1189 | data_bh = sb_getblk(inode->i_sb, map.m_pblk); |
1190 | if (!data_bh) { | 1190 | if (!data_bh) { |
1191 | error = -EIO; | 1191 | error = -ENOMEM; |
1192 | goto out_restore; | 1192 | goto out_restore; |
1193 | } | 1193 | } |
1194 | 1194 | ||
diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c index cbfe13bf5b2a..9ccc140b82d2 100644 --- a/fs/ext4/inode.c +++ b/fs/ext4/inode.c | |||
@@ -714,7 +714,7 @@ struct buffer_head *ext4_getblk(handle_t *handle, struct inode *inode, | |||
714 | 714 | ||
715 | bh = sb_getblk(inode->i_sb, map.m_pblk); | 715 | bh = sb_getblk(inode->i_sb, map.m_pblk); |
716 | if (!bh) { | 716 | if (!bh) { |
717 | *errp = -EIO; | 717 | *errp = -ENOMEM; |
718 | return NULL; | 718 | return NULL; |
719 | } | 719 | } |
720 | if (map.m_flags & EXT4_MAP_NEW) { | 720 | if (map.m_flags & EXT4_MAP_NEW) { |
@@ -3660,11 +3660,8 @@ static int __ext4_get_inode_loc(struct inode *inode, | |||
3660 | iloc->offset = (inode_offset % inodes_per_block) * EXT4_INODE_SIZE(sb); | 3660 | iloc->offset = (inode_offset % inodes_per_block) * EXT4_INODE_SIZE(sb); |
3661 | 3661 | ||
3662 | bh = sb_getblk(sb, block); | 3662 | bh = sb_getblk(sb, block); |
3663 | if (!bh) { | 3663 | if (!bh) |
3664 | EXT4_ERROR_INODE_BLOCK(inode, block, | 3664 | return -ENOMEM; |
3665 | "unable to read itable block"); | ||
3666 | return -EIO; | ||
3667 | } | ||
3668 | if (!buffer_uptodate(bh)) { | 3665 | if (!buffer_uptodate(bh)) { |
3669 | lock_buffer(bh); | 3666 | lock_buffer(bh); |
3670 | 3667 | ||
diff --git a/fs/ext4/mmp.c b/fs/ext4/mmp.c index fe7c63f4717e..44734f1ca554 100644 --- a/fs/ext4/mmp.c +++ b/fs/ext4/mmp.c | |||
@@ -80,6 +80,8 @@ static int read_mmp_block(struct super_block *sb, struct buffer_head **bh, | |||
80 | * is not blocked in the elevator. */ | 80 | * is not blocked in the elevator. */ |
81 | if (!*bh) | 81 | if (!*bh) |
82 | *bh = sb_getblk(sb, mmp_block); | 82 | *bh = sb_getblk(sb, mmp_block); |
83 | if (!*bh) | ||
84 | return -ENOMEM; | ||
83 | if (*bh) { | 85 | if (*bh) { |
84 | get_bh(*bh); | 86 | get_bh(*bh); |
85 | lock_buffer(*bh); | 87 | lock_buffer(*bh); |
diff --git a/fs/ext4/resize.c b/fs/ext4/resize.c index d99387b89edd..02824dc2ff3b 100644 --- a/fs/ext4/resize.c +++ b/fs/ext4/resize.c | |||
@@ -334,7 +334,7 @@ static struct buffer_head *bclean(handle_t *handle, struct super_block *sb, | |||
334 | 334 | ||
335 | bh = sb_getblk(sb, blk); | 335 | bh = sb_getblk(sb, blk); |
336 | if (!bh) | 336 | if (!bh) |
337 | return ERR_PTR(-EIO); | 337 | return ERR_PTR(-ENOMEM); |
338 | if ((err = ext4_journal_get_write_access(handle, bh))) { | 338 | if ((err = ext4_journal_get_write_access(handle, bh))) { |
339 | brelse(bh); | 339 | brelse(bh); |
340 | bh = ERR_PTR(err); | 340 | bh = ERR_PTR(err); |
@@ -411,7 +411,7 @@ static int set_flexbg_block_bitmap(struct super_block *sb, handle_t *handle, | |||
411 | 411 | ||
412 | bh = sb_getblk(sb, flex_gd->groups[group].block_bitmap); | 412 | bh = sb_getblk(sb, flex_gd->groups[group].block_bitmap); |
413 | if (!bh) | 413 | if (!bh) |
414 | return -EIO; | 414 | return -ENOMEM; |
415 | 415 | ||
416 | err = ext4_journal_get_write_access(handle, bh); | 416 | err = ext4_journal_get_write_access(handle, bh); |
417 | if (err) | 417 | if (err) |
@@ -501,7 +501,7 @@ static int setup_new_flex_group_blocks(struct super_block *sb, | |||
501 | 501 | ||
502 | gdb = sb_getblk(sb, block); | 502 | gdb = sb_getblk(sb, block); |
503 | if (!gdb) { | 503 | if (!gdb) { |
504 | err = -EIO; | 504 | err = -ENOMEM; |
505 | goto out; | 505 | goto out; |
506 | } | 506 | } |
507 | 507 | ||
@@ -1065,7 +1065,7 @@ static void update_backups(struct super_block *sb, int blk_off, char *data, | |||
1065 | 1065 | ||
1066 | bh = sb_getblk(sb, backup_block); | 1066 | bh = sb_getblk(sb, backup_block); |
1067 | if (!bh) { | 1067 | if (!bh) { |
1068 | err = -EIO; | 1068 | err = -ENOMEM; |
1069 | break; | 1069 | break; |
1070 | } | 1070 | } |
1071 | ext4_debug("update metadata backup %llu(+%llu)\n", | 1071 | ext4_debug("update metadata backup %llu(+%llu)\n", |
diff --git a/fs/ext4/xattr.c b/fs/ext4/xattr.c index 3a91ebc2b66f..07d684a4e523 100644 --- a/fs/ext4/xattr.c +++ b/fs/ext4/xattr.c | |||
@@ -887,16 +887,17 @@ inserted: | |||
887 | 887 | ||
888 | new_bh = sb_getblk(sb, block); | 888 | new_bh = sb_getblk(sb, block); |
889 | if (!new_bh) { | 889 | if (!new_bh) { |
890 | error = -ENOMEM; | ||
890 | getblk_failed: | 891 | getblk_failed: |
891 | ext4_free_blocks(handle, inode, NULL, block, 1, | 892 | ext4_free_blocks(handle, inode, NULL, block, 1, |
892 | EXT4_FREE_BLOCKS_METADATA); | 893 | EXT4_FREE_BLOCKS_METADATA); |
893 | error = -EIO; | ||
894 | goto cleanup; | 894 | goto cleanup; |
895 | } | 895 | } |
896 | lock_buffer(new_bh); | 896 | lock_buffer(new_bh); |
897 | error = ext4_journal_get_create_access(handle, new_bh); | 897 | error = ext4_journal_get_create_access(handle, new_bh); |
898 | if (error) { | 898 | if (error) { |
899 | unlock_buffer(new_bh); | 899 | unlock_buffer(new_bh); |
900 | error = -EIO; | ||
900 | goto getblk_failed; | 901 | goto getblk_failed; |
901 | } | 902 | } |
902 | memcpy(new_bh->b_data, s->base, new_bh->b_size); | 903 | memcpy(new_bh->b_data, s->base, new_bh->b_size); |