add patch jbd2-improve-error-messages-for-inconsistent-jh
[ext4-patch-queue.git] / jbd2-improve-error-messages-for-inconsistent-jh
blob799122f410f482e3d27b67f377b2a619a8ab7354
1 jbd2: improve error messages for inconsistent journal heads
3 Fix up error messages printed when the transaction pointers in a
4 journal head are inconsistent.  This improves the error messages which
5 are printed when running xfstests generic/068 in data=journal mode.
6 See the bug report at: https://bugzilla.kernel.org/show_bug.cgi?id=60786
8 Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
10 ---
11  fs/ext4/ext4_jbd2.c   | 10 ++++++++++
12  fs/jbd2/transaction.c | 33 ++++++++++++++-------------------
13  2 files changed, 24 insertions(+), 19 deletions(-)
15 diff --git a/fs/ext4/ext4_jbd2.c b/fs/ext4/ext4_jbd2.c
16 index 3fe29de..c3fb607 100644
17 --- a/fs/ext4/ext4_jbd2.c
18 +++ b/fs/ext4/ext4_jbd2.c
19 @@ -259,6 +259,16 @@ int __ext4_handle_dirty_metadata(const char *where, unsigned int line,
20                 if (WARN_ON_ONCE(err)) {
21                         ext4_journal_abort_handle(where, line, __func__, bh,
22                                                   handle, err);
23 +                       if (inode == NULL) {
24 +                               pr_err("EXT4: jbd2_journal_dirty_metadata "
25 +                                      "failed: handle type %u started at "
26 +                                      "line %u, credits %u/%u, errcode %d",
27 +                                      handle->h_type,
28 +                                      handle->h_line_no,
29 +                                      handle->h_requested_credits,
30 +                                      handle->h_buffer_credits, err);
31 +                               return err;
32 +                       }
33                         ext4_error_inode(inode, where, line,
34                                          bh->b_blocknr,
35                                          "journal_dirty_metadata failed: "
36 diff --git a/fs/jbd2/transaction.c b/fs/jbd2/transaction.c
37 index d999b1f..38cfcf5 100644
38 --- a/fs/jbd2/transaction.c
39 +++ b/fs/jbd2/transaction.c
40 @@ -1313,7 +1313,7 @@ int jbd2_journal_dirty_metadata(handle_t *handle, struct buffer_head *bh)
41                              journal->j_running_transaction)) {
42                         printk(KERN_ERR "JBD2: %s: "
43                                "jh->b_transaction (%llu, %p, %u) != "
44 -                              "journal->j_running_transaction (%p, %u)",
45 +                              "journal->j_running_transaction (%p, %u)\n",
46                                journal->j_devname,
47                                (unsigned long long) bh->b_blocknr,
48                                jh->b_transaction,
49 @@ -1336,30 +1336,25 @@ int jbd2_journal_dirty_metadata(handle_t *handle, struct buffer_head *bh)
50          */
51         if (jh->b_transaction != transaction) {
52                 JBUFFER_TRACE(jh, "already on other transaction");
53 -               if (unlikely(jh->b_transaction !=
54 -                            journal->j_committing_transaction)) {
55 -                       printk(KERN_ERR "JBD2: %s: "
56 -                              "jh->b_transaction (%llu, %p, %u) != "
57 -                              "journal->j_committing_transaction (%p, %u)",
58 +               if (unlikely(((jh->b_transaction !=
59 +                              journal->j_committing_transaction)) ||
60 +                            (jh->b_next_transaction != transaction))) {
61 +                       printk(KERN_ERR "jbd2_journal_dirty_metadata: %s: "
62 +                              "bad jh for block %llu: "
63 +                              "transaction (%p, %u), "
64 +                              "jh->b_transaction (%p, %u), "
65 +                              "jh->b_next_transaction (%p, %u), jlist %u\n",
66                                journal->j_devname,
67                                (unsigned long long) bh->b_blocknr,
68 +                              transaction, transaction->t_tid,
69                                jh->b_transaction,
70 -                              jh->b_transaction ? jh->b_transaction->t_tid : 0,
71 -                              journal->j_committing_transaction,
72 -                              journal->j_committing_transaction ?
73 -                              journal->j_committing_transaction->t_tid : 0);
74 -                       ret = -EINVAL;
75 -               }
76 -               if (unlikely(jh->b_next_transaction != transaction)) {
77 -                       printk(KERN_ERR "JBD2: %s: "
78 -                              "jh->b_next_transaction (%llu, %p, %u) != "
79 -                              "transaction (%p, %u)",
80 -                              journal->j_devname,
81 -                              (unsigned long long) bh->b_blocknr,
82 +                              jh->b_transaction ?
83 +                              jh->b_transaction->t_tid : 0,
84                                jh->b_next_transaction,
85                                jh->b_next_transaction ?
86                                jh->b_next_transaction->t_tid : 0,
87 -                              transaction, transaction->t_tid);
88 +                              jh->b_jlist);
89 +                       WARN_ON(1);
90                         ret = -EINVAL;
91                 }
92                 /* And this case is illegal: we can't reuse another