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/extents.c | |
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/extents.c')
-rw-r--r-- | fs/ext4/extents.c | 25 |
1 files changed, 14 insertions, 11 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); |