Chris Mason's patch to cope with io errors during journal replay. Fixes wrong behavior that caused reiserfs to panic during mount when hitting bad-block in the journal area. diff -rup linux-2.4.7-pre9/fs/reiserfs/journal.c linux-2.4.7-pre9.patched/fs/reiserfs/journal.c --- linux-2.4.7-pre9/fs/reiserfs/journal.c Fri Jul 20 15:02:19 2001 +++ linux-2.4.7-pre9.patched/fs/reiserfs/journal.c Fri Jul 20 14:59:07 2001 @@ -815,7 +815,7 @@ static void remove_all_from_journal_list ** called by flush_journal_list, before it calls remove_all_from_journal_list ** */ -static int update_journal_header_block(struct super_block *p_s_sb, unsigned long offset, unsigned long trans_id) { +static int _update_journal_header_block(struct super_block *p_s_sb, unsigned long offset, unsigned long trans_id) { struct reiserfs_journal_header *jh ; if (trans_id >= SB_JOURNAL(p_s_sb)->j_last_flush_trans_id) { if (buffer_locked((SB_JOURNAL(p_s_sb)->j_header_bh))) { @@ -834,12 +834,21 @@ static int update_journal_header_block(s ll_rw_block(WRITE, 1, &(SB_JOURNAL(p_s_sb)->j_header_bh)) ; wait_on_buffer((SB_JOURNAL(p_s_sb)->j_header_bh)) ; if (!buffer_uptodate(SB_JOURNAL(p_s_sb)->j_header_bh)) { - reiserfs_panic(p_s_sb, "journal-712: buffer write failed\n") ; + printk( "reiserfs: journal-837: IO error during journal replay\n" ); + return -EIO ; } } return 0 ; } +static int update_journal_header_block(struct super_block *p_s_sb, + unsigned long offset, + unsigned long trans_id) { + if (_update_journal_header_block(p_s_sb, offset, trans_id)) { + reiserfs_panic(p_s_sb, "journal-712: buffer write failed\n") ; + } + return 0 ; +} /* ** flush any and all journal lists older than you are ** can only be called from flush_journal_list @@ -1374,6 +1383,9 @@ static int journal_transaction_is_valid( struct buffer_head *c_bh ; unsigned long offset ; + if (!d_bh) + return 0 ; + desc = (struct reiserfs_journal_desc *)d_bh->b_data ; if (le32_to_cpu(desc->j_len) > 0 && !memcmp(desc->j_magic, JOURNAL_DESC_MAGIC, 8)) { if (oldest_invalid_trans_id && *oldest_invalid_trans_id && le32_to_cpu(desc->j_trans_id) > *oldest_invalid_trans_id) { @@ -1641,8 +1653,6 @@ static int journal_read(struct super_blo if (continue_replay && is_read_only(p_s_sb->s_dev)) { printk("clm-2076: device is readonly, unable to replay log\n") ; - brelse(SB_JOURNAL(p_s_sb)->j_header_bh) ; - SB_JOURNAL(p_s_sb)->j_header_bh = NULL ; return -1 ; } if (continue_replay && (p_s_sb->s_flags & MS_RDONLY)) { @@ -1734,9 +1744,14 @@ static int journal_read(struct super_blo printk("reiserfs: replayed %d transactions in %lu seconds\n", replay_count, CURRENT_TIME - start) ; } - if (!is_read_only(p_s_sb->s_dev)) { - update_journal_header_block(p_s_sb, SB_JOURNAL(p_s_sb)->j_start, - SB_JOURNAL(p_s_sb)->j_last_flush_trans_id) ; + if (!is_read_only(p_s_sb->s_dev) && + _update_journal_header_block(p_s_sb, SB_JOURNAL(p_s_sb)->j_start, + SB_JOURNAL(p_s_sb)->j_last_flush_trans_id)) + { + /* replay failed, caller must call free_journal_ram and abort + ** the mount + */ + return -1 ; } return 0 ; }