]> git.ipfire.org Git - people/teissler/ipfire-2.x.git/blob - src/patches/suse-2.6.27.31/patches.fixes/reiserfs-debug-1036
Merge branch 'master' of git://git.ipfire.org/ipfire-2.x
[people/teissler/ipfire-2.x.git] / src / patches / suse-2.6.27.31 / patches.fixes / reiserfs-debug-1036
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;