*  - ENOMEM
  *  - EIO
  */
-static int ext4_ext_dirty(handle_t *handle, struct inode *inode,
-                               struct ext4_ext_path *path)
+#define ext4_ext_dirty(handle, inode, path) \
+               __ext4_ext_dirty(__func__, __LINE__, (handle), (inode), (path))
+static int __ext4_ext_dirty(const char *where, unsigned int line,
+                           handle_t *handle, struct inode *inode,
+                           struct ext4_ext_path *path)
 {
        int err;
        if (path->p_bh) {
                /* path points to block */
-               err = ext4_handle_dirty_metadata(handle, inode, path->p_bh);
+               err = __ext4_handle_dirty_metadata(where, line, handle,
+                                                  inode, path->p_bh);
        } else {
                /* path points to leaf/index in inode body */
                err = ext4_mark_inode_dirty(handle, inode);
 
  * mark dirty metadata which needs to be journaled as part of the current
  * transaction.
  *
+ * The buffer must have previously had jbd2_journal_get_write_access()
+ * called so that it has a valid journal_head attached to the buffer
+ * head.
+ *
  * The buffer is placed on the transaction's metadata list and is marked
  * as belonging to the transaction.
  *
        transaction_t *transaction = handle->h_transaction;
        journal_t *journal = transaction->t_journal;
        struct journal_head *jh = bh2jh(bh);
+       int ret = 0;
 
        jbd_debug(5, "journal_head %p\n", jh);
        JBUFFER_TRACE(jh, "entry");
        if (is_handle_aborted(handle))
                goto out;
+       if (!buffer_jbd(bh)) {
+               ret = -EUCLEAN;
+               goto out;
+       }
 
        jbd_lock_bh_state(bh);
 
         */
        if (jh->b_transaction == transaction && jh->b_jlist == BJ_Metadata) {
                JBUFFER_TRACE(jh, "fastpath");
-               J_ASSERT_JH(jh, jh->b_transaction ==
-                                       journal->j_running_transaction);
+               if (unlikely(jh->b_transaction !=
+                            journal->j_running_transaction)) {
+                       printk(KERN_EMERG "JBD: %s: "
+                              "jh->b_transaction (%llu, %p, %u) != "
+                              "journal->j_running_transaction (%p, %u)",
+                              journal->j_devname,
+                              (unsigned long long) bh->b_blocknr,
+                              jh->b_transaction,
+                              jh->b_transaction ? jh->b_transaction->t_tid : 0,
+                              journal->j_running_transaction,
+                              journal->j_running_transaction ?
+                              journal->j_running_transaction->t_tid : 0);
+                       ret = -EINVAL;
+               }
                goto out_unlock_bh;
        }
 
         */
        if (jh->b_transaction != transaction) {
                JBUFFER_TRACE(jh, "already on other transaction");
-               J_ASSERT_JH(jh, jh->b_transaction ==
-                                       journal->j_committing_transaction);
-               J_ASSERT_JH(jh, jh->b_next_transaction == transaction);
+               if (unlikely(jh->b_transaction !=
+                            journal->j_committing_transaction)) {
+                       printk(KERN_EMERG "JBD: %s: "
+                              "jh->b_transaction (%llu, %p, %u) != "
+                              "journal->j_committing_transaction (%p, %u)",
+                              journal->j_devname,
+                              (unsigned long long) bh->b_blocknr,
+                              jh->b_transaction,
+                              jh->b_transaction ? jh->b_transaction->t_tid : 0,
+                              journal->j_committing_transaction,
+                              journal->j_committing_transaction ?
+                              journal->j_committing_transaction->t_tid : 0);
+                       ret = -EINVAL;
+               }
+               if (unlikely(jh->b_next_transaction != transaction)) {
+                       printk(KERN_EMERG "JBD: %s: "
+                              "jh->b_next_transaction (%llu, %p, %u) != "
+                              "transaction (%p, %u)",
+                              journal->j_devname,
+                              (unsigned long long) bh->b_blocknr,
+                              jh->b_next_transaction,
+                              jh->b_next_transaction ?
+                              jh->b_next_transaction->t_tid : 0,
+                              transaction, transaction->t_tid);
+                       ret = -EINVAL;
+               }
                /* And this case is illegal: we can't reuse another
                 * transaction's data buffer, ever. */
                goto out_unlock_bh;
        jbd_unlock_bh_state(bh);
 out:
        JBUFFER_TRACE(jh, "exit");
-       return 0;
+       if (ret)
+               __WARN();       /* All errors are bugs, so dump the stack */
+       return ret;
 }
 
 /*