]>
Commit | Line | Data |
---|---|---|
2cb7cef9 BS |
1 | From: Jeff Mahoney <jeffm@suse.com> |
2 | Subject: [PATCH] reiserfs: print more information when an empty journal list is encountered | |
3 | References: bnc#447406 bnc#399966 | |
4 | Patch-mainline: Never | |
5 | ||
6 | BNC#447406 describes a BUG() at fs/reiserfs/journal.c:1036. This patch | |
7 | dumps more information regarding the state of the list before failing. | |
8 | ||
9 | Signed-off-by: Jeff Mahoney <jeffm@suse.com> | |
10 | --- | |
11 | fs/reiserfs/journal.c | 21 ++++++++++++++++++++- | |
12 | fs/reiserfs/prints.c | 22 +++++++++++++++++++++- | |
13 | include/linux/reiserfs_fs_sb.h | 6 ++++++ | |
14 | 3 files changed, 47 insertions(+), 2 deletions(-) | |
15 | ||
16 | --- a/fs/reiserfs/journal.c | |
17 | +++ b/fs/reiserfs/journal.c | |
18 | @@ -82,6 +82,8 @@ static struct workqueue_struct *commit_w | |
19 | #define LIST_TOUCHED 1 | |
20 | #define LIST_DIRTY 2 | |
21 | #define LIST_COMMIT_PENDING 4 /* someone will commit this list */ | |
22 | +#define LIST_DEAD 8 | |
23 | +#define LIST_CURRENT 16 | |
24 | ||
25 | /* flags for do_journal_end */ | |
26 | #define FLUSH_ALL 1 /* flush commit and real blocks */ | |
27 | @@ -1031,6 +1033,14 @@ static int flush_commit_list(struct supe | |
28 | /* before we can put our commit blocks on disk, we have to make sure everyone older than | |
29 | ** us is on disk too | |
30 | */ | |
31 | + if (jl->j_len <= 0) { | |
32 | + reiserfs_warning(s, "journal-d1", "%j; " | |
33 | + "trans_id = %u; " | |
34 | + "journal->trans_id = %u; " | |
35 | + "oldest live jl->j_trans_id = %u\n", | |
36 | + jl, trans_id, journal->j_trans_id, | |
37 | + JOURNAL_LIST_ENTRY(journal->j_journal_list.next)->j_trans_id); | |
38 | + } | |
39 | BUG_ON(jl->j_len <= 0); | |
40 | BUG_ON(trans_id == journal->j_trans_id); | |
41 | ||
42 | @@ -1636,7 +1646,7 @@ static int flush_journal_list(struct sup | |
43 | jl->j_realblock = NULL; | |
44 | jl->j_commit_bh = NULL; | |
45 | jl->j_trans_id = 0; | |
46 | - jl->j_state = 0; | |
47 | + jl->j_state = LIST_DEAD; | |
48 | put_journal_list(s, jl); | |
49 | if (flushall) | |
50 | mutex_unlock(&journal->j_flush_mutex); | |
51 | @@ -2561,6 +2571,12 @@ static struct reiserfs_journal_list *all | |
52 | INIT_LIST_HEAD(&jl->j_bh_list); | |
53 | mutex_init(&jl->j_commit_mutex); | |
54 | SB_JOURNAL(s)->j_num_lists++; | |
55 | + jl->j_magic1 = 0xa5a5a5a5; | |
56 | + jl->j_magic2 = 0xb4b4b4b4; | |
57 | + jl->j_magic3 = 0xc3c3c3c3; | |
58 | + jl->j_magic4 = 0xd2d2d2d2; | |
59 | + jl->j_magic5 = 0xe1e1e1e1; | |
60 | + jl->j_magic6 = 0x96969696; | |
61 | get_journal_list(jl); | |
62 | return jl; | |
63 | } | |
64 | @@ -2824,6 +2840,7 @@ int journal_init(struct super_block *sb, | |
65 | ||
66 | journal->j_list_bitmap_index = 0; | |
67 | journal_list_init(sb); | |
68 | + journal->j_current_jl->j_state |= LIST_CURRENT; | |
69 | ||
70 | memset(journal->j_list_hash_table, 0, | |
71 | JOURNAL_HASH_SIZE * sizeof(struct reiserfs_journal_cnode *)); | |
72 | @@ -4162,6 +4179,8 @@ static int do_journal_end(struct reiserf | |
73 | */ | |
74 | ||
75 | journal->j_current_jl = alloc_journal_list(sb); | |
76 | + journal->j_current_jl->j_state |= LIST_CURRENT; | |
77 | + jl->j_state &= LIST_CURRENT; | |
78 | ||
79 | /* now it is safe to insert this transaction on the main list */ | |
80 | list_add_tail(&jl->j_list, &journal->j_journal_list); | |
81 | --- a/fs/reiserfs/prints.c | |
82 | +++ b/fs/reiserfs/prints.c | |
83 | @@ -157,13 +157,28 @@ static void sprintf_disk_child(char *buf | |
84 | dc_size(dc)); | |
85 | } | |
86 | ||
87 | +static void sprintf_journal_list(char *buf, struct reiserfs_journal_list *jl) | |
88 | +{ | |
89 | + sprintf(buf, "[j_start=%lu, j_state=%lu, j_len=%lu, j_nonzerolen=%d, " | |
90 | + "j_commit_left=%u, j_older_commits_done=%u, j_trans_id=%u, " | |
91 | + "j_timestamp=%ld, j_refcount=%d (%08x%08x%08x%08x%08x%08x)]", | |
92 | + jl->j_start, jl->j_state, jl->j_len, | |
93 | + atomic_read(&jl->j_nonzerolen), | |
94 | + atomic_read(&jl->j_commit_left), | |
95 | + atomic_read(&jl->j_older_commits_done), | |
96 | + jl->j_trans_id, jl->j_timestamp, jl->j_refcount, | |
97 | + jl->j_magic1, jl->j_magic2, jl->j_magic3, jl->j_magic4, | |
98 | + jl->j_magic5, jl->j_magic6); | |
99 | +} | |
100 | + | |
101 | static char *is_there_reiserfs_struct(char *fmt, int *what) | |
102 | { | |
103 | char *k = fmt; | |
104 | ||
105 | while ((k = strchr(k, '%')) != NULL) { | |
106 | if (k[1] == 'k' || k[1] == 'K' || k[1] == 'h' || k[1] == 't' || | |
107 | - k[1] == 'z' || k[1] == 'b' || k[1] == 'y' || k[1] == 'a') { | |
108 | + k[1] == 'z' || k[1] == 'b' || k[1] == 'y' || k[1] == 'a' || | |
109 | + k[1] == 'j') { | |
110 | *what = k[1]; | |
111 | break; | |
112 | } | |
113 | @@ -233,6 +248,11 @@ static void prepare_error_buf(const char | |
114 | va_arg(args, | |
115 | struct reiserfs_de_head *)); | |
116 | break; | |
117 | + case 'j': | |
118 | + sprintf_journal_list(p, | |
119 | + va_arg(args, | |
120 | + struct reiserfs_journal_list *)); | |
121 | + break; | |
122 | } | |
123 | ||
124 | p += strlen(p); | |
125 | --- a/include/linux/reiserfs_fs_sb.h | |
126 | +++ b/include/linux/reiserfs_fs_sb.h | |
127 | @@ -149,6 +149,12 @@ struct reiserfs_list_bitmap { | |
128 | ** and to make sure every real block in a transaction is on disk before allowing the log area | |
129 | ** to be overwritten */ | |
130 | struct reiserfs_journal_list { | |
131 | + unsigned int j_magic1; | |
132 | + unsigned int j_magic2; | |
133 | + unsigned int j_magic3; | |
134 | + unsigned int j_magic4; | |
135 | + unsigned int j_magic5; | |
136 | + unsigned int j_magic6; | |
137 | unsigned long j_start; | |
138 | unsigned long j_state; | |
139 | unsigned long j_len; |