aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ocfs2/suballoc.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/ocfs2/suballoc.c')
-rw-r--r--fs/ocfs2/suballoc.c91
1 files changed, 64 insertions, 27 deletions
diff --git a/fs/ocfs2/suballoc.c b/fs/ocfs2/suballoc.c
index 766a00b26441..226fe21f2608 100644
--- a/fs/ocfs2/suballoc.c
+++ b/fs/ocfs2/suballoc.c
@@ -145,14 +145,6 @@ static u32 ocfs2_bits_per_group(struct ocfs2_chain_list *cl)
145 return (u32)le16_to_cpu(cl->cl_cpg) * (u32)le16_to_cpu(cl->cl_bpc); 145 return (u32)le16_to_cpu(cl->cl_cpg) * (u32)le16_to_cpu(cl->cl_bpc);
146} 146}
147 147
148int ocfs2_validate_group_descriptor(struct super_block *sb,
149 struct ocfs2_dinode *di,
150 struct buffer_head *bh,
151 int clean_error)
152{
153 unsigned int max_bits;
154 struct ocfs2_group_desc *gd = (struct ocfs2_group_desc *)bh->b_data;
155
156#define do_error(fmt, ...) \ 148#define do_error(fmt, ...) \
157 do{ \ 149 do{ \
158 if (clean_error) \ 150 if (clean_error) \
@@ -161,6 +153,12 @@ int ocfs2_validate_group_descriptor(struct super_block *sb,
161 ocfs2_error(sb, fmt, ##__VA_ARGS__); \ 153 ocfs2_error(sb, fmt, ##__VA_ARGS__); \
162 } while (0) 154 } while (0)
163 155
156static int ocfs2_validate_gd_self(struct super_block *sb,
157 struct buffer_head *bh,
158 int clean_error)
159{
160 struct ocfs2_group_desc *gd = (struct ocfs2_group_desc *)bh->b_data;
161
164 if (!OCFS2_IS_VALID_GROUP_DESC(gd)) { 162 if (!OCFS2_IS_VALID_GROUP_DESC(gd)) {
165 do_error("Group descriptor #%llu has bad signature %.*s", 163 do_error("Group descriptor #%llu has bad signature %.*s",
166 (unsigned long long)bh->b_blocknr, 7, 164 (unsigned long long)bh->b_blocknr, 7,
@@ -184,6 +182,35 @@ int ocfs2_validate_group_descriptor(struct super_block *sb,
184 return -EINVAL; 182 return -EINVAL;
185 } 183 }
186 184
185 if (le16_to_cpu(gd->bg_free_bits_count) > le16_to_cpu(gd->bg_bits)) {
186 do_error("Group descriptor #%llu has bit count %u but "
187 "claims that %u are free",
188 (unsigned long long)bh->b_blocknr,
189 le16_to_cpu(gd->bg_bits),
190 le16_to_cpu(gd->bg_free_bits_count));
191 return -EINVAL;
192 }
193
194 if (le16_to_cpu(gd->bg_bits) > (8 * le16_to_cpu(gd->bg_size))) {
195 do_error("Group descriptor #%llu has bit count %u but "
196 "max bitmap bits of %u",
197 (unsigned long long)bh->b_blocknr,
198 le16_to_cpu(gd->bg_bits),
199 8 * le16_to_cpu(gd->bg_size));
200 return -EINVAL;
201 }
202
203 return 0;
204}
205
206static int ocfs2_validate_gd_parent(struct super_block *sb,
207 struct ocfs2_dinode *di,
208 struct buffer_head *bh,
209 int clean_error)
210{
211 unsigned int max_bits;
212 struct ocfs2_group_desc *gd = (struct ocfs2_group_desc *)bh->b_data;
213
187 if (di->i_blkno != gd->bg_parent_dinode) { 214 if (di->i_blkno != gd->bg_parent_dinode) {
188 do_error("Group descriptor #%llu has bad parent " 215 do_error("Group descriptor #%llu has bad parent "
189 "pointer (%llu, expected %llu)", 216 "pointer (%llu, expected %llu)",
@@ -209,26 +236,35 @@ int ocfs2_validate_group_descriptor(struct super_block *sb,
209 return -EINVAL; 236 return -EINVAL;
210 } 237 }
211 238
212 if (le16_to_cpu(gd->bg_free_bits_count) > le16_to_cpu(gd->bg_bits)) { 239 return 0;
213 do_error("Group descriptor #%llu has bit count %u but " 240}
214 "claims that %u are free",
215 (unsigned long long)bh->b_blocknr,
216 le16_to_cpu(gd->bg_bits),
217 le16_to_cpu(gd->bg_free_bits_count));
218 return -EINVAL;
219 }
220 241
221 if (le16_to_cpu(gd->bg_bits) > (8 * le16_to_cpu(gd->bg_size))) {
222 do_error("Group descriptor #%llu has bit count %u but "
223 "max bitmap bits of %u",
224 (unsigned long long)bh->b_blocknr,
225 le16_to_cpu(gd->bg_bits),
226 8 * le16_to_cpu(gd->bg_size));
227 return -EINVAL;
228 }
229#undef do_error 242#undef do_error
230 243
231 return 0; 244/*
245 * This version only prints errors. It does not fail the filesystem, and
246 * exists only for resize.
247 */
248int ocfs2_check_group_descriptor(struct super_block *sb,
249 struct ocfs2_dinode *di,
250 struct buffer_head *bh)
251{
252 int rc;
253
254 rc = ocfs2_validate_gd_self(sb, bh, 1);
255 if (!rc)
256 rc = ocfs2_validate_gd_parent(sb, di, bh, 1);
257
258 return rc;
259}
260
261static int ocfs2_validate_group_descriptor(struct super_block *sb,
262 struct buffer_head *bh)
263{
264 mlog(0, "Validating group descriptor %llu\n",
265 (unsigned long long)bh->b_blocknr);
266
267 return ocfs2_validate_gd_self(sb, bh, 0);
232} 268}
233 269
234int ocfs2_read_group_descriptor(struct inode *inode, struct ocfs2_dinode *di, 270int ocfs2_read_group_descriptor(struct inode *inode, struct ocfs2_dinode *di,
@@ -237,11 +273,12 @@ int ocfs2_read_group_descriptor(struct inode *inode, struct ocfs2_dinode *di,
237 int rc; 273 int rc;
238 struct buffer_head *tmp = *bh; 274 struct buffer_head *tmp = *bh;
239 275
240 rc = ocfs2_read_block(inode, gd_blkno, &tmp); 276 rc = ocfs2_read_block(inode, gd_blkno, &tmp,
277 ocfs2_validate_group_descriptor);
241 if (rc) 278 if (rc)
242 goto out; 279 goto out;
243 280
244 rc = ocfs2_validate_group_descriptor(inode->i_sb, di, tmp, 0); 281 rc = ocfs2_validate_gd_parent(inode->i_sb, di, tmp, 0);
245 if (rc) { 282 if (rc) {
246 brelse(tmp); 283 brelse(tmp);
247 goto out; 284 goto out;