From b4394b4fd622ce99775ba66592a5c36640fea4aa Mon Sep 17 00:00:00 2001 From: Theodore Ts'o Date: Fri, 30 Mar 2018 18:58:36 -0400 Subject: [PATCH] add patch move-call-to-ext4_error-into-ext4_xattr_check_block --- ...-call-to-ext4_error-into-ext4_xattr_check_block | 146 +++++++++++++++++++++ series | 1 + timestamps | 9 +- 3 files changed, 152 insertions(+), 4 deletions(-) create mode 100644 move-call-to-ext4_error-into-ext4_xattr_check_block diff --git a/move-call-to-ext4_error-into-ext4_xattr_check_block b/move-call-to-ext4_error-into-ext4_xattr_check_block new file mode 100644 index 00000000..f93c3ceb --- /dev/null +++ b/move-call-to-ext4_error-into-ext4_xattr_check_block @@ -0,0 +1,146 @@ +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 +Cc: stable@vger.kernel.org +--- + fs/ext4/xattr.c | 60 +++++++++++++++++++++++++++--------------------------------- + 1 file changed, 27 insertions(+), 33 deletions(-) + +diff --git a/fs/ext4/xattr.c b/fs/ext4/xattr.c +index d2a9b078e121..b0a9ba8e576a 100644 +--- a/fs/ext4/xattr.c ++++ b/fs/ext4/xattr.c +@@ -226,25 +226,36 @@ ext4_xattr_check_entries(struct ext4_xattr_entry *entry, void *end, + } + + static inline int +-ext4_xattr_check_block(struct inode *inode, struct buffer_head *bh) ++__ext4_xattr_check_block(struct inode *inode, struct buffer_head *bh, ++ const char *function, unsigned int line) + { +- int error; ++ int error = -EFSCORRUPTED; + + if (buffer_verified(bh)) + return 0; + + if (BHDR(bh)->h_magic != cpu_to_le32(EXT4_XATTR_MAGIC) || + BHDR(bh)->h_blocks != cpu_to_le32(1)) +- return -EFSCORRUPTED; ++ goto errout; ++ error = -EFSBADCRC; + if (!ext4_xattr_block_csum_verify(inode, bh)) +- return -EFSBADCRC; ++ goto errout; + error = ext4_xattr_check_entries(BFIRST(bh), bh->b_data + bh->b_size, + bh->b_data); +- if (!error) ++errout: ++ if (error) ++ __ext4_error_inode(inode, function, line, 0, ++ "corrupted xattr block %llu", ++ (unsigned long long) bh->b_blocknr); ++ else + set_buffer_verified(bh); + return error; + } + ++#define ext4_xattr_check_block(inode, bh) \ ++ __ext4_xattr_check_block((inode), (bh), __func__, __LINE__) ++ ++ + static int + __xattr_check_inode(struct inode *inode, struct ext4_xattr_ibody_header *header, + void *end, const char *function, unsigned int line) +@@ -515,12 +526,9 @@ ext4_xattr_block_get(struct inode *inode, int name_index, const char *name, + goto cleanup; + ea_bdebug(bh, "b_count=%d, refcount=%d", + atomic_read(&(bh->b_count)), le32_to_cpu(BHDR(bh)->h_refcount)); +- if (ext4_xattr_check_block(inode, bh)) { +- EXT4_ERROR_INODE(inode, "bad block %llu", +- EXT4_I(inode)->i_file_acl); +- error = -EFSCORRUPTED; ++ error = ext4_xattr_check_block(inode, bh); ++ if (error) + goto cleanup; +- } + ext4_xattr_block_cache_insert(ea_block_cache, bh); + entry = BFIRST(bh); + error = ext4_xattr_find_entry(&entry, name_index, name, 1); +@@ -684,12 +692,9 @@ ext4_xattr_block_list(struct dentry *dentry, char *buffer, size_t buffer_size) + goto cleanup; + ea_bdebug(bh, "b_count=%d, refcount=%d", + atomic_read(&(bh->b_count)), le32_to_cpu(BHDR(bh)->h_refcount)); +- if (ext4_xattr_check_block(inode, bh)) { +- EXT4_ERROR_INODE(inode, "bad block %llu", +- EXT4_I(inode)->i_file_acl); +- error = -EFSCORRUPTED; ++ error = ext4_xattr_check_block(inode, bh); ++ if (error) + goto cleanup; +- } + ext4_xattr_block_cache_insert(EA_BLOCK_CACHE(inode), bh); + error = ext4_xattr_list_entries(dentry, BFIRST(bh), buffer, buffer_size); + +@@ -816,10 +821,9 @@ int ext4_get_inode_usage(struct inode *inode, qsize_t *usage) + goto out; + } + +- if (ext4_xattr_check_block(inode, bh)) { +- ret = -EFSCORRUPTED; ++ ret = ext4_xattr_check_block(inode, bh); ++ if (ret) + goto out; +- } + + for (entry = BFIRST(bh); !IS_LAST_ENTRY(entry); + entry = EXT4_XATTR_NEXT(entry)) +@@ -1801,12 +1805,9 @@ ext4_xattr_block_find(struct inode *inode, struct ext4_xattr_info *i, + ea_bdebug(bs->bh, "b_count=%d, refcount=%d", + atomic_read(&(bs->bh->b_count)), + le32_to_cpu(BHDR(bs->bh)->h_refcount)); +- if (ext4_xattr_check_block(inode, bs->bh)) { +- EXT4_ERROR_INODE(inode, "bad block %llu", +- EXT4_I(inode)->i_file_acl); +- error = -EFSCORRUPTED; ++ error = ext4_xattr_check_block(inode, bs->bh); ++ if (error) + goto cleanup; +- } + /* Find the named attribute. */ + bs->s.base = BHDR(bs->bh); + bs->s.first = BFIRST(bs->bh); +@@ -2729,13 +2730,9 @@ int ext4_expand_extra_isize_ea(struct inode *inode, int new_extra_isize, + error = -EIO; + if (!bh) + goto cleanup; +- if (ext4_xattr_check_block(inode, bh)) { +- EXT4_ERROR_INODE(inode, "bad block %llu", +- EXT4_I(inode)->i_file_acl); +- error = -EFSCORRUPTED; +- brelse(bh); ++ error = ext4_xattr_check_block(inode, bh); ++ if (error) + goto cleanup; +- } + base = BHDR(bh); + end = bh->b_data + bh->b_size; + min_offs = end - base; +@@ -2892,11 +2889,8 @@ int ext4_xattr_delete_inode(handle_t *handle, struct inode *inode, + goto cleanup; + } + error = ext4_xattr_check_block(inode, bh); +- if (error) { +- EXT4_ERROR_INODE(inode, "bad block %llu (error %d)", +- EXT4_I(inode)->i_file_acl, error); ++ if (error) + goto cleanup; +- } + + if (ext4_has_feature_ea_inode(inode->i_sb)) { + for (entry = BFIRST(bh); !IS_LAST_ENTRY(entry); diff --git a/series b/series index 14842934..77ed565d 100644 --- a/series +++ b/series @@ -29,6 +29,7 @@ simplify-object-usage show-more-binary-mount-options omit-init_itable-in-procfs-when-disabled dont-show-jbd-data-option-if-defaulted +move-call-to-ext4_error-into-ext4_xattr_check_block #################################################### # unstable patches diff --git a/timestamps b/timestamps index 9244d9c0..875bc472 100755 --- a/timestamps +++ b/timestamps @@ -52,13 +52,14 @@ touch -d @1522348302 add-better-range-checking-for-xattr-value-sizes touch -d @1522374969 fail-unalloc-root-dir-in-ext4_iget touch -d @1522375831 always-load-checksum-driver touch -d @1522375835 dont-allow-rw-mounts-of-metadata-blocks-over-lap-sb -touch -d @1522375895 stable-boundary touch -d @1522382618 null-out-kobject-during-sysfs-cleanup touch -d @1522383190 remove-unsued-parameters-in-sysfs-code touch -d @1522384894 simplify-object-usage touch -d @1522385470 show-more-binary-mount-options touch -d @1522385613 omit-init_itable-in-procfs-when-disabled touch -d @1522385770 dont-show-jbd-data-option-if-defaulted -touch -d @1522385873 series -touch -d @1522385951 status -touch -d @1522386087 timestamps +touch -d @1522385830 stable-boundary +touch -d @1522438806 series +touch -d @1522438945 move-call-to-ext4_error-into-ext4_xattr_check_block +touch -d @1522438945 status +touch -d @1522447446 timestamps -- 2.11.4.GIT