struct ratelimit_state s_warning_ratelimit_state;
        struct ratelimit_state s_msg_ratelimit_state;
 
-       /* Barrier between changing inodes' journal flags and writepages ops. */
+       /*
+        * Barrier between writepages ops and changing any inode's JOURNAL_DATA
+        * or EXTENTS flag.
+        */
        struct percpu_rw_semaphore s_writepages_rwsem;
        struct dax_device *s_daxdev;
 #ifdef CONFIG_EXT4_DEBUG
 
 
 int ext4_ext_migrate(struct inode *inode)
 {
+       struct ext4_sb_info *sbi = EXT4_SB(inode->i_sb);
        handle_t *handle;
        int retval = 0, i;
        __le32 *i_data;
                 */
                return retval;
 
+       percpu_down_write(&sbi->s_writepages_rwsem);
+
        /*
         * Worst case we can touch the allocation bitmaps, a bgd
         * block, and a block to link in the orphan list.  We do need
 
        if (IS_ERR(handle)) {
                retval = PTR_ERR(handle);
-               return retval;
+               goto out_unlock;
        }
        goal = (((inode->i_ino - 1) / EXT4_INODES_PER_GROUP(inode->i_sb)) *
                EXT4_INODES_PER_GROUP(inode->i_sb)) + 1;
        if (IS_ERR(tmp_inode)) {
                retval = PTR_ERR(tmp_inode);
                ext4_journal_stop(handle);
-               return retval;
+               goto out_unlock;
        }
        i_size_write(tmp_inode, i_size_read(inode));
        /*
                 */
                ext4_orphan_del(NULL, tmp_inode);
                retval = PTR_ERR(handle);
-               goto out;
+               goto out_tmp_inode;
        }
 
        ei = EXT4_I(inode);
        ext4_ext_tree_init(handle, tmp_inode);
 out_stop:
        ext4_journal_stop(handle);
-out:
+out_tmp_inode:
        unlock_new_inode(tmp_inode);
        iput(tmp_inode);
-
+out_unlock:
+       percpu_up_write(&sbi->s_writepages_rwsem);
        return retval;
 }
 
 int ext4_ind_migrate(struct inode *inode)
 {
        struct ext4_extent_header       *eh;
-       struct ext4_super_block         *es = EXT4_SB(inode->i_sb)->s_es;
+       struct ext4_sb_info             *sbi = EXT4_SB(inode->i_sb);
+       struct ext4_super_block         *es = sbi->s_es;
        struct ext4_inode_info          *ei = EXT4_I(inode);
        struct ext4_extent              *ex;
        unsigned int                    i, len;
        if (test_opt(inode->i_sb, DELALLOC))
                ext4_alloc_da_blocks(inode);
 
+       percpu_down_write(&sbi->s_writepages_rwsem);
+
        handle = ext4_journal_start(inode, EXT4_HT_MIGRATE, 1);
-       if (IS_ERR(handle))
-               return PTR_ERR(handle);
+       if (IS_ERR(handle)) {
+               ret = PTR_ERR(handle);
+               goto out_unlock;
+       }
 
        down_write(&EXT4_I(inode)->i_data_sem);
        ret = ext4_ext_check_inode(inode);
 errout:
        ext4_journal_stop(handle);
        up_write(&EXT4_I(inode)->i_data_sem);
+out_unlock:
+       percpu_up_write(&sbi->s_writepages_rwsem);
        return ret;
 }