Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

ocfs2: fix NULL pointer dereference in ocfs2_abort_trigger()

bdev->bd_super has been removed and commit 8887b94d9322 change the usage
from bdev->bd_super to b_assoc_map->host->i_sb. Since ocfs2 hasn't set
bh->b_assoc_map, it will trigger NULL pointer dereference when calling
into ocfs2_abort_trigger().

Actually this was pointed out in history, see commit 74e364ad1b13. But
I've made a mistake when reviewing commit 8887b94d9322 and then
re-introduce this regression.

Since we cannot revive bdev in buffer head, so fix this issue by
initializing all types of ocfs2 triggers when fill super, and then get the
specific ocfs2 trigger from ocfs2_caching_info when access journal.

[joseph.qi@linux.alibaba.com: v2]
Link: https://lkml.kernel.org/r/20240602112045.1112708-1-joseph.qi@linux.alibaba.com
Link: https://lkml.kernel.org/r/20240530110630.3933832-2-joseph.qi@linux.alibaba.com
Fixes: 8887b94d9322 ("ocfs2: stop using bdev->bd_super for journal error logging")
Signed-off-by: Joseph Qi <joseph.qi@linux.alibaba.com>
Reviewed-by: Heming Zhao <heming.zhao@suse.com>
Cc: Mark Fasheh <mark@fasheh.com>
Cc: Joel Becker <jlbec@evilplan.org>
Cc: Junxiao Bi <junxiao.bi@oracle.com>
Cc: Changwei Ge <gechangwei@live.cn>
Cc: Gang He <ghe@suse.com>
Cc: Jun Piao <piaojun@huawei.com>
Cc: <stable@vger.kernel.org> [6.6+]
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>

authored by

Joseph Qi and committed by
Andrew Morton
685d03c3 58f7e1e2

+131 -82
+101 -81
fs/ocfs2/journal.c
··· 479 479 return status; 480 480 } 481 481 482 - 483 - struct ocfs2_triggers { 484 - struct jbd2_buffer_trigger_type ot_triggers; 485 - int ot_offset; 486 - }; 487 - 488 482 static inline struct ocfs2_triggers *to_ocfs2_trigger(struct jbd2_buffer_trigger_type *triggers) 489 483 { 490 484 return container_of(triggers, struct ocfs2_triggers, ot_triggers); ··· 542 548 static void ocfs2_abort_trigger(struct jbd2_buffer_trigger_type *triggers, 543 549 struct buffer_head *bh) 544 550 { 551 + struct ocfs2_triggers *ot = to_ocfs2_trigger(triggers); 552 + 545 553 mlog(ML_ERROR, 546 554 "ocfs2_abort_trigger called by JBD2. bh = 0x%lx, " 547 555 "bh->b_blocknr = %llu\n", 548 556 (unsigned long)bh, 549 557 (unsigned long long)bh->b_blocknr); 550 558 551 - ocfs2_error(bh->b_assoc_map->host->i_sb, 559 + ocfs2_error(ot->sb, 552 560 "JBD2 has aborted our journal, ocfs2 cannot continue\n"); 553 561 } 554 562 555 - static struct ocfs2_triggers di_triggers = { 556 - .ot_triggers = { 557 - .t_frozen = ocfs2_frozen_trigger, 558 - .t_abort = ocfs2_abort_trigger, 559 - }, 560 - .ot_offset = offsetof(struct ocfs2_dinode, i_check), 561 - }; 563 + static void ocfs2_setup_csum_triggers(struct super_block *sb, 564 + enum ocfs2_journal_trigger_type type, 565 + struct ocfs2_triggers *ot) 566 + { 567 + BUG_ON(type >= OCFS2_JOURNAL_TRIGGER_COUNT); 562 568 563 - static struct ocfs2_triggers eb_triggers = { 564 - .ot_triggers = { 565 - .t_frozen = ocfs2_frozen_trigger, 566 - .t_abort = ocfs2_abort_trigger, 567 - }, 568 - .ot_offset = offsetof(struct ocfs2_extent_block, h_check), 569 - }; 569 + switch (type) { 570 + case OCFS2_JTR_DI: 571 + ot->ot_triggers.t_frozen = ocfs2_frozen_trigger; 572 + ot->ot_offset = offsetof(struct ocfs2_dinode, i_check); 573 + break; 574 + case OCFS2_JTR_EB: 575 + ot->ot_triggers.t_frozen = ocfs2_frozen_trigger; 576 + ot->ot_offset = offsetof(struct ocfs2_extent_block, h_check); 577 + break; 578 + case OCFS2_JTR_RB: 579 + ot->ot_triggers.t_frozen = ocfs2_frozen_trigger; 580 + ot->ot_offset = offsetof(struct ocfs2_refcount_block, rf_check); 581 + break; 582 + case OCFS2_JTR_GD: 583 + ot->ot_triggers.t_frozen = ocfs2_frozen_trigger; 584 + ot->ot_offset = offsetof(struct ocfs2_group_desc, bg_check); 585 + break; 586 + case OCFS2_JTR_DB: 587 + ot->ot_triggers.t_frozen = ocfs2_db_frozen_trigger; 588 + break; 589 + case OCFS2_JTR_XB: 590 + ot->ot_triggers.t_frozen = ocfs2_frozen_trigger; 591 + ot->ot_offset = offsetof(struct ocfs2_xattr_block, xb_check); 592 + break; 593 + case OCFS2_JTR_DQ: 594 + ot->ot_triggers.t_frozen = ocfs2_dq_frozen_trigger; 595 + break; 596 + case OCFS2_JTR_DR: 597 + ot->ot_triggers.t_frozen = ocfs2_frozen_trigger; 598 + ot->ot_offset = offsetof(struct ocfs2_dx_root_block, dr_check); 599 + break; 600 + case OCFS2_JTR_DL: 601 + ot->ot_triggers.t_frozen = ocfs2_frozen_trigger; 602 + ot->ot_offset = offsetof(struct ocfs2_dx_leaf, dl_check); 603 + break; 604 + case OCFS2_JTR_NONE: 605 + /* To make compiler happy... */ 606 + return; 607 + } 570 608 571 - static struct ocfs2_triggers rb_triggers = { 572 - .ot_triggers = { 573 - .t_frozen = ocfs2_frozen_trigger, 574 - .t_abort = ocfs2_abort_trigger, 575 - }, 576 - .ot_offset = offsetof(struct ocfs2_refcount_block, rf_check), 577 - }; 609 + ot->ot_triggers.t_abort = ocfs2_abort_trigger; 610 + ot->sb = sb; 611 + } 578 612 579 - static struct ocfs2_triggers gd_triggers = { 580 - .ot_triggers = { 581 - .t_frozen = ocfs2_frozen_trigger, 582 - .t_abort = ocfs2_abort_trigger, 583 - }, 584 - .ot_offset = offsetof(struct ocfs2_group_desc, bg_check), 585 - }; 613 + void ocfs2_initialize_journal_triggers(struct super_block *sb, 614 + struct ocfs2_triggers triggers[]) 615 + { 616 + enum ocfs2_journal_trigger_type type; 586 617 587 - static struct ocfs2_triggers db_triggers = { 588 - .ot_triggers = { 589 - .t_frozen = ocfs2_db_frozen_trigger, 590 - .t_abort = ocfs2_abort_trigger, 591 - }, 592 - }; 593 - 594 - static struct ocfs2_triggers xb_triggers = { 595 - .ot_triggers = { 596 - .t_frozen = ocfs2_frozen_trigger, 597 - .t_abort = ocfs2_abort_trigger, 598 - }, 599 - .ot_offset = offsetof(struct ocfs2_xattr_block, xb_check), 600 - }; 601 - 602 - static struct ocfs2_triggers dq_triggers = { 603 - .ot_triggers = { 604 - .t_frozen = ocfs2_dq_frozen_trigger, 605 - .t_abort = ocfs2_abort_trigger, 606 - }, 607 - }; 608 - 609 - static struct ocfs2_triggers dr_triggers = { 610 - .ot_triggers = { 611 - .t_frozen = ocfs2_frozen_trigger, 612 - .t_abort = ocfs2_abort_trigger, 613 - }, 614 - .ot_offset = offsetof(struct ocfs2_dx_root_block, dr_check), 615 - }; 616 - 617 - static struct ocfs2_triggers dl_triggers = { 618 - .ot_triggers = { 619 - .t_frozen = ocfs2_frozen_trigger, 620 - .t_abort = ocfs2_abort_trigger, 621 - }, 622 - .ot_offset = offsetof(struct ocfs2_dx_leaf, dl_check), 623 - }; 618 + for (type = OCFS2_JTR_DI; type < OCFS2_JOURNAL_TRIGGER_COUNT; type++) 619 + ocfs2_setup_csum_triggers(sb, type, &triggers[type]); 620 + } 624 621 625 622 static int __ocfs2_journal_access(handle_t *handle, 626 623 struct ocfs2_caching_info *ci, ··· 693 708 int ocfs2_journal_access_di(handle_t *handle, struct ocfs2_caching_info *ci, 694 709 struct buffer_head *bh, int type) 695 710 { 696 - return __ocfs2_journal_access(handle, ci, bh, &di_triggers, type); 711 + struct ocfs2_super *osb = OCFS2_SB(ocfs2_metadata_cache_get_super(ci)); 712 + 713 + return __ocfs2_journal_access(handle, ci, bh, 714 + &osb->s_journal_triggers[OCFS2_JTR_DI], 715 + type); 697 716 } 698 717 699 718 int ocfs2_journal_access_eb(handle_t *handle, struct ocfs2_caching_info *ci, 700 719 struct buffer_head *bh, int type) 701 720 { 702 - return __ocfs2_journal_access(handle, ci, bh, &eb_triggers, type); 721 + struct ocfs2_super *osb = OCFS2_SB(ocfs2_metadata_cache_get_super(ci)); 722 + 723 + return __ocfs2_journal_access(handle, ci, bh, 724 + &osb->s_journal_triggers[OCFS2_JTR_EB], 725 + type); 703 726 } 704 727 705 728 int ocfs2_journal_access_rb(handle_t *handle, struct ocfs2_caching_info *ci, 706 729 struct buffer_head *bh, int type) 707 730 { 708 - return __ocfs2_journal_access(handle, ci, bh, &rb_triggers, 731 + struct ocfs2_super *osb = OCFS2_SB(ocfs2_metadata_cache_get_super(ci)); 732 + 733 + return __ocfs2_journal_access(handle, ci, bh, 734 + &osb->s_journal_triggers[OCFS2_JTR_RB], 709 735 type); 710 736 } 711 737 712 738 int ocfs2_journal_access_gd(handle_t *handle, struct ocfs2_caching_info *ci, 713 739 struct buffer_head *bh, int type) 714 740 { 715 - return __ocfs2_journal_access(handle, ci, bh, &gd_triggers, type); 741 + struct ocfs2_super *osb = OCFS2_SB(ocfs2_metadata_cache_get_super(ci)); 742 + 743 + return __ocfs2_journal_access(handle, ci, bh, 744 + &osb->s_journal_triggers[OCFS2_JTR_GD], 745 + type); 716 746 } 717 747 718 748 int ocfs2_journal_access_db(handle_t *handle, struct ocfs2_caching_info *ci, 719 749 struct buffer_head *bh, int type) 720 750 { 721 - return __ocfs2_journal_access(handle, ci, bh, &db_triggers, type); 751 + struct ocfs2_super *osb = OCFS2_SB(ocfs2_metadata_cache_get_super(ci)); 752 + 753 + return __ocfs2_journal_access(handle, ci, bh, 754 + &osb->s_journal_triggers[OCFS2_JTR_DB], 755 + type); 722 756 } 723 757 724 758 int ocfs2_journal_access_xb(handle_t *handle, struct ocfs2_caching_info *ci, 725 759 struct buffer_head *bh, int type) 726 760 { 727 - return __ocfs2_journal_access(handle, ci, bh, &xb_triggers, type); 761 + struct ocfs2_super *osb = OCFS2_SB(ocfs2_metadata_cache_get_super(ci)); 762 + 763 + return __ocfs2_journal_access(handle, ci, bh, 764 + &osb->s_journal_triggers[OCFS2_JTR_XB], 765 + type); 728 766 } 729 767 730 768 int ocfs2_journal_access_dq(handle_t *handle, struct ocfs2_caching_info *ci, 731 769 struct buffer_head *bh, int type) 732 770 { 733 - return __ocfs2_journal_access(handle, ci, bh, &dq_triggers, type); 771 + struct ocfs2_super *osb = OCFS2_SB(ocfs2_metadata_cache_get_super(ci)); 772 + 773 + return __ocfs2_journal_access(handle, ci, bh, 774 + &osb->s_journal_triggers[OCFS2_JTR_DQ], 775 + type); 734 776 } 735 777 736 778 int ocfs2_journal_access_dr(handle_t *handle, struct ocfs2_caching_info *ci, 737 779 struct buffer_head *bh, int type) 738 780 { 739 - return __ocfs2_journal_access(handle, ci, bh, &dr_triggers, type); 781 + struct ocfs2_super *osb = OCFS2_SB(ocfs2_metadata_cache_get_super(ci)); 782 + 783 + return __ocfs2_journal_access(handle, ci, bh, 784 + &osb->s_journal_triggers[OCFS2_JTR_DR], 785 + type); 740 786 } 741 787 742 788 int ocfs2_journal_access_dl(handle_t *handle, struct ocfs2_caching_info *ci, 743 789 struct buffer_head *bh, int type) 744 790 { 745 - return __ocfs2_journal_access(handle, ci, bh, &dl_triggers, type); 791 + struct ocfs2_super *osb = OCFS2_SB(ocfs2_metadata_cache_get_super(ci)); 792 + 793 + return __ocfs2_journal_access(handle, ci, bh, 794 + &osb->s_journal_triggers[OCFS2_JTR_DL], 795 + type); 746 796 } 747 797 748 798 int ocfs2_journal_access(handle_t *handle, struct ocfs2_caching_info *ci,
+27
fs/ocfs2/ocfs2.h
··· 284 284 #define OCFS2_OSB_ERROR_FS 0x0004 285 285 #define OCFS2_DEFAULT_ATIME_QUANTUM 60 286 286 287 + struct ocfs2_triggers { 288 + struct jbd2_buffer_trigger_type ot_triggers; 289 + int ot_offset; 290 + struct super_block *sb; 291 + }; 292 + 293 + enum ocfs2_journal_trigger_type { 294 + OCFS2_JTR_DI, 295 + OCFS2_JTR_EB, 296 + OCFS2_JTR_RB, 297 + OCFS2_JTR_GD, 298 + OCFS2_JTR_DB, 299 + OCFS2_JTR_XB, 300 + OCFS2_JTR_DQ, 301 + OCFS2_JTR_DR, 302 + OCFS2_JTR_DL, 303 + OCFS2_JTR_NONE /* This must be the last entry */ 304 + }; 305 + 306 + #define OCFS2_JOURNAL_TRIGGER_COUNT OCFS2_JTR_NONE 307 + 308 + void ocfs2_initialize_journal_triggers(struct super_block *sb, 309 + struct ocfs2_triggers triggers[]); 310 + 287 311 struct ocfs2_journal; 288 312 struct ocfs2_slot_info; 289 313 struct ocfs2_recovery_map; ··· 374 350 wait_queue_head_t checkpoint_event; 375 351 struct ocfs2_journal *journal; 376 352 unsigned long osb_commit_interval; 353 + 354 + /* Journal triggers for checksum */ 355 + struct ocfs2_triggers s_journal_triggers[OCFS2_JOURNAL_TRIGGER_COUNT]; 377 356 378 357 struct delayed_work la_enable_wq; 379 358
+3 -1
fs/ocfs2/super.c
··· 1075 1075 debugfs_create_file("fs_state", S_IFREG|S_IRUSR, osb->osb_debug_root, 1076 1076 osb, &ocfs2_osb_debug_fops); 1077 1077 1078 - if (ocfs2_meta_ecc(osb)) 1078 + if (ocfs2_meta_ecc(osb)) { 1079 + ocfs2_initialize_journal_triggers(sb, osb->s_journal_triggers); 1079 1080 ocfs2_blockcheck_stats_debugfs_install( &osb->osb_ecc_stats, 1080 1081 osb->osb_debug_root); 1082 + } 1081 1083 1082 1084 status = ocfs2_mount_volume(sb); 1083 1085 if (status < 0)