]> git.ipfire.org Git - ipfire-2.x.git/blame - src/patches/suse-2.6.27.39/patches.fixes/reiserfs-debug-1036
Imported linux-2.6.27.39 suse/xen patches.
[ipfire-2.x.git] / src / patches / suse-2.6.27.39 / patches.fixes / reiserfs-debug-1036
CommitLineData
2cb7cef9
BS
1From: Jeff Mahoney <jeffm@suse.com>
2Subject: [PATCH] reiserfs: print more information when an empty journal list is encountered
3References: bnc#447406 bnc#399966
4Patch-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
9Signed-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;