]>
Commit | Line | Data |
---|---|---|
1cbbdaac JR |
1 | Chris Mason's patch to cope with io errors during journal replay. |
2 | Fixes wrong behavior that caused reiserfs to panic during mount | |
3 | when hitting bad-block in the journal area. | |
4 | diff -rup linux-2.4.7-pre9/fs/reiserfs/journal.c linux-2.4.7-pre9.patched/fs/reiserfs/journal.c | |
5 | --- linux-2.4.7-pre9/fs/reiserfs/journal.c Fri Jul 20 15:02:19 2001 | |
6 | +++ linux-2.4.7-pre9.patched/fs/reiserfs/journal.c Fri Jul 20 14:59:07 2001 | |
7 | @@ -815,7 +815,7 @@ static void remove_all_from_journal_list | |
8 | ** called by flush_journal_list, before it calls remove_all_from_journal_list | |
9 | ** | |
10 | */ | |
11 | -static int update_journal_header_block(struct super_block *p_s_sb, unsigned long offset, unsigned long trans_id) { | |
12 | +static int _update_journal_header_block(struct super_block *p_s_sb, unsigned long offset, unsigned long trans_id) { | |
13 | struct reiserfs_journal_header *jh ; | |
14 | if (trans_id >= SB_JOURNAL(p_s_sb)->j_last_flush_trans_id) { | |
15 | if (buffer_locked((SB_JOURNAL(p_s_sb)->j_header_bh))) { | |
16 | @@ -834,12 +834,21 @@ static int update_journal_header_block(s | |
17 | ll_rw_block(WRITE, 1, &(SB_JOURNAL(p_s_sb)->j_header_bh)) ; | |
18 | wait_on_buffer((SB_JOURNAL(p_s_sb)->j_header_bh)) ; | |
19 | if (!buffer_uptodate(SB_JOURNAL(p_s_sb)->j_header_bh)) { | |
20 | - reiserfs_panic(p_s_sb, "journal-712: buffer write failed\n") ; | |
21 | + printk( "reiserfs: journal-837: IO error during journal replay\n" ); | |
22 | + return -EIO ; | |
23 | } | |
24 | } | |
25 | return 0 ; | |
26 | } | |
27 | ||
28 | +static int update_journal_header_block(struct super_block *p_s_sb, | |
29 | + unsigned long offset, | |
30 | + unsigned long trans_id) { | |
31 | + if (_update_journal_header_block(p_s_sb, offset, trans_id)) { | |
32 | + reiserfs_panic(p_s_sb, "journal-712: buffer write failed\n") ; | |
33 | + } | |
34 | + return 0 ; | |
35 | +} | |
36 | /* | |
37 | ** flush any and all journal lists older than you are | |
38 | ** can only be called from flush_journal_list | |
39 | @@ -1374,6 +1383,9 @@ static int journal_transaction_is_valid( | |
40 | struct buffer_head *c_bh ; | |
41 | unsigned long offset ; | |
42 | ||
43 | + if (!d_bh) | |
44 | + return 0 ; | |
45 | + | |
46 | desc = (struct reiserfs_journal_desc *)d_bh->b_data ; | |
47 | if (le32_to_cpu(desc->j_len) > 0 && !memcmp(desc->j_magic, JOURNAL_DESC_MAGIC, 8)) { | |
48 | if (oldest_invalid_trans_id && *oldest_invalid_trans_id && le32_to_cpu(desc->j_trans_id) > *oldest_invalid_trans_id) { | |
49 | @@ -1641,8 +1653,6 @@ static int journal_read(struct super_blo | |
50 | ||
51 | if (continue_replay && is_read_only(p_s_sb->s_dev)) { | |
52 | printk("clm-2076: device is readonly, unable to replay log\n") ; | |
53 | - brelse(SB_JOURNAL(p_s_sb)->j_header_bh) ; | |
54 | - SB_JOURNAL(p_s_sb)->j_header_bh = NULL ; | |
55 | return -1 ; | |
56 | } | |
57 | if (continue_replay && (p_s_sb->s_flags & MS_RDONLY)) { | |
58 | @@ -1734,9 +1744,14 @@ static int journal_read(struct super_blo | |
59 | printk("reiserfs: replayed %d transactions in %lu seconds\n", replay_count, | |
60 | CURRENT_TIME - start) ; | |
61 | } | |
62 | - if (!is_read_only(p_s_sb->s_dev)) { | |
63 | - update_journal_header_block(p_s_sb, SB_JOURNAL(p_s_sb)->j_start, | |
64 | - SB_JOURNAL(p_s_sb)->j_last_flush_trans_id) ; | |
65 | + if (!is_read_only(p_s_sb->s_dev) && | |
66 | + _update_journal_header_block(p_s_sb, SB_JOURNAL(p_s_sb)->j_start, | |
67 | + SB_JOURNAL(p_s_sb)->j_last_flush_trans_id)) | |
68 | + { | |
69 | + /* replay failed, caller must call free_journal_ram and abort | |
70 | + ** the mount | |
71 | + */ | |
72 | + return -1 ; | |
73 | } | |
74 | return 0 ; | |
75 | } |