These changes are the raw update to linux-4.4.6-rt14. Kernel sources
[kvmfornfv.git] / kernel / fs / ext4 / move_extent.c
index 370420b..e032a04 100644 (file)
@@ -166,12 +166,9 @@ mext_page_double_lock(struct inode *inode1, struct inode *inode2,
         */
        wait_on_page_writeback(page[0]);
        wait_on_page_writeback(page[1]);
-       if (inode1 > inode2) {
-               struct page *tmp;
-               tmp = page[0];
-               page[0] = page[1];
-               page[1] = tmp;
-       }
+       if (inode1 > inode2)
+               swap(page[0], page[1]);
+
        return 0;
 }
 
@@ -268,11 +265,12 @@ move_extent_per_page(struct file *o_filp, struct inode *donor_inode,
        ext4_lblk_t orig_blk_offset, donor_blk_offset;
        unsigned long blocksize = orig_inode->i_sb->s_blocksize;
        unsigned int tmp_data_size, data_size, replaced_size;
-       int err2, jblocks, retries = 0;
+       int i, err2, jblocks, retries = 0;
        int replaced_count = 0;
        int from = data_offset_in_page << orig_inode->i_blkbits;
        int blocks_per_page = PAGE_CACHE_SIZE >> orig_inode->i_blkbits;
        struct super_block *sb = orig_inode->i_sb;
+       struct buffer_head *bh = NULL;
 
        /*
         * It needs twice the amount of ordinary journal buffers because
@@ -383,8 +381,16 @@ data_copy:
        }
        /* Perform all necessary steps similar write_begin()/write_end()
         * but keeping in mind that i_size will not change */
-       *err = __block_write_begin(pagep[0], from, replaced_size,
-                                  ext4_get_block);
+       if (!page_has_buffers(pagep[0]))
+               create_empty_buffers(pagep[0], 1 << orig_inode->i_blkbits, 0);
+       bh = page_buffers(pagep[0]);
+       for (i = 0; i < data_offset_in_page; i++)
+               bh = bh->b_this_page;
+       for (i = 0; i < block_len_in_page; i++) {
+               *err = ext4_get_block(orig_inode, orig_blk_offset + i, bh, 0);
+               if (*err < 0)
+                       break;
+       }
        if (!*err)
                *err = block_commit_write(pagep[0], from, from + replaced_size);
 
@@ -574,12 +580,16 @@ ext4_move_extents(struct file *o_filp, struct file *d_filp, __u64 orig_blk,
                        orig_inode->i_ino, donor_inode->i_ino);
                return -EINVAL;
        }
-       /* TODO: This is non obvious task to swap blocks for inodes with full
-          jornaling enabled */
+
+       /* TODO: it's not obvious how to swap blocks for inodes with full
+          journaling enabled */
        if (ext4_should_journal_data(orig_inode) ||
            ext4_should_journal_data(donor_inode)) {
-               return -EINVAL;
+               ext4_msg(orig_inode->i_sb, KERN_ERR,
+                        "Online defrag not supported with data journaling");
+               return -EOPNOTSUPP;
        }
+
        /* Protect orig and donor inodes against a truncate */
        lock_two_nondirectories(orig_inode, donor_inode);