diff options
author | Theodore Ts'o <tytso@mit.edu> | 2018-03-30 15:42:25 -0400 |
---|---|---|
committer | Theodore Ts'o <tytso@mit.edu> | 2018-03-30 15:42:25 -0400 |
commit | de05ca8526796c7e9f7c7282b7f89a818af19818 (patch) | |
tree | cc98259f026483d15edd01629d71eefd4bb24915 | |
parent | 27f394a7718d00ad16c59c616638cb46c6cd6a9d (diff) |
ext4: move call to ext4_error() into ext4_xattr_check_block()
Refactor the call to EXT4_ERROR_INODE() into ext4_xattr_check_block().
This simplifies the code, and fixes a problem where not all callers of
ext4_xattr_check_block() were not resulting in ext4_error() getting
called when the xattr block is corrupted.
Signed-off-by: Theodore Ts'o <tytso@mit.edu>
Cc: stable@vger.kernel.org
-rw-r--r-- | fs/ext4/xattr.c | 60 |
1 files changed, 27 insertions, 33 deletions
diff --git a/fs/ext4/xattr.c b/fs/ext4/xattr.c index 2077d87b09f2..c030e41818ab 100644 --- a/fs/ext4/xattr.c +++ b/fs/ext4/xattr.c | |||
@@ -225,25 +225,36 @@ ext4_xattr_check_entries(struct ext4_xattr_entry *entry, void *end, | |||
225 | } | 225 | } |
226 | 226 | ||
227 | static inline int | 227 | static inline int |
228 | ext4_xattr_check_block(struct inode *inode, struct buffer_head *bh) | 228 | __ext4_xattr_check_block(struct inode *inode, struct buffer_head *bh, |
229 | const char *function, unsigned int line) | ||
229 | { | 230 | { |
230 | int error; | 231 | int error = -EFSCORRUPTED; |
231 | 232 | ||
232 | if (buffer_verified(bh)) | 233 | if (buffer_verified(bh)) |
233 | return 0; | 234 | return 0; |
234 | 235 | ||
235 | if (BHDR(bh)->h_magic != cpu_to_le32(EXT4_XATTR_MAGIC) || | 236 | if (BHDR(bh)->h_magic != cpu_to_le32(EXT4_XATTR_MAGIC) || |
236 | BHDR(bh)->h_blocks != cpu_to_le32(1)) | 237 | BHDR(bh)->h_blocks != cpu_to_le32(1)) |
237 | return -EFSCORRUPTED; | 238 | goto errout; |
239 | error = -EFSBADCRC; | ||
238 | if (!ext4_xattr_block_csum_verify(inode, bh)) | 240 | if (!ext4_xattr_block_csum_verify(inode, bh)) |
239 | return -EFSBADCRC; | 241 | goto errout; |
240 | error = ext4_xattr_check_entries(BFIRST(bh), bh->b_data + bh->b_size, | 242 | error = ext4_xattr_check_entries(BFIRST(bh), bh->b_data + bh->b_size, |
241 | bh->b_data); | 243 | bh->b_data); |
242 | if (!error) | 244 | errout: |
245 | if (error) | ||
246 | __ext4_error_inode(inode, function, line, 0, | ||
247 | "corrupted xattr block %llu", | ||
248 | (unsigned long long) bh->b_blocknr); | ||
249 | else | ||
243 | set_buffer_verified(bh); | 250 | set_buffer_verified(bh); |
244 | return error; | 251 | return error; |
245 | } | 252 | } |
246 | 253 | ||
254 | #define ext4_xattr_check_block(inode, bh) \ | ||
255 | __ext4_xattr_check_block((inode), (bh), __func__, __LINE__) | ||
256 | |||
257 | |||
247 | static int | 258 | static int |
248 | __xattr_check_inode(struct inode *inode, struct ext4_xattr_ibody_header *header, | 259 | __xattr_check_inode(struct inode *inode, struct ext4_xattr_ibody_header *header, |
249 | void *end, const char *function, unsigned int line) | 260 | void *end, const char *function, unsigned int line) |
@@ -514,12 +525,9 @@ ext4_xattr_block_get(struct inode *inode, int name_index, const char *name, | |||
514 | goto cleanup; | 525 | goto cleanup; |
515 | ea_bdebug(bh, "b_count=%d, refcount=%d", | 526 | ea_bdebug(bh, "b_count=%d, refcount=%d", |
516 | atomic_read(&(bh->b_count)), le32_to_cpu(BHDR(bh)->h_refcount)); | 527 | atomic_read(&(bh->b_count)), le32_to_cpu(BHDR(bh)->h_refcount)); |
517 | if (ext4_xattr_check_block(inode, bh)) { | 528 | error = ext4_xattr_check_block(inode, bh); |
518 | EXT4_ERROR_INODE(inode, "bad block %llu", | 529 | if (error) |
519 | EXT4_I(inode)->i_file_acl); | ||
520 | error = -EFSCORRUPTED; | ||
521 | goto cleanup; | 530 | goto cleanup; |
522 | } | ||
523 | ext4_xattr_block_cache_insert(ea_block_cache, bh); | 531 | ext4_xattr_block_cache_insert(ea_block_cache, bh); |
524 | entry = BFIRST(bh); | 532 | entry = BFIRST(bh); |
525 | error = ext4_xattr_find_entry(&entry, name_index, name, 1); | 533 | error = ext4_xattr_find_entry(&entry, name_index, name, 1); |
@@ -679,12 +687,9 @@ ext4_xattr_block_list(struct dentry *dentry, char *buffer, size_t buffer_size) | |||
679 | goto cleanup; | 687 | goto cleanup; |
680 | ea_bdebug(bh, "b_count=%d, refcount=%d", | 688 | ea_bdebug(bh, "b_count=%d, refcount=%d", |
681 | atomic_read(&(bh->b_count)), le32_to_cpu(BHDR(bh)->h_refcount)); | 689 | atomic_read(&(bh->b_count)), le32_to_cpu(BHDR(bh)->h_refcount)); |
682 | if (ext4_xattr_check_block(inode, bh)) { | 690 | error = ext4_xattr_check_block(inode, bh); |
683 | EXT4_ERROR_INODE(inode, "bad block %llu", | 691 | if (error) |
684 | EXT4_I(inode)->i_file_acl); | ||
685 | error = -EFSCORRUPTED; | ||
686 | goto cleanup; | 692 | goto cleanup; |
687 | } | ||
688 | ext4_xattr_block_cache_insert(EA_BLOCK_CACHE(inode), bh); | 693 | ext4_xattr_block_cache_insert(EA_BLOCK_CACHE(inode), bh); |
689 | error = ext4_xattr_list_entries(dentry, BFIRST(bh), buffer, buffer_size); | 694 | error = ext4_xattr_list_entries(dentry, BFIRST(bh), buffer, buffer_size); |
690 | 695 | ||
@@ -811,10 +816,9 @@ int ext4_get_inode_usage(struct inode *inode, qsize_t *usage) | |||
811 | goto out; | 816 | goto out; |
812 | } | 817 | } |
813 | 818 | ||
814 | if (ext4_xattr_check_block(inode, bh)) { | 819 | ret = ext4_xattr_check_block(inode, bh); |
815 | ret = -EFSCORRUPTED; | 820 | if (ret) |
816 | goto out; | 821 | goto out; |
817 | } | ||
818 | 822 | ||
819 | for (entry = BFIRST(bh); !IS_LAST_ENTRY(entry); | 823 | for (entry = BFIRST(bh); !IS_LAST_ENTRY(entry); |
820 | entry = EXT4_XATTR_NEXT(entry)) | 824 | entry = EXT4_XATTR_NEXT(entry)) |
@@ -1796,12 +1800,9 @@ ext4_xattr_block_find(struct inode *inode, struct ext4_xattr_info *i, | |||
1796 | ea_bdebug(bs->bh, "b_count=%d, refcount=%d", | 1800 | ea_bdebug(bs->bh, "b_count=%d, refcount=%d", |
1797 | atomic_read(&(bs->bh->b_count)), | 1801 | atomic_read(&(bs->bh->b_count)), |
1798 | le32_to_cpu(BHDR(bs->bh)->h_refcount)); | 1802 | le32_to_cpu(BHDR(bs->bh)->h_refcount)); |
1799 | if (ext4_xattr_check_block(inode, bs->bh)) { | 1803 | error = ext4_xattr_check_block(inode, bs->bh); |
1800 | EXT4_ERROR_INODE(inode, "bad block %llu", | 1804 | if (error) |
1801 | EXT4_I(inode)->i_file_acl); | ||
1802 | error = -EFSCORRUPTED; | ||
1803 | goto cleanup; | 1805 | goto cleanup; |
1804 | } | ||
1805 | /* Find the named attribute. */ | 1806 | /* Find the named attribute. */ |
1806 | bs->s.base = BHDR(bs->bh); | 1807 | bs->s.base = BHDR(bs->bh); |
1807 | bs->s.first = BFIRST(bs->bh); | 1808 | bs->s.first = BFIRST(bs->bh); |
@@ -2724,13 +2725,9 @@ retry: | |||
2724 | error = -EIO; | 2725 | error = -EIO; |
2725 | if (!bh) | 2726 | if (!bh) |
2726 | goto cleanup; | 2727 | goto cleanup; |
2727 | if (ext4_xattr_check_block(inode, bh)) { | 2728 | error = ext4_xattr_check_block(inode, bh); |
2728 | EXT4_ERROR_INODE(inode, "bad block %llu", | 2729 | if (error) |
2729 | EXT4_I(inode)->i_file_acl); | ||
2730 | error = -EFSCORRUPTED; | ||
2731 | brelse(bh); | ||
2732 | goto cleanup; | 2730 | goto cleanup; |
2733 | } | ||
2734 | base = BHDR(bh); | 2731 | base = BHDR(bh); |
2735 | end = bh->b_data + bh->b_size; | 2732 | end = bh->b_data + bh->b_size; |
2736 | min_offs = end - base; | 2733 | min_offs = end - base; |
@@ -2887,11 +2884,8 @@ int ext4_xattr_delete_inode(handle_t *handle, struct inode *inode, | |||
2887 | goto cleanup; | 2884 | goto cleanup; |
2888 | } | 2885 | } |
2889 | error = ext4_xattr_check_block(inode, bh); | 2886 | error = ext4_xattr_check_block(inode, bh); |
2890 | if (error) { | 2887 | if (error) |
2891 | EXT4_ERROR_INODE(inode, "bad block %llu (error %d)", | ||
2892 | EXT4_I(inode)->i_file_acl, error); | ||
2893 | goto cleanup; | 2888 | goto cleanup; |
2894 | } | ||
2895 | 2889 | ||
2896 | if (ext4_has_feature_ea_inode(inode->i_sb)) { | 2890 | if (ext4_has_feature_ea_inode(inode->i_sb)) { |
2897 | for (entry = BFIRST(bh); !IS_LAST_ENTRY(entry); | 2891 | for (entry = BFIRST(bh); !IS_LAST_ENTRY(entry); |