aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTheodore Ts'o <tytso@mit.edu>2018-03-30 15:42:25 -0400
committerTheodore Ts'o <tytso@mit.edu>2018-03-30 15:42:25 -0400
commitde05ca8526796c7e9f7c7282b7f89a818af19818 (patch)
treecc98259f026483d15edd01629d71eefd4bb24915
parent27f394a7718d00ad16c59c616638cb46c6cd6a9d (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.c60
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
227static inline int 227static inline int
228ext4_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) 244errout:
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
247static int 258static 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);