#define EXT4_ENC_UTF8_12_1     1
 
+/* Types of ext4 journal triggers */
+enum ext4_journal_trigger_type {
+       EXT4_JTR_NONE   /* This must be the last entry for indexing to work! */
+};
+
+#define EXT4_JOURNAL_TRIGGER_COUNT EXT4_JTR_NONE
+
+struct ext4_journal_trigger {
+       struct jbd2_buffer_trigger_type tr_triggers;
+       struct super_block *sb;
+};
+
+static inline struct ext4_journal_trigger *EXT4_TRIGGER(
+                               struct jbd2_buffer_trigger_type *trigger)
+{
+       return container_of(trigger, struct ext4_journal_trigger, tr_triggers);
+}
+
 /*
  * fourth extended-fs super-block data in memory
  */
        struct mb_cache *s_ea_inode_cache;
        spinlock_t s_es_lock ____cacheline_aligned_in_smp;
 
+       /* Journal triggers for checksum computation */
+       struct ext4_journal_trigger s_journal_triggers[EXT4_JOURNAL_TRIGGER_COUNT];
+
        /* Ratelimit ext4 messages. */
        struct ratelimit_state s_err_ratelimit_state;
        struct ratelimit_state s_warning_ratelimit_state;
 int ext4_da_get_block_prep(struct inode *inode, sector_t iblock,
                           struct buffer_head *bh, int create);
 int ext4_walk_page_buffers(handle_t *handle,
+                          struct inode *inode,
                           struct buffer_head *head,
                           unsigned from,
                           unsigned to,
                           int *partial,
-                          int (*fn)(handle_t *handle,
+                          int (*fn)(handle_t *handle, struct inode *inode,
                                     struct buffer_head *bh));
-int do_journal_get_write_access(handle_t *handle,
+int do_journal_get_write_access(handle_t *handle, struct inode *inode,
                                struct buffer_head *bh);
 #define FALL_BACK_TO_NONDELALLOC 1
 #define CONVERT_INLINE_DATA     2
 
 }
 
 int __ext4_journal_get_write_access(const char *where, unsigned int line,
-                                   handle_t *handle, struct buffer_head *bh)
+                                   handle_t *handle, struct super_block *sb,
+                                   struct buffer_head *bh,
+                                   enum ext4_journal_trigger_type trigger_type)
 {
-       int err = 0;
+       int err;
 
        might_sleep();
 
 
        if (ext4_handle_valid(handle)) {
                err = jbd2_journal_get_write_access(handle, bh);
-               if (err)
+               if (err) {
                        ext4_journal_abort_handle(where, line, __func__, bh,
                                                  handle, err);
+                       return err;
+               }
        }
-       return err;
+       if (trigger_type == EXT4_JTR_NONE || !ext4_has_metadata_csum(sb))
+               return 0;
+       BUG_ON(trigger_type >= EXT4_JOURNAL_TRIGGER_COUNT);
+       jbd2_journal_set_triggers(bh,
+               &EXT4_SB(sb)->s_journal_triggers[trigger_type].tr_triggers);
+       return 0;
 }
 
 /*
 }
 
 int __ext4_journal_get_create_access(const char *where, unsigned int line,
-                               handle_t *handle, struct buffer_head *bh)
+                               handle_t *handle, struct super_block *sb,
+                               struct buffer_head *bh,
+                               enum ext4_journal_trigger_type trigger_type)
 {
-       int err = 0;
+       int err;
 
-       if (ext4_handle_valid(handle)) {
-               err = jbd2_journal_get_create_access(handle, bh);
-               if (err)
-                       ext4_journal_abort_handle(where, line, __func__,
-                                                 bh, handle, err);
+       if (!ext4_handle_valid(handle))
+               return 0;
+
+       err = jbd2_journal_get_create_access(handle, bh);
+       if (err) {
+               ext4_journal_abort_handle(where, line, __func__, bh, handle,
+                                         err);
+               return err;
        }
-       return err;
+       if (trigger_type == EXT4_JTR_NONE || !ext4_has_metadata_csum(sb))
+               return 0;
+       BUG_ON(trigger_type >= EXT4_JOURNAL_TRIGGER_COUNT);
+       jbd2_journal_set_triggers(bh,
+               &EXT4_SB(sb)->s_journal_triggers[trigger_type].tr_triggers);
+       return 0;
 }
 
 int __ext4_handle_dirty_metadata(const char *where, unsigned int line,
 
  * Wrapper functions with which ext4 calls into JBD.
  */
 int __ext4_journal_get_write_access(const char *where, unsigned int line,
-                                   handle_t *handle, struct buffer_head *bh);
+                                   handle_t *handle, struct super_block *sb,
+                                   struct buffer_head *bh,
+                                   enum ext4_journal_trigger_type trigger_type);
 
 int __ext4_forget(const char *where, unsigned int line, handle_t *handle,
                  int is_metadata, struct inode *inode,
                  struct buffer_head *bh, ext4_fsblk_t blocknr);
 
 int __ext4_journal_get_create_access(const char *where, unsigned int line,
-                               handle_t *handle, struct buffer_head *bh);
+                               handle_t *handle, struct super_block *sb,
+                               struct buffer_head *bh,
+                               enum ext4_journal_trigger_type trigger_type);
 
 int __ext4_handle_dirty_metadata(const char *where, unsigned int line,
                                 handle_t *handle, struct inode *inode,
                                 struct buffer_head *bh);
 
-#define ext4_journal_get_write_access(handle, bh) \
-       __ext4_journal_get_write_access(__func__, __LINE__, (handle), (bh))
+#define ext4_journal_get_write_access(handle, sb, bh, trigger_type) \
+       __ext4_journal_get_write_access(__func__, __LINE__, (handle), (sb), \
+                                       (bh), (trigger_type))
 #define ext4_forget(handle, is_metadata, inode, bh, block_nr) \
        __ext4_forget(__func__, __LINE__, (handle), (is_metadata), (inode), \
                      (bh), (block_nr))
-#define ext4_journal_get_create_access(handle, bh) \
-       __ext4_journal_get_create_access(__func__, __LINE__, (handle), (bh))
+#define ext4_journal_get_create_access(handle, sb, bh, trigger_type) \
+       __ext4_journal_get_create_access(__func__, __LINE__, (handle), (sb), \
+                                        (bh), (trigger_type))
 #define ext4_handle_dirty_metadata(handle, inode, bh) \
        __ext4_handle_dirty_metadata(__func__, __LINE__, (handle), (inode), \
                                     (bh))
 
        if (path->p_bh) {
                /* path points to block */
                BUFFER_TRACE(path->p_bh, "get_write_access");
-               return ext4_journal_get_write_access(handle, path->p_bh);
+               return ext4_journal_get_write_access(handle, inode->i_sb,
+                                                    path->p_bh, EXT4_JTR_NONE);
        }
        /* path points to leaf/index in inode body */
        /* we use in-core data, no need to protect them */
        }
        lock_buffer(bh);
 
-       err = ext4_journal_get_create_access(handle, bh);
+       err = ext4_journal_get_create_access(handle, inode->i_sb, bh,
+                                            EXT4_JTR_NONE);
        if (err)
                goto cleanup;
 
                }
                lock_buffer(bh);
 
-               err = ext4_journal_get_create_access(handle, bh);
+               err = ext4_journal_get_create_access(handle, inode->i_sb, bh,
+                                                    EXT4_JTR_NONE);
                if (err)
                        goto cleanup;
 
                return -ENOMEM;
        lock_buffer(bh);
 
-       err = ext4_journal_get_create_access(handle, bh);
+       err = ext4_journal_get_create_access(handle, inode->i_sb, bh,
+                                            EXT4_JTR_NONE);
        if (err) {
                unlock_buffer(bh);
                goto out;
 
        if (IS_ERR(handle))
                goto out;
        BUFFER_TRACE(sbi->s_sbh, "get_write_access");
-       err = ext4_journal_get_write_access(handle, sbi->s_sbh);
+       err = ext4_journal_get_write_access(handle, sb, sbi->s_sbh,
+                                           EXT4_JTR_NONE);
        if (err)
                goto out_journal;
        lock_buffer(sbi->s_sbh);
 
        }
 
        BUFFER_TRACE(bitmap_bh, "get_write_access");
-       fatal = ext4_journal_get_write_access(handle, bitmap_bh);
+       fatal = ext4_journal_get_write_access(handle, sb, bitmap_bh,
+                                             EXT4_JTR_NONE);
        if (fatal)
                goto error_return;
 
        gdp = ext4_get_group_desc(sb, block_group, &bh2);
        if (gdp) {
                BUFFER_TRACE(bh2, "get_write_access");
-               fatal = ext4_journal_get_write_access(handle, bh2);
+               fatal = ext4_journal_get_write_access(handle, sb, bh2,
+                                                     EXT4_JTR_NONE);
        }
        ext4_lock_group(sb, block_group);
        cleared = ext4_test_and_clear_bit(bit, bitmap_bh->b_data);
                        }
                }
                BUFFER_TRACE(inode_bitmap_bh, "get_write_access");
-               err = ext4_journal_get_write_access(handle, inode_bitmap_bh);
+               err = ext4_journal_get_write_access(handle, sb, inode_bitmap_bh,
+                                                   EXT4_JTR_NONE);
                if (err) {
                        ext4_std_error(sb, err);
                        goto out;
        }
 
        BUFFER_TRACE(group_desc_bh, "get_write_access");
-       err = ext4_journal_get_write_access(handle, group_desc_bh);
+       err = ext4_journal_get_write_access(handle, sb, group_desc_bh,
+                                           EXT4_JTR_NONE);
        if (err) {
                ext4_std_error(sb, err);
                goto out;
                        goto out;
                }
                BUFFER_TRACE(block_bitmap_bh, "get block bitmap access");
-               err = ext4_journal_get_write_access(handle, block_bitmap_bh);
+               err = ext4_journal_get_write_access(handle, sb, block_bitmap_bh,
+                                                   EXT4_JTR_NONE);
                if (err) {
                        brelse(block_bitmap_bh);
                        ext4_std_error(sb, err);
        num = sbi->s_itb_per_group - used_blks;
 
        BUFFER_TRACE(group_desc_bh, "get_write_access");
-       ret = ext4_journal_get_write_access(handle,
-                                           group_desc_bh);
+       ret = ext4_journal_get_write_access(handle, sb, group_desc_bh,
+                                           EXT4_JTR_NONE);
        if (ret)
                goto err_out;
 
 
                }
                lock_buffer(bh);
                BUFFER_TRACE(bh, "call get_create_access");
-               err = ext4_journal_get_create_access(handle, bh);
+               err = ext4_journal_get_create_access(handle, ar->inode->i_sb,
+                                                    bh, EXT4_JTR_NONE);
                if (err) {
                        unlock_buffer(bh);
                        goto failed;
         */
        if (where->bh) {
                BUFFER_TRACE(where->bh, "get_write_access");
-               err = ext4_journal_get_write_access(handle, where->bh);
+               err = ext4_journal_get_write_access(handle, ar->inode->i_sb,
+                                                   where->bh, EXT4_JTR_NONE);
                if (err)
                        goto err_out;
        }
                return ret;
        if (bh) {
                BUFFER_TRACE(bh, "retaking write access");
-               ret = ext4_journal_get_write_access(handle, bh);
+               ret = ext4_journal_get_write_access(handle, inode->i_sb, bh,
+                                                   EXT4_JTR_NONE);
                if (unlikely(ret))
                        return ret;
        }
 
        if (this_bh) {                          /* For indirect block */
                BUFFER_TRACE(this_bh, "get_write_access");
-               err = ext4_journal_get_write_access(handle, this_bh);
+               err = ext4_journal_get_write_access(handle, inode->i_sb,
+                                                   this_bh, EXT4_JTR_NONE);
                /* Important: if we can't update the indirect pointers
                 * to the blocks, we can't free them. */
                if (err)
                                 */
                                BUFFER_TRACE(parent_bh, "get_write_access");
                                if (!ext4_journal_get_write_access(handle,
-                                                                  parent_bh)){
+                                               inode->i_sb, parent_bh,
+                                               EXT4_JTR_NONE)) {
                                        *p = 0;
                                        BUFFER_TRACE(parent_bh,
                                        "call ext4_handle_dirty_metadata");
 
                return error;
 
        BUFFER_TRACE(is.iloc.bh, "get_write_access");
-       error = ext4_journal_get_write_access(handle, is.iloc.bh);
+       error = ext4_journal_get_write_access(handle, inode->i_sb, is.iloc.bh,
+                                             EXT4_JTR_NONE);
        if (error)
                goto out;
 
                goto out;
 
        BUFFER_TRACE(is.iloc.bh, "get_write_access");
-       error = ext4_journal_get_write_access(handle, is.iloc.bh);
+       error = ext4_journal_get_write_access(handle, inode->i_sb, is.iloc.bh,
+                                             EXT4_JTR_NONE);
        if (error)
                goto out;
 
                goto out;
 
        BUFFER_TRACE(is.iloc.bh, "get_write_access");
-       error = ext4_journal_get_write_access(handle, is.iloc.bh);
+       error = ext4_journal_get_write_access(handle, inode->i_sb, is.iloc.bh,
+                                             EXT4_JTR_NONE);
        if (error)
                goto out;
 
                ret = __block_write_begin(page, from, to, ext4_get_block);
 
        if (!ret && ext4_should_journal_data(inode)) {
-               ret = ext4_walk_page_buffers(handle, page_buffers(page),
+               ret = ext4_walk_page_buffers(handle, inode, page_buffers(page),
                                             from, to, NULL,
                                             do_journal_get_write_access);
        }
                goto convert;
        }
 
-       ret = ext4_journal_get_write_access(handle, iloc.bh);
+       ret = ext4_journal_get_write_access(handle, inode->i_sb, iloc.bh,
+                                           EXT4_JTR_NONE);
        if (ret)
                goto out;
 
                if (ret < 0)
                        goto out_release_page;
        }
-       ret = ext4_journal_get_write_access(handle, iloc.bh);
+       ret = ext4_journal_get_write_access(handle, inode->i_sb, iloc.bh,
+                                           EXT4_JTR_NONE);
        if (ret)
                goto out_release_page;
 
                return err;
 
        BUFFER_TRACE(iloc->bh, "get_write_access");
-       err = ext4_journal_get_write_access(handle, iloc->bh);
+       err = ext4_journal_get_write_access(handle, dir->i_sb, iloc->bh,
+                                           EXT4_JTR_NONE);
        if (err)
                return err;
        ext4_insert_dentry(dir, inode, de, inline_size, fname);
        }
 
        lock_buffer(data_bh);
-       error = ext4_journal_get_create_access(handle, data_bh);
+       error = ext4_journal_get_create_access(handle, inode->i_sb, data_bh,
+                                              EXT4_JTR_NONE);
        if (error) {
                unlock_buffer(data_bh);
                error = -EIO;
        }
 
        BUFFER_TRACE(bh, "get_write_access");
-       err = ext4_journal_get_write_access(handle, bh);
+       err = ext4_journal_get_write_access(handle, dir->i_sb, bh,
+                                           EXT4_JTR_NONE);
        if (err)
                goto out;
 
 
 static void ext4_invalidatepage(struct page *page, unsigned int offset,
                                unsigned int length);
 static int __ext4_journalled_writepage(struct page *page, unsigned int len);
-static int ext4_bh_delay_or_unwritten(handle_t *handle, struct buffer_head *bh);
 static int ext4_meta_trans_blocks(struct inode *inode, int lblocks,
                                  int pextents);
 
                 */
                lock_buffer(bh);
                BUFFER_TRACE(bh, "call get_create_access");
-               err = ext4_journal_get_create_access(handle, bh);
+               err = ext4_journal_get_create_access(handle, inode->i_sb, bh,
+                                                    EXT4_JTR_NONE);
                if (unlikely(err)) {
                        unlock_buffer(bh);
                        goto errout;
        return err;
 }
 
-int ext4_walk_page_buffers(handle_t *handle,
+int ext4_walk_page_buffers(handle_t *handle, struct inode *inode,
                           struct buffer_head *head,
                           unsigned from,
                           unsigned to,
                           int *partial,
-                          int (*fn)(handle_t *handle,
+                          int (*fn)(handle_t *handle, struct inode *inode,
                                     struct buffer_head *bh))
 {
        struct buffer_head *bh;
                                *partial = 1;
                        continue;
                }
-               err = (*fn)(handle, bh);
+               err = (*fn)(handle, inode, bh);
                if (!ret)
                        ret = err;
        }
  * is elevated.  We'll still have enough credits for the tiny quotafile
  * write.
  */
-int do_journal_get_write_access(handle_t *handle,
+int do_journal_get_write_access(handle_t *handle, struct inode *inode,
                                struct buffer_head *bh)
 {
        int dirty = buffer_dirty(bh);
        if (dirty)
                clear_buffer_dirty(bh);
        BUFFER_TRACE(bh, "get write access");
-       ret = ext4_journal_get_write_access(handle, bh);
+       ret = ext4_journal_get_write_access(handle, inode->i_sb, bh,
+                                           EXT4_JTR_NONE);
        if (!ret && dirty)
                ret = ext4_handle_dirty_metadata(handle, NULL, bh);
        return ret;
                ret = __block_write_begin(page, pos, len, ext4_get_block);
 #endif
        if (!ret && ext4_should_journal_data(inode)) {
-               ret = ext4_walk_page_buffers(handle, page_buffers(page),
-                                            from, to, NULL,
+               ret = ext4_walk_page_buffers(handle, inode,
+                                            page_buffers(page), from, to, NULL,
                                             do_journal_get_write_access);
        }
 
 }
 
 /* For write_end() in data=journal mode */
-static int write_end_fn(handle_t *handle, struct buffer_head *bh)
+static int write_end_fn(handle_t *handle, struct inode *inode,
+                       struct buffer_head *bh)
 {
        int ret;
        if (!buffer_mapped(bh) || buffer_freed(bh))
  * to call ext4_handle_dirty_metadata() instead.
  */
 static void ext4_journalled_zero_new_buffers(handle_t *handle,
+                                           struct inode *inode,
                                            struct page *page,
                                            unsigned from, unsigned to)
 {
                                        size = min(to, block_end) - start;
 
                                        zero_user(page, start, size);
-                                       write_end_fn(handle, bh);
+                                       write_end_fn(handle, inode, bh);
                                }
                                clear_buffer_new(bh);
                        }
                copied = ret;
        } else if (unlikely(copied < len) && !PageUptodate(page)) {
                copied = 0;
-               ext4_journalled_zero_new_buffers(handle, page, from, to);
+               ext4_journalled_zero_new_buffers(handle, inode, page, from, to);
        } else {
                if (unlikely(copied < len))
-                       ext4_journalled_zero_new_buffers(handle, page,
+                       ext4_journalled_zero_new_buffers(handle, inode, page,
                                                         from + copied, to);
-               ret = ext4_walk_page_buffers(handle, page_buffers(page), from,
-                                            from + copied, &partial,
+               ret = ext4_walk_page_buffers(handle, inode, page_buffers(page),
+                                            from, from + copied, &partial,
                                             write_end_fn);
                if (!partial)
                        SetPageUptodate(page);
        return;
 }
 
-static int ext4_bh_delay_or_unwritten(handle_t *handle, struct buffer_head *bh)
+static int ext4_bh_delay_or_unwritten(handle_t *handle, struct inode *inode,
+                                     struct buffer_head *bh)
 {
        return (buffer_delay(bh) || buffer_unwritten(bh)) && buffer_dirty(bh);
 }
        return 0;
 }
 
-static int bget_one(handle_t *handle, struct buffer_head *bh)
+static int bget_one(handle_t *handle, struct inode *inode,
+                   struct buffer_head *bh)
 {
        get_bh(bh);
        return 0;
 }
 
-static int bput_one(handle_t *handle, struct buffer_head *bh)
+static int bput_one(handle_t *handle, struct inode *inode,
+                   struct buffer_head *bh)
 {
        put_bh(bh);
        return 0;
                        BUG();
                        goto out;
                }
-               ext4_walk_page_buffers(handle, page_bufs, 0, len,
+               ext4_walk_page_buffers(handle, inode, page_bufs, 0, len,
                                       NULL, bget_one);
        }
        /*
        if (inline_data) {
                ret = ext4_mark_inode_dirty(handle, inode);
        } else {
-               ret = ext4_walk_page_buffers(handle, page_bufs, 0, len, NULL,
-                                            do_journal_get_write_access);
+               ret = ext4_walk_page_buffers(handle, inode, page_bufs, 0, len,
+                                            NULL, do_journal_get_write_access);
 
-               err = ext4_walk_page_buffers(handle, page_bufs, 0, len, NULL,
-                                            write_end_fn);
+               err = ext4_walk_page_buffers(handle, inode, page_bufs, 0, len,
+                                            NULL, write_end_fn);
        }
        if (ret == 0)
                ret = err;
        unlock_page(page);
 out_no_pagelock:
        if (!inline_data && page_bufs)
-               ext4_walk_page_buffers(NULL, page_bufs, 0, len,
+               ext4_walk_page_buffers(NULL, inode, page_bufs, 0, len,
                                       NULL, bput_one);
        brelse(inode_bh);
        return ret;
         * for the extremely common case, this is an optimization that
         * skips a useless round trip through ext4_bio_write_page().
         */
-       if (ext4_walk_page_buffers(NULL, page_bufs, 0, len, NULL,
+       if (ext4_walk_page_buffers(NULL, inode, page_bufs, 0, len, NULL,
                                   ext4_bh_delay_or_unwritten)) {
                redirty_page_for_writepage(wbc, page);
                if ((current->flags & PF_MEMALLOC) ||
        }
        if (ext4_should_journal_data(inode)) {
                BUFFER_TRACE(bh, "get write access");
-               err = ext4_journal_get_write_access(handle, bh);
+               err = ext4_journal_get_write_access(handle, inode->i_sb, bh,
+                                                   EXT4_JTR_NONE);
                if (err)
                        goto unlock;
        }
        ext4_clear_inode_state(inode, EXT4_STATE_NEW);
        if (set_large_file) {
                BUFFER_TRACE(EXT4_SB(sb)->s_sbh, "get write access");
-               err = ext4_journal_get_write_access(handle, EXT4_SB(sb)->s_sbh);
+               err = ext4_journal_get_write_access(handle, sb,
+                                                   EXT4_SB(sb)->s_sbh,
+                                                   EXT4_JTR_NONE);
                if (err)
                        goto out_brelse;
                lock_buffer(EXT4_SB(sb)->s_sbh);
        err = ext4_get_inode_loc(inode, iloc);
        if (!err) {
                BUFFER_TRACE(iloc->bh, "get_write_access");
-               err = ext4_journal_get_write_access(handle, iloc->bh);
+               err = ext4_journal_get_write_access(handle, inode->i_sb,
+                                                   iloc->bh, EXT4_JTR_NONE);
                if (err) {
                        brelse(iloc->bh);
                        iloc->bh = NULL;
        ext4_write_lock_xattr(inode, &no_expand);
 
        BUFFER_TRACE(iloc->bh, "get_write_access");
-       error = ext4_journal_get_write_access(handle, iloc->bh);
+       error = ext4_journal_get_write_access(handle, inode->i_sb, iloc->bh,
+                                             EXT4_JTR_NONE);
        if (error) {
                brelse(iloc->bh);
                goto out_unlock;
        return err;
 }
 
-static int ext4_bh_unmapped(handle_t *handle, struct buffer_head *bh)
+static int ext4_bh_unmapped(handle_t *handle, struct inode *inode,
+                           struct buffer_head *bh)
 {
        return !buffer_mapped(bh);
 }
         * inode to the transaction's list to writeprotect pages on commit.
         */
        if (page_has_buffers(page)) {
-               if (!ext4_walk_page_buffers(NULL, page_buffers(page),
+               if (!ext4_walk_page_buffers(NULL, inode, page_buffers(page),
                                            0, len, NULL,
                                            ext4_bh_unmapped)) {
                        /* Wait so that we don't change page under IO */
                err = __block_write_begin(page, 0, len, ext4_get_block);
                if (!err) {
                        ret = VM_FAULT_SIGBUS;
-                       if (ext4_walk_page_buffers(handle, page_buffers(page),
-                                       0, len, NULL, do_journal_get_write_access))
+                       if (ext4_walk_page_buffers(handle, inode,
+                                       page_buffers(page), 0, len, NULL,
+                                       do_journal_get_write_access))
                                goto out_error;
-                       if (ext4_walk_page_buffers(handle, page_buffers(page),
-                                       0, len, NULL, write_end_fn))
+                       if (ext4_walk_page_buffers(handle, inode,
+                                       page_buffers(page), 0, len, NULL,
+                                       write_end_fn))
                                goto out_error;
                        if (ext4_jbd2_inode_add_write(handle, inode,
                                                      page_offset(page), len))
 
                                err = PTR_ERR(handle);
                                goto pwsalt_err_exit;
                        }
-                       err = ext4_journal_get_write_access(handle, sbi->s_sbh);
+                       err = ext4_journal_get_write_access(handle, sb,
+                                                           sbi->s_sbh,
+                                                           EXT4_JTR_NONE);
                        if (err)
                                goto pwsalt_err_journal;
                        lock_buffer(sbi->s_sbh);
 
        }
 
        BUFFER_TRACE(bitmap_bh, "getting write access");
-       err = ext4_journal_get_write_access(handle, bitmap_bh);
+       err = ext4_journal_get_write_access(handle, sb, bitmap_bh,
+                                           EXT4_JTR_NONE);
        if (err)
                goto out_err;
 
                        ext4_free_group_clusters(sb, gdp));
 
        BUFFER_TRACE(gdp_bh, "get_write_access");
-       err = ext4_journal_get_write_access(handle, gdp_bh);
+       err = ext4_journal_get_write_access(handle, sb, gdp_bh, EXT4_JTR_NONE);
        if (err)
                goto out_err;
 
        }
 
        BUFFER_TRACE(bitmap_bh, "getting write access");
-       err = ext4_journal_get_write_access(handle, bitmap_bh);
+       err = ext4_journal_get_write_access(handle, sb, bitmap_bh,
+                                           EXT4_JTR_NONE);
        if (err)
                goto error_return;
 
         * using it
         */
        BUFFER_TRACE(gd_bh, "get_write_access");
-       err = ext4_journal_get_write_access(handle, gd_bh);
+       err = ext4_journal_get_write_access(handle, sb, gd_bh, EXT4_JTR_NONE);
        if (err)
                goto error_return;
 #ifdef AGGRESSIVE_CHECK
        }
 
        BUFFER_TRACE(bitmap_bh, "getting write access");
-       err = ext4_journal_get_write_access(handle, bitmap_bh);
+       err = ext4_journal_get_write_access(handle, sb, bitmap_bh,
+                                           EXT4_JTR_NONE);
        if (err)
                goto error_return;
 
         * using it
         */
        BUFFER_TRACE(gd_bh, "get_write_access");
-       err = ext4_journal_get_write_access(handle, gd_bh);
+       err = ext4_journal_get_write_access(handle, sb, gd_bh, EXT4_JTR_NONE);
        if (err)
                goto error_return;
 
 
        inode->i_size += inode->i_sb->s_blocksize;
        EXT4_I(inode)->i_disksize = inode->i_size;
        BUFFER_TRACE(bh, "get_write_access");
-       err = ext4_journal_get_write_access(handle, bh);
+       err = ext4_journal_get_write_access(handle, inode->i_sb, bh,
+                                           EXT4_JTR_NONE);
        if (err) {
                brelse(bh);
                ext4_std_error(inode->i_sb, err);
        }
 
        BUFFER_TRACE(*bh, "get_write_access");
-       err = ext4_journal_get_write_access(handle, *bh);
+       err = ext4_journal_get_write_access(handle, dir->i_sb, *bh,
+                                           EXT4_JTR_NONE);
        if (err)
                goto journal_error;
 
        BUFFER_TRACE(frame->bh, "get_write_access");
-       err = ext4_journal_get_write_access(handle, frame->bh);
+       err = ext4_journal_get_write_access(handle, dir->i_sb, frame->bh,
+                                           EXT4_JTR_NONE);
        if (err)
                goto journal_error;
 
                        return err;
        }
        BUFFER_TRACE(bh, "get_write_access");
-       err = ext4_journal_get_write_access(handle, bh);
+       err = ext4_journal_get_write_access(handle, dir->i_sb, bh,
+                                           EXT4_JTR_NONE);
        if (err) {
                ext4_std_error(dir->i_sb, err);
                return err;
        blocksize =  dir->i_sb->s_blocksize;
        dxtrace(printk(KERN_DEBUG "Creating index: inode %lu\n", dir->i_ino));
        BUFFER_TRACE(bh, "get_write_access");
-       retval = ext4_journal_get_write_access(handle, bh);
+       retval = ext4_journal_get_write_access(handle, dir->i_sb, bh,
+                                              EXT4_JTR_NONE);
        if (retval) {
                ext4_std_error(dir->i_sb, retval);
                brelse(bh);
        }
 
        BUFFER_TRACE(bh, "get_write_access");
-       err = ext4_journal_get_write_access(handle, bh);
+       err = ext4_journal_get_write_access(handle, sb, bh, EXT4_JTR_NONE);
        if (err)
                goto journal_error;
 
                node2->fake.rec_len = ext4_rec_len_to_disk(sb->s_blocksize,
                                                           sb->s_blocksize);
                BUFFER_TRACE(frame->bh, "get_write_access");
-               err = ext4_journal_get_write_access(handle, frame->bh);
+               err = ext4_journal_get_write_access(handle, sb, frame->bh,
+                                                   EXT4_JTR_NONE);
                if (err)
                        goto journal_error;
                if (!add_level) {
                                       icount1, icount2));
 
                        BUFFER_TRACE(frame->bh, "get_write_access"); /* index root */
-                       err = ext4_journal_get_write_access(handle,
-                                                            (frame - 1)->bh);
+                       err = ext4_journal_get_write_access(handle, sb,
+                                                           (frame - 1)->bh,
+                                                           EXT4_JTR_NONE);
                        if (err)
                                goto journal_error;
 
                csum_size = sizeof(struct ext4_dir_entry_tail);
 
        BUFFER_TRACE(bh, "get_write_access");
-       err = ext4_journal_get_write_access(handle, bh);
+       err = ext4_journal_get_write_access(handle, dir->i_sb, bh,
+                                           EXT4_JTR_NONE);
        if (unlikely(err))
                goto out;
 
                  S_ISLNK(inode->i_mode)) || inode->i_nlink == 0);
 
        BUFFER_TRACE(sbi->s_sbh, "get_write_access");
-       err = ext4_journal_get_write_access(handle, sbi->s_sbh);
+       err = ext4_journal_get_write_access(handle, sb, sbi->s_sbh,
+                                           EXT4_JTR_NONE);
        if (err)
                goto out;
 
        if (prev == &sbi->s_orphan) {
                jbd_debug(4, "superblock will point to %u\n", ino_next);
                BUFFER_TRACE(sbi->s_sbh, "get_write_access");
-               err = ext4_journal_get_write_access(handle, sbi->s_sbh);
+               err = ext4_journal_get_write_access(handle, inode->i_sb,
+                                                   sbi->s_sbh, EXT4_JTR_NONE);
                if (err) {
                        mutex_unlock(&sbi->s_orphan_lock);
                        goto out_brelse;
        if (le32_to_cpu(ent->parent_de->inode) != ent->dir->i_ino)
                return -EFSCORRUPTED;
        BUFFER_TRACE(ent->dir_bh, "get_write_access");
-       return ext4_journal_get_write_access(handle, ent->dir_bh);
+       return ext4_journal_get_write_access(handle, ent->dir->i_sb,
+                                            ent->dir_bh, EXT4_JTR_NONE);
 }
 
 static int ext4_rename_dir_finish(handle_t *handle, struct ext4_renament *ent,
        int retval, retval2;
 
        BUFFER_TRACE(ent->bh, "get write access");
-       retval = ext4_journal_get_write_access(handle, ent->bh);
+       retval = ext4_journal_get_write_access(handle, ent->dir->i_sb, ent->bh,
+                                              EXT4_JTR_NONE);
        if (retval)
                return retval;
        ent->de->inode = cpu_to_le32(ino);
 
        if (unlikely(!bh))
                return ERR_PTR(-ENOMEM);
        BUFFER_TRACE(bh, "get_write_access");
-       if ((err = ext4_journal_get_write_access(handle, bh))) {
+       err = ext4_journal_get_write_access(handle, sb, bh, EXT4_JTR_NONE);
+       if (err) {
                brelse(bh);
                bh = ERR_PTR(err);
        } else {
                        return -ENOMEM;
 
                BUFFER_TRACE(bh, "get_write_access");
-               err = ext4_journal_get_write_access(handle, bh);
+               err = ext4_journal_get_write_access(handle, sb, bh,
+                                                   EXT4_JTR_NONE);
                if (err) {
                        brelse(bh);
                        return err;
                        }
 
                        BUFFER_TRACE(gdb, "get_write_access");
-                       err = ext4_journal_get_write_access(handle, gdb);
+                       err = ext4_journal_get_write_access(handle, sb, gdb,
+                                                           EXT4_JTR_NONE);
                        if (err) {
                                brelse(gdb);
                                goto out;
        }
 
        BUFFER_TRACE(EXT4_SB(sb)->s_sbh, "get_write_access");
-       err = ext4_journal_get_write_access(handle, EXT4_SB(sb)->s_sbh);
+       err = ext4_journal_get_write_access(handle, sb, EXT4_SB(sb)->s_sbh,
+                                           EXT4_JTR_NONE);
        if (unlikely(err))
                goto errout;
 
        BUFFER_TRACE(gdb_bh, "get_write_access");
-       err = ext4_journal_get_write_access(handle, gdb_bh);
+       err = ext4_journal_get_write_access(handle, sb, gdb_bh, EXT4_JTR_NONE);
        if (unlikely(err))
                goto errout;
 
        BUFFER_TRACE(dind, "get_write_access");
-       err = ext4_journal_get_write_access(handle, dind);
+       err = ext4_journal_get_write_access(handle, sb, dind, EXT4_JTR_NONE);
        if (unlikely(err)) {
                ext4_std_error(sb, err);
                goto errout;
        n_group_desc[gdb_num] = gdb_bh;
 
        BUFFER_TRACE(gdb_bh, "get_write_access");
-       err = ext4_journal_get_write_access(handle, gdb_bh);
+       err = ext4_journal_get_write_access(handle, sb, gdb_bh, EXT4_JTR_NONE);
        if (err) {
                kvfree(n_group_desc);
                brelse(gdb_bh);
 
        for (i = 0; i < reserved_gdb; i++) {
                BUFFER_TRACE(primary[i], "get_write_access");
-               if ((err = ext4_journal_get_write_access(handle, primary[i])))
+               if ((err = ext4_journal_get_write_access(handle, sb, primary[i],
+                                                        EXT4_JTR_NONE)))
                        goto exit_bh;
        }
 
                           backup_block, backup_block -
                           ext4_group_first_block_no(sb, group));
                BUFFER_TRACE(bh, "get_write_access");
-               if ((err = ext4_journal_get_write_access(handle, bh))) {
-                       brelse(bh);
+               if ((err = ext4_journal_get_write_access(handle, sb, bh,
+                                                        EXT4_JTR_NONE)))
                        break;
-               }
                lock_buffer(bh);
                memcpy(bh->b_data, data, size);
                if (rest)
                        gdb_bh = sbi_array_rcu_deref(sbi, s_group_desc,
                                                     gdb_num);
                        BUFFER_TRACE(gdb_bh, "get_write_access");
-                       err = ext4_journal_get_write_access(handle, gdb_bh);
+                       err = ext4_journal_get_write_access(handle, sb, gdb_bh,
+                                                           EXT4_JTR_NONE);
 
                        if (!err && reserved_gdb && ext4_bg_num_gdb(sb, group))
                                err = reserve_backup_gdb(handle, resize_inode, group);
        }
 
        BUFFER_TRACE(sbi->s_sbh, "get_write_access");
-       err = ext4_journal_get_write_access(handle, sbi->s_sbh);
+       err = ext4_journal_get_write_access(handle, sb, sbi->s_sbh,
+                                           EXT4_JTR_NONE);
        if (err)
                goto exit_journal;
 
        }
 
        BUFFER_TRACE(EXT4_SB(sb)->s_sbh, "get_write_access");
-       err = ext4_journal_get_write_access(handle, EXT4_SB(sb)->s_sbh);
+       err = ext4_journal_get_write_access(handle, sb, EXT4_SB(sb)->s_sbh,
+                                           EXT4_JTR_NONE);
        if (err) {
                ext4_warning(sb, "error %d on journal write access", err);
                goto errout;
                return PTR_ERR(handle);
 
        BUFFER_TRACE(sbi->s_sbh, "get_write_access");
-       err = ext4_journal_get_write_access(handle, sbi->s_sbh);
+       err = ext4_journal_get_write_access(handle, sb, sbi->s_sbh,
+                                           EXT4_JTR_NONE);
        if (err)
                goto errout;
 
 
 #endif
 }
 
+static void ext4_setup_csum_trigger(struct super_block *sb,
+                                   enum ext4_journal_trigger_type type,
+                                   void (*trigger)(
+                                       struct jbd2_buffer_trigger_type *type,
+                                       struct buffer_head *bh,
+                                       void *mapped_data,
+                                       size_t size))
+{
+       struct ext4_sb_info *sbi = EXT4_SB(sb);
+
+       sbi->s_journal_triggers[type].sb = sb;
+       sbi->s_journal_triggers[type].tr_triggers.t_frozen = trigger;
+}
+
 static int ext4_fill_super(struct super_block *sb, void *data, int silent)
 {
        struct dax_device *dax_dev = fs_dax_get_by_bdev(sb->s_bdev);
        if (!bh)
                goto out;
        BUFFER_TRACE(bh, "get write access");
-       err = ext4_journal_get_write_access(handle, bh);
+       err = ext4_journal_get_write_access(handle, sb, bh, EXT4_JTR_NONE);
        if (err) {
                brelse(bh);
                return err;
 
                return;
 
        BUFFER_TRACE(EXT4_SB(sb)->s_sbh, "get_write_access");
-       if (ext4_journal_get_write_access(handle, EXT4_SB(sb)->s_sbh) == 0) {
+       if (ext4_journal_get_write_access(handle, sb, EXT4_SB(sb)->s_sbh,
+                                         EXT4_JTR_NONE) == 0) {
                lock_buffer(EXT4_SB(sb)->s_sbh);
                ext4_set_feature_xattr(sb);
                ext4_superblock_csum_set(sb);
                        continue;
                }
                if (err > 0) {
-                       err = ext4_journal_get_write_access(handle, bh);
+                       err = ext4_journal_get_write_access(handle,
+                                       parent->i_sb, bh, EXT4_JTR_NONE);
                        if (err) {
                                ext4_warning_inode(ea_inode,
                                                "Re-get write access err=%d",
        int error = 0;
 
        BUFFER_TRACE(bh, "get_write_access");
-       error = ext4_journal_get_write_access(handle, bh);
+       error = ext4_journal_get_write_access(handle, inode->i_sb, bh,
+                                             EXT4_JTR_NONE);
        if (error)
                goto out;
 
                                         "ext4_getblk() return bh = NULL");
                        return -EFSCORRUPTED;
                }
-               ret = ext4_journal_get_write_access(handle, bh);
+               ret = ext4_journal_get_write_access(handle, ea_inode->i_sb, bh,
+                                                  EXT4_JTR_NONE);
                if (ret)
                        goto out;
 
 
        if (s->base) {
                BUFFER_TRACE(bs->bh, "get_write_access");
-               error = ext4_journal_get_write_access(handle, bs->bh);
+               error = ext4_journal_get_write_access(handle, sb, bs->bh,
+                                                     EXT4_JTR_NONE);
                if (error)
                        goto cleanup;
                lock_buffer(bs->bh);
                                if (error)
                                        goto cleanup;
                                BUFFER_TRACE(new_bh, "get_write_access");
-                               error = ext4_journal_get_write_access(handle,
-                                                                     new_bh);
+                               error = ext4_journal_get_write_access(
+                                               handle, sb, new_bh,
+                                               EXT4_JTR_NONE);
                                if (error)
                                        goto cleanup_dquot;
                                lock_buffer(new_bh);
                        }
 
                        lock_buffer(new_bh);
-                       error = ext4_journal_get_create_access(handle, new_bh);
+                       error = ext4_journal_get_create_access(handle, sb,
+                                                       new_bh, EXT4_JTR_NONE);
                        if (error) {
                                unlock_buffer(new_bh);
                                error = -EIO;
                        goto cleanup;
                }
 
-               error = ext4_journal_get_write_access(handle, iloc.bh);
+               error = ext4_journal_get_write_access(handle, inode->i_sb,
+                                               iloc.bh, EXT4_JTR_NONE);
                if (error) {
                        EXT4_ERROR_INODE(inode, "write access (error %d)",
                                         error);
 
 {
        struct journal_head *jh = jbd2_journal_grab_journal_head(bh);
 
-       if (WARN_ON(!jh))
+       if (WARN_ON_ONCE(!jh))
                return;
        jh->b_triggers = type;
        jbd2_journal_put_journal_head(jh);