aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJoel Becker <joel.becker@oracle.com>2008-11-13 17:49:12 -0500
committerMark Fasheh <mfasheh@suse.com>2009-01-05 11:36:52 -0500
commit10995aa2451afa20b721cc7de856cae1a13dba57 (patch)
tree63129e7d752fb018dc76aa42de136baa4a8a4232
parentb657c95c11088d77fc1bfc9c84d940f778bf9d12 (diff)
ocfs2: Morph the haphazard OCFS2_IS_VALID_DINODE() checks.
Random places in the code would check a dinode bh to see if it was valid. Not only did they do different levels of validation, they handled errors in different ways. The previous commit unified inode block reads, validating all block reads in the same place. Thus, these haphazard checks are no longer necessary. Rather than eliminate them, however, we change them to BUG_ON() checks. This ensures the assumptions remain true. All of the code paths to these checks have been audited to ensure they come from a validated inode read. Signed-off-by: Joel Becker <joel.becker@oracle.com> Signed-off-by: Mark Fasheh <mfasheh@suse.com>
-rw-r--r--fs/ocfs2/alloc.c50
-rw-r--r--fs/ocfs2/journal.c17
-rw-r--r--fs/ocfs2/ocfs2.h8
-rw-r--r--fs/ocfs2/resize.c10
-rw-r--r--fs/ocfs2/suballoc.c36
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,
187static int ocfs2_dinode_sanity_check(struct inode *inode, 187static 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
206static void ocfs2_dinode_fill_root_el(struct ocfs2_extent_tree *et) 198static 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
616out:
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",