diff options
-rw-r--r-- | fs/ocfs2/alloc.c | 50 | ||||
-rw-r--r-- | fs/ocfs2/journal.c | 17 | ||||
-rw-r--r-- | fs/ocfs2/ocfs2.h | 8 | ||||
-rw-r--r-- | fs/ocfs2/resize.c | 10 | ||||
-rw-r--r-- | fs/ocfs2/suballoc.c | 36 |
5 files changed, 46 insertions, 75 deletions
diff --git a/fs/ocfs2/alloc.c b/fs/ocfs2/alloc.c index 9c598adc9475..320545b9fe12 100644 --- a/fs/ocfs2/alloc.c +++ b/fs/ocfs2/alloc.c | |||
@@ -187,20 +187,12 @@ static int ocfs2_dinode_insert_check(struct inode *inode, | |||
187 | static int ocfs2_dinode_sanity_check(struct inode *inode, | 187 | static int ocfs2_dinode_sanity_check(struct inode *inode, |
188 | struct ocfs2_extent_tree *et) | 188 | struct ocfs2_extent_tree *et) |
189 | { | 189 | { |
190 | int ret = 0; | 190 | struct ocfs2_dinode *di = et->et_object; |
191 | struct ocfs2_dinode *di; | ||
192 | 191 | ||
193 | BUG_ON(et->et_ops != &ocfs2_dinode_et_ops); | 192 | BUG_ON(et->et_ops != &ocfs2_dinode_et_ops); |
193 | BUG_ON(!OCFS2_IS_VALID_DINODE(di)); | ||
194 | 194 | ||
195 | di = et->et_object; | 195 | return 0; |
196 | if (!OCFS2_IS_VALID_DINODE(di)) { | ||
197 | ret = -EIO; | ||
198 | ocfs2_error(inode->i_sb, | ||
199 | "Inode %llu has invalid path root", | ||
200 | (unsigned long long)OCFS2_I(inode)->ip_blkno); | ||
201 | } | ||
202 | |||
203 | return ret; | ||
204 | } | 196 | } |
205 | 197 | ||
206 | static void ocfs2_dinode_fill_root_el(struct ocfs2_extent_tree *et) | 198 | static void ocfs2_dinode_fill_root_el(struct ocfs2_extent_tree *et) |
@@ -5380,13 +5372,13 @@ int ocfs2_truncate_log_append(struct ocfs2_super *osb, | |||
5380 | start_cluster = ocfs2_blocks_to_clusters(osb->sb, start_blk); | 5372 | start_cluster = ocfs2_blocks_to_clusters(osb->sb, start_blk); |
5381 | 5373 | ||
5382 | di = (struct ocfs2_dinode *) tl_bh->b_data; | 5374 | di = (struct ocfs2_dinode *) tl_bh->b_data; |
5383 | tl = &di->id2.i_dealloc; | ||
5384 | if (!OCFS2_IS_VALID_DINODE(di)) { | ||
5385 | OCFS2_RO_ON_INVALID_DINODE(osb->sb, di); | ||
5386 | status = -EIO; | ||
5387 | goto bail; | ||
5388 | } | ||
5389 | 5375 | ||
5376 | /* tl_bh is loaded from ocfs2_truncate_log_init(). It's validated | ||
5377 | * by the underlying call to ocfs2_read_inode_block(), so any | ||
5378 | * corruption is a code bug */ | ||
5379 | BUG_ON(!OCFS2_IS_VALID_DINODE(di)); | ||
5380 | |||
5381 | tl = &di->id2.i_dealloc; | ||
5390 | tl_count = le16_to_cpu(tl->tl_count); | 5382 | tl_count = le16_to_cpu(tl->tl_count); |
5391 | mlog_bug_on_msg(tl_count > ocfs2_truncate_recs_per_inode(osb->sb) || | 5383 | mlog_bug_on_msg(tl_count > ocfs2_truncate_recs_per_inode(osb->sb) || |
5392 | tl_count == 0, | 5384 | tl_count == 0, |
@@ -5536,13 +5528,13 @@ int __ocfs2_flush_truncate_log(struct ocfs2_super *osb) | |||
5536 | BUG_ON(mutex_trylock(&tl_inode->i_mutex)); | 5528 | BUG_ON(mutex_trylock(&tl_inode->i_mutex)); |
5537 | 5529 | ||
5538 | di = (struct ocfs2_dinode *) tl_bh->b_data; | 5530 | di = (struct ocfs2_dinode *) tl_bh->b_data; |
5539 | tl = &di->id2.i_dealloc; | ||
5540 | if (!OCFS2_IS_VALID_DINODE(di)) { | ||
5541 | OCFS2_RO_ON_INVALID_DINODE(osb->sb, di); | ||
5542 | status = -EIO; | ||
5543 | goto out; | ||
5544 | } | ||
5545 | 5531 | ||
5532 | /* tl_bh is loaded from ocfs2_truncate_log_init(). It's validated | ||
5533 | * by the underlying call to ocfs2_read_inode_block(), so any | ||
5534 | * corruption is a code bug */ | ||
5535 | BUG_ON(!OCFS2_IS_VALID_DINODE(di)); | ||
5536 | |||
5537 | tl = &di->id2.i_dealloc; | ||
5546 | num_to_flush = le16_to_cpu(tl->tl_used); | 5538 | num_to_flush = le16_to_cpu(tl->tl_used); |
5547 | mlog(0, "Flush %u records from truncate log #%llu\n", | 5539 | mlog(0, "Flush %u records from truncate log #%llu\n", |
5548 | num_to_flush, (unsigned long long)OCFS2_I(tl_inode)->ip_blkno); | 5540 | num_to_flush, (unsigned long long)OCFS2_I(tl_inode)->ip_blkno); |
@@ -5697,13 +5689,13 @@ int ocfs2_begin_truncate_log_recovery(struct ocfs2_super *osb, | |||
5697 | } | 5689 | } |
5698 | 5690 | ||
5699 | di = (struct ocfs2_dinode *) tl_bh->b_data; | 5691 | di = (struct ocfs2_dinode *) tl_bh->b_data; |
5700 | tl = &di->id2.i_dealloc; | ||
5701 | if (!OCFS2_IS_VALID_DINODE(di)) { | ||
5702 | OCFS2_RO_ON_INVALID_DINODE(tl_inode->i_sb, di); | ||
5703 | status = -EIO; | ||
5704 | goto bail; | ||
5705 | } | ||
5706 | 5692 | ||
5693 | /* tl_bh is loaded from ocfs2_get_truncate_log_info(). It's | ||
5694 | * validated by the underlying call to ocfs2_read_inode_block(), | ||
5695 | * so any corruption is a code bug */ | ||
5696 | BUG_ON(!OCFS2_IS_VALID_DINODE(di)); | ||
5697 | |||
5698 | tl = &di->id2.i_dealloc; | ||
5707 | if (le16_to_cpu(tl->tl_used)) { | 5699 | if (le16_to_cpu(tl->tl_used)) { |
5708 | mlog(0, "We'll have %u logs to recover\n", | 5700 | mlog(0, "We'll have %u logs to recover\n", |
5709 | le16_to_cpu(tl->tl_used)); | 5701 | le16_to_cpu(tl->tl_used)); |
diff --git a/fs/ocfs2/journal.c b/fs/ocfs2/journal.c index 877aaa05e199..9223bfcca3ba 100644 --- a/fs/ocfs2/journal.c +++ b/fs/ocfs2/journal.c | |||
@@ -587,17 +587,11 @@ static int ocfs2_journal_toggle_dirty(struct ocfs2_super *osb, | |||
587 | mlog_entry_void(); | 587 | mlog_entry_void(); |
588 | 588 | ||
589 | fe = (struct ocfs2_dinode *)bh->b_data; | 589 | fe = (struct ocfs2_dinode *)bh->b_data; |
590 | if (!OCFS2_IS_VALID_DINODE(fe)) { | 590 | |
591 | /* This is called from startup/shutdown which will | 591 | /* The journal bh on the osb always comes from ocfs2_journal_init() |
592 | * handle the errors in a specific manner, so no need | 592 | * and was validated there inside ocfs2_inode_lock_full(). It's a |
593 | * to call ocfs2_error() here. */ | 593 | * code bug if we mess it up. */ |
594 | mlog(ML_ERROR, "Journal dinode %llu has invalid " | 594 | BUG_ON(!OCFS2_IS_VALID_DINODE(fe)); |
595 | "signature: %.*s", | ||
596 | (unsigned long long)le64_to_cpu(fe->i_blkno), 7, | ||
597 | fe->i_signature); | ||
598 | status = -EIO; | ||
599 | goto out; | ||
600 | } | ||
601 | 595 | ||
602 | flags = le32_to_cpu(fe->id1.journal1.ij_flags); | 596 | flags = le32_to_cpu(fe->id1.journal1.ij_flags); |
603 | if (dirty) | 597 | if (dirty) |
@@ -613,7 +607,6 @@ static int ocfs2_journal_toggle_dirty(struct ocfs2_super *osb, | |||
613 | if (status < 0) | 607 | if (status < 0) |
614 | mlog_errno(status); | 608 | mlog_errno(status); |
615 | 609 | ||
616 | out: | ||
617 | mlog_exit(status); | 610 | mlog_exit(status); |
618 | return status; | 611 | return status; |
619 | } | 612 | } |
diff --git a/fs/ocfs2/ocfs2.h b/fs/ocfs2/ocfs2.h index 25d07ff1d3cd..467bdb6f71e1 100644 --- a/fs/ocfs2/ocfs2.h +++ b/fs/ocfs2/ocfs2.h | |||
@@ -444,14 +444,6 @@ static inline int ocfs2_uses_extended_slot_map(struct ocfs2_super *osb) | |||
444 | #define OCFS2_IS_VALID_DINODE(ptr) \ | 444 | #define OCFS2_IS_VALID_DINODE(ptr) \ |
445 | (!strcmp((ptr)->i_signature, OCFS2_INODE_SIGNATURE)) | 445 | (!strcmp((ptr)->i_signature, OCFS2_INODE_SIGNATURE)) |
446 | 446 | ||
447 | #define OCFS2_RO_ON_INVALID_DINODE(__sb, __di) do { \ | ||
448 | typeof(__di) ____di = (__di); \ | ||
449 | ocfs2_error((__sb), \ | ||
450 | "Dinode # %llu has bad signature %.*s", \ | ||
451 | (unsigned long long)le64_to_cpu((____di)->i_blkno), 7, \ | ||
452 | (____di)->i_signature); \ | ||
453 | } while (0) | ||
454 | |||
455 | #define OCFS2_IS_VALID_EXTENT_BLOCK(ptr) \ | 447 | #define OCFS2_IS_VALID_EXTENT_BLOCK(ptr) \ |
456 | (!strcmp((ptr)->h_signature, OCFS2_EXTENT_BLOCK_SIGNATURE)) | 448 | (!strcmp((ptr)->h_signature, OCFS2_EXTENT_BLOCK_SIGNATURE)) |
457 | 449 | ||
diff --git a/fs/ocfs2/resize.c b/fs/ocfs2/resize.c index ffd48db229a7..739d452f6174 100644 --- a/fs/ocfs2/resize.c +++ b/fs/ocfs2/resize.c | |||
@@ -314,6 +314,10 @@ int ocfs2_group_extend(struct inode * inode, int new_clusters) | |||
314 | 314 | ||
315 | fe = (struct ocfs2_dinode *)main_bm_bh->b_data; | 315 | fe = (struct ocfs2_dinode *)main_bm_bh->b_data; |
316 | 316 | ||
317 | /* main_bm_bh is validated by inode read inside ocfs2_inode_lock(), | ||
318 | * so any corruption is a code bug. */ | ||
319 | BUG_ON(!OCFS2_IS_VALID_DINODE(fe)); | ||
320 | |||
317 | if (le16_to_cpu(fe->id2.i_chain.cl_cpg) != | 321 | if (le16_to_cpu(fe->id2.i_chain.cl_cpg) != |
318 | ocfs2_group_bitmap_size(osb->sb) * 8) { | 322 | ocfs2_group_bitmap_size(osb->sb) * 8) { |
319 | mlog(ML_ERROR, "The disk is too old and small. " | 323 | mlog(ML_ERROR, "The disk is too old and small. " |
@@ -322,12 +326,6 @@ int ocfs2_group_extend(struct inode * inode, int new_clusters) | |||
322 | goto out_unlock; | 326 | goto out_unlock; |
323 | } | 327 | } |
324 | 328 | ||
325 | if (!OCFS2_IS_VALID_DINODE(fe)) { | ||
326 | OCFS2_RO_ON_INVALID_DINODE(main_bm_inode->i_sb, fe); | ||
327 | ret = -EIO; | ||
328 | goto out_unlock; | ||
329 | } | ||
330 | |||
331 | first_new_cluster = le32_to_cpu(fe->i_clusters); | 329 | first_new_cluster = le32_to_cpu(fe->i_clusters); |
332 | lgd_blkno = ocfs2_which_cluster_group(main_bm_inode, | 330 | lgd_blkno = ocfs2_which_cluster_group(main_bm_inode, |
333 | first_new_cluster - 1); | 331 | first_new_cluster - 1); |
diff --git a/fs/ocfs2/suballoc.c b/fs/ocfs2/suballoc.c index c5ff18b46b57..95d432b694e4 100644 --- a/fs/ocfs2/suballoc.c +++ b/fs/ocfs2/suballoc.c | |||
@@ -441,11 +441,11 @@ static int ocfs2_reserve_suballoc_bits(struct ocfs2_super *osb, | |||
441 | ac->ac_alloc_slot = slot; | 441 | ac->ac_alloc_slot = slot; |
442 | 442 | ||
443 | fe = (struct ocfs2_dinode *) bh->b_data; | 443 | fe = (struct ocfs2_dinode *) bh->b_data; |
444 | if (!OCFS2_IS_VALID_DINODE(fe)) { | 444 | |
445 | OCFS2_RO_ON_INVALID_DINODE(alloc_inode->i_sb, fe); | 445 | /* The bh was validated by the inode read inside |
446 | status = -EIO; | 446 | * ocfs2_inode_lock(). Any corruption is a code bug. */ |
447 | goto bail; | 447 | BUG_ON(!OCFS2_IS_VALID_DINODE(fe)); |
448 | } | 448 | |
449 | if (!(fe->i_flags & cpu_to_le32(OCFS2_CHAIN_FL))) { | 449 | if (!(fe->i_flags & cpu_to_le32(OCFS2_CHAIN_FL))) { |
450 | ocfs2_error(alloc_inode->i_sb, "Invalid chain allocator %llu", | 450 | ocfs2_error(alloc_inode->i_sb, "Invalid chain allocator %llu", |
451 | (unsigned long long)le64_to_cpu(fe->i_blkno)); | 451 | (unsigned long long)le64_to_cpu(fe->i_blkno)); |
@@ -931,11 +931,6 @@ static int ocfs2_relink_block_group(handle_t *handle, | |||
931 | struct ocfs2_group_desc *bg = (struct ocfs2_group_desc *) bg_bh->b_data; | 931 | struct ocfs2_group_desc *bg = (struct ocfs2_group_desc *) bg_bh->b_data; |
932 | struct ocfs2_group_desc *prev_bg = (struct ocfs2_group_desc *) prev_bg_bh->b_data; | 932 | struct ocfs2_group_desc *prev_bg = (struct ocfs2_group_desc *) prev_bg_bh->b_data; |
933 | 933 | ||
934 | if (!OCFS2_IS_VALID_DINODE(fe)) { | ||
935 | OCFS2_RO_ON_INVALID_DINODE(alloc_inode->i_sb, fe); | ||
936 | status = -EIO; | ||
937 | goto out; | ||
938 | } | ||
939 | if (!OCFS2_IS_VALID_GROUP_DESC(bg)) { | 934 | if (!OCFS2_IS_VALID_GROUP_DESC(bg)) { |
940 | OCFS2_RO_ON_INVALID_GROUP_DESC(alloc_inode->i_sb, bg); | 935 | OCFS2_RO_ON_INVALID_GROUP_DESC(alloc_inode->i_sb, bg); |
941 | status = -EIO; | 936 | status = -EIO; |
@@ -1392,11 +1387,11 @@ static int ocfs2_claim_suballoc_bits(struct ocfs2_super *osb, | |||
1392 | BUG_ON(!ac->ac_bh); | 1387 | BUG_ON(!ac->ac_bh); |
1393 | 1388 | ||
1394 | fe = (struct ocfs2_dinode *) ac->ac_bh->b_data; | 1389 | fe = (struct ocfs2_dinode *) ac->ac_bh->b_data; |
1395 | if (!OCFS2_IS_VALID_DINODE(fe)) { | 1390 | |
1396 | OCFS2_RO_ON_INVALID_DINODE(osb->sb, fe); | 1391 | /* The bh was validated by the inode read during |
1397 | status = -EIO; | 1392 | * ocfs2_reserve_suballoc_bits(). Any corruption is a code bug. */ |
1398 | goto bail; | 1393 | BUG_ON(!OCFS2_IS_VALID_DINODE(fe)); |
1399 | } | 1394 | |
1400 | if (le32_to_cpu(fe->id1.bitmap1.i_used) >= | 1395 | if (le32_to_cpu(fe->id1.bitmap1.i_used) >= |
1401 | le32_to_cpu(fe->id1.bitmap1.i_total)) { | 1396 | le32_to_cpu(fe->id1.bitmap1.i_total)) { |
1402 | ocfs2_error(osb->sb, "Chain allocator dinode %llu has %u used " | 1397 | ocfs2_error(osb->sb, "Chain allocator dinode %llu has %u used " |
@@ -1782,11 +1777,12 @@ int ocfs2_free_suballoc_bits(handle_t *handle, | |||
1782 | 1777 | ||
1783 | mlog_entry_void(); | 1778 | mlog_entry_void(); |
1784 | 1779 | ||
1785 | if (!OCFS2_IS_VALID_DINODE(fe)) { | 1780 | /* The alloc_bh comes from ocfs2_free_dinode() or |
1786 | OCFS2_RO_ON_INVALID_DINODE(alloc_inode->i_sb, fe); | 1781 | * ocfs2_free_clusters(). The callers have all locked the |
1787 | status = -EIO; | 1782 | * allocator and gotten alloc_bh from the lock call. This |
1788 | goto bail; | 1783 | * validates the dinode buffer. Any corruption that has happended |
1789 | } | 1784 | * is a code bug. */ |
1785 | BUG_ON(!OCFS2_IS_VALID_DINODE(fe)); | ||
1790 | BUG_ON((count + start_bit) > ocfs2_bits_per_group(cl)); | 1786 | BUG_ON((count + start_bit) > ocfs2_bits_per_group(cl)); |
1791 | 1787 | ||
1792 | mlog(0, "%llu: freeing %u bits from group %llu, starting at %u\n", | 1788 | mlog(0, "%llu: freeing %u bits from group %llu, starting at %u\n", |