]>
Commit | Line | Data |
---|---|---|
0f23eb5b GKH |
1 | From de05ca8526796c7e9f7c7282b7f89a818af19818 Mon Sep 17 00:00:00 2001 |
2 | From: Theodore Ts'o <tytso@mit.edu> | |
3 | Date: Fri, 30 Mar 2018 15:42:25 -0400 | |
4 | Subject: ext4: move call to ext4_error() into ext4_xattr_check_block() | |
5 | ||
6 | From: Theodore Ts'o <tytso@mit.edu> | |
7 | ||
8 | commit de05ca8526796c7e9f7c7282b7f89a818af19818 upstream. | |
9 | ||
10 | Refactor the call to EXT4_ERROR_INODE() into ext4_xattr_check_block(). | |
11 | This simplifies the code, and fixes a problem where not all callers of | |
12 | ext4_xattr_check_block() were not resulting in ext4_error() getting | |
13 | called when the xattr block is corrupted. | |
14 | ||
15 | Signed-off-by: Theodore Ts'o <tytso@mit.edu> | |
16 | Cc: stable@vger.kernel.org | |
17 | Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> | |
18 | ||
19 | --- | |
20 | fs/ext4/xattr.c | 60 +++++++++++++++++++++++++------------------------------- | |
21 | 1 file changed, 27 insertions(+), 33 deletions(-) | |
22 | ||
23 | --- a/fs/ext4/xattr.c | |
24 | +++ b/fs/ext4/xattr.c | |
25 | @@ -225,25 +225,36 @@ ext4_xattr_check_entries(struct ext4_xat | |
26 | } | |
27 | ||
28 | static inline int | |
29 | -ext4_xattr_check_block(struct inode *inode, struct buffer_head *bh) | |
30 | +__ext4_xattr_check_block(struct inode *inode, struct buffer_head *bh, | |
31 | + const char *function, unsigned int line) | |
32 | { | |
33 | - int error; | |
34 | + int error = -EFSCORRUPTED; | |
35 | ||
36 | if (buffer_verified(bh)) | |
37 | return 0; | |
38 | ||
39 | if (BHDR(bh)->h_magic != cpu_to_le32(EXT4_XATTR_MAGIC) || | |
40 | BHDR(bh)->h_blocks != cpu_to_le32(1)) | |
41 | - return -EFSCORRUPTED; | |
42 | + goto errout; | |
43 | + error = -EFSBADCRC; | |
44 | if (!ext4_xattr_block_csum_verify(inode, bh)) | |
45 | - return -EFSBADCRC; | |
46 | + goto errout; | |
47 | error = ext4_xattr_check_entries(BFIRST(bh), bh->b_data + bh->b_size, | |
48 | bh->b_data); | |
49 | - if (!error) | |
50 | +errout: | |
51 | + if (error) | |
52 | + __ext4_error_inode(inode, function, line, 0, | |
53 | + "corrupted xattr block %llu", | |
54 | + (unsigned long long) bh->b_blocknr); | |
55 | + else | |
56 | set_buffer_verified(bh); | |
57 | return error; | |
58 | } | |
59 | ||
60 | +#define ext4_xattr_check_block(inode, bh) \ | |
61 | + __ext4_xattr_check_block((inode), (bh), __func__, __LINE__) | |
62 | + | |
63 | + | |
64 | static int | |
65 | __xattr_check_inode(struct inode *inode, struct ext4_xattr_ibody_header *header, | |
66 | void *end, const char *function, unsigned int line) | |
67 | @@ -514,12 +525,9 @@ ext4_xattr_block_get(struct inode *inode | |
68 | goto cleanup; | |
69 | ea_bdebug(bh, "b_count=%d, refcount=%d", | |
70 | atomic_read(&(bh->b_count)), le32_to_cpu(BHDR(bh)->h_refcount)); | |
71 | - if (ext4_xattr_check_block(inode, bh)) { | |
72 | - EXT4_ERROR_INODE(inode, "bad block %llu", | |
73 | - EXT4_I(inode)->i_file_acl); | |
74 | - error = -EFSCORRUPTED; | |
75 | + error = ext4_xattr_check_block(inode, bh); | |
76 | + if (error) | |
77 | goto cleanup; | |
78 | - } | |
79 | ext4_xattr_block_cache_insert(ea_block_cache, bh); | |
80 | entry = BFIRST(bh); | |
81 | error = ext4_xattr_find_entry(&entry, name_index, name, 1); | |
82 | @@ -679,12 +687,9 @@ ext4_xattr_block_list(struct dentry *den | |
83 | goto cleanup; | |
84 | ea_bdebug(bh, "b_count=%d, refcount=%d", | |
85 | atomic_read(&(bh->b_count)), le32_to_cpu(BHDR(bh)->h_refcount)); | |
86 | - if (ext4_xattr_check_block(inode, bh)) { | |
87 | - EXT4_ERROR_INODE(inode, "bad block %llu", | |
88 | - EXT4_I(inode)->i_file_acl); | |
89 | - error = -EFSCORRUPTED; | |
90 | + error = ext4_xattr_check_block(inode, bh); | |
91 | + if (error) | |
92 | goto cleanup; | |
93 | - } | |
94 | ext4_xattr_block_cache_insert(EA_BLOCK_CACHE(inode), bh); | |
95 | error = ext4_xattr_list_entries(dentry, BFIRST(bh), buffer, buffer_size); | |
96 | ||
97 | @@ -811,10 +816,9 @@ int ext4_get_inode_usage(struct inode *i | |
98 | goto out; | |
99 | } | |
100 | ||
101 | - if (ext4_xattr_check_block(inode, bh)) { | |
102 | - ret = -EFSCORRUPTED; | |
103 | + ret = ext4_xattr_check_block(inode, bh); | |
104 | + if (ret) | |
105 | goto out; | |
106 | - } | |
107 | ||
108 | for (entry = BFIRST(bh); !IS_LAST_ENTRY(entry); | |
109 | entry = EXT4_XATTR_NEXT(entry)) | |
110 | @@ -1796,12 +1800,9 @@ ext4_xattr_block_find(struct inode *inod | |
111 | ea_bdebug(bs->bh, "b_count=%d, refcount=%d", | |
112 | atomic_read(&(bs->bh->b_count)), | |
113 | le32_to_cpu(BHDR(bs->bh)->h_refcount)); | |
114 | - if (ext4_xattr_check_block(inode, bs->bh)) { | |
115 | - EXT4_ERROR_INODE(inode, "bad block %llu", | |
116 | - EXT4_I(inode)->i_file_acl); | |
117 | - error = -EFSCORRUPTED; | |
118 | + error = ext4_xattr_check_block(inode, bs->bh); | |
119 | + if (error) | |
120 | goto cleanup; | |
121 | - } | |
122 | /* Find the named attribute. */ | |
123 | bs->s.base = BHDR(bs->bh); | |
124 | bs->s.first = BFIRST(bs->bh); | |
125 | @@ -2724,13 +2725,9 @@ retry: | |
126 | error = -EIO; | |
127 | if (!bh) | |
128 | goto cleanup; | |
129 | - if (ext4_xattr_check_block(inode, bh)) { | |
130 | - EXT4_ERROR_INODE(inode, "bad block %llu", | |
131 | - EXT4_I(inode)->i_file_acl); | |
132 | - error = -EFSCORRUPTED; | |
133 | - brelse(bh); | |
134 | + error = ext4_xattr_check_block(inode, bh); | |
135 | + if (error) | |
136 | goto cleanup; | |
137 | - } | |
138 | base = BHDR(bh); | |
139 | end = bh->b_data + bh->b_size; | |
140 | min_offs = end - base; | |
141 | @@ -2887,11 +2884,8 @@ int ext4_xattr_delete_inode(handle_t *ha | |
142 | goto cleanup; | |
143 | } | |
144 | error = ext4_xattr_check_block(inode, bh); | |
145 | - if (error) { | |
146 | - EXT4_ERROR_INODE(inode, "bad block %llu (error %d)", | |
147 | - EXT4_I(inode)->i_file_acl, error); | |
148 | + if (error) | |
149 | goto cleanup; | |
150 | - } | |
151 | ||
152 | if (ext4_has_feature_ea_inode(inode->i_sb)) { | |
153 | for (entry = BFIRST(bh); !IS_LAST_ENTRY(entry); |