aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ext4/move_extent.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/ext4/move_extent.c')
-rw-r--r--fs/ext4/move_extent.c282
1 files changed, 133 insertions, 149 deletions
diff --git a/fs/ext4/move_extent.c b/fs/ext4/move_extent.c
index 25b6b1457360..82c415be87a4 100644
--- a/fs/ext4/move_extent.c
+++ b/fs/ext4/move_extent.c
@@ -77,12 +77,14 @@ static int
77mext_next_extent(struct inode *inode, struct ext4_ext_path *path, 77mext_next_extent(struct inode *inode, struct ext4_ext_path *path,
78 struct ext4_extent **extent) 78 struct ext4_extent **extent)
79{ 79{
80 struct ext4_extent_header *eh;
80 int ppos, leaf_ppos = path->p_depth; 81 int ppos, leaf_ppos = path->p_depth;
81 82
82 ppos = leaf_ppos; 83 ppos = leaf_ppos;
83 if (EXT_LAST_EXTENT(path[ppos].p_hdr) > path[ppos].p_ext) { 84 if (EXT_LAST_EXTENT(path[ppos].p_hdr) > path[ppos].p_ext) {
84 /* leaf block */ 85 /* leaf block */
85 *extent = ++path[ppos].p_ext; 86 *extent = ++path[ppos].p_ext;
87 path[ppos].p_block = ext_pblock(path[ppos].p_ext);
86 return 0; 88 return 0;
87 } 89 }
88 90
@@ -119,9 +121,18 @@ mext_next_extent(struct inode *inode, struct ext4_ext_path *path,
119 ext_block_hdr(path[cur_ppos+1].p_bh); 121 ext_block_hdr(path[cur_ppos+1].p_bh);
120 } 122 }
121 123
124 path[leaf_ppos].p_ext = *extent = NULL;
125
126 eh = path[leaf_ppos].p_hdr;
127 if (le16_to_cpu(eh->eh_entries) == 0)
128 /* empty leaf is found */
129 return -ENODATA;
130
122 /* leaf block */ 131 /* leaf block */
123 path[leaf_ppos].p_ext = *extent = 132 path[leaf_ppos].p_ext = *extent =
124 EXT_FIRST_EXTENT(path[leaf_ppos].p_hdr); 133 EXT_FIRST_EXTENT(path[leaf_ppos].p_hdr);
134 path[leaf_ppos].p_block =
135 ext_pblock(path[leaf_ppos].p_ext);
125 return 0; 136 return 0;
126 } 137 }
127 } 138 }
@@ -155,40 +166,15 @@ mext_check_null_inode(struct inode *inode1, struct inode *inode2,
155} 166}
156 167
157/** 168/**
158 * mext_double_down_read - Acquire two inodes' read semaphore 169 * double_down_write_data_sem - Acquire two inodes' write lock of i_data_sem
159 *
160 * @orig_inode: original inode structure
161 * @donor_inode: donor inode structure
162 * Acquire read semaphore of the two inodes (orig and donor) by i_ino order.
163 */
164static void
165mext_double_down_read(struct inode *orig_inode, struct inode *donor_inode)
166{
167 struct inode *first = orig_inode, *second = donor_inode;
168
169 /*
170 * Use the inode number to provide the stable locking order instead
171 * of its address, because the C language doesn't guarantee you can
172 * compare pointers that don't come from the same array.
173 */
174 if (donor_inode->i_ino < orig_inode->i_ino) {
175 first = donor_inode;
176 second = orig_inode;
177 }
178
179 down_read(&EXT4_I(first)->i_data_sem);
180 down_read(&EXT4_I(second)->i_data_sem);
181}
182
183/**
184 * mext_double_down_write - Acquire two inodes' write semaphore
185 * 170 *
186 * @orig_inode: original inode structure 171 * @orig_inode: original inode structure
187 * @donor_inode: donor inode structure 172 * @donor_inode: donor inode structure
188 * Acquire write semaphore of the two inodes (orig and donor) by i_ino order. 173 * Acquire write lock of i_data_sem of the two inodes (orig and donor) by
174 * i_ino order.
189 */ 175 */
190static void 176static void
191mext_double_down_write(struct inode *orig_inode, struct inode *donor_inode) 177double_down_write_data_sem(struct inode *orig_inode, struct inode *donor_inode)
192{ 178{
193 struct inode *first = orig_inode, *second = donor_inode; 179 struct inode *first = orig_inode, *second = donor_inode;
194 180
@@ -203,32 +189,18 @@ mext_double_down_write(struct inode *orig_inode, struct inode *donor_inode)
203 } 189 }
204 190
205 down_write(&EXT4_I(first)->i_data_sem); 191 down_write(&EXT4_I(first)->i_data_sem);
206 down_write(&EXT4_I(second)->i_data_sem); 192 down_write_nested(&EXT4_I(second)->i_data_sem, SINGLE_DEPTH_NESTING);
207} 193}
208 194
209/** 195/**
210 * mext_double_up_read - Release two inodes' read semaphore 196 * double_up_write_data_sem - Release two inodes' write lock of i_data_sem
211 * 197 *
212 * @orig_inode: original inode structure to be released its lock first 198 * @orig_inode: original inode structure to be released its lock first
213 * @donor_inode: donor inode structure to be released its lock second 199 * @donor_inode: donor inode structure to be released its lock second
214 * Release read semaphore of two inodes (orig and donor). 200 * Release write lock of i_data_sem of two inodes (orig and donor).
215 */ 201 */
216static void 202static void
217mext_double_up_read(struct inode *orig_inode, struct inode *donor_inode) 203double_up_write_data_sem(struct inode *orig_inode, struct inode *donor_inode)
218{
219 up_read(&EXT4_I(orig_inode)->i_data_sem);
220 up_read(&EXT4_I(donor_inode)->i_data_sem);
221}
222
223/**
224 * mext_double_up_write - Release two inodes' write semaphore
225 *
226 * @orig_inode: original inode structure to be released its lock first
227 * @donor_inode: donor inode structure to be released its lock second
228 * Release write semaphore of two inodes (orig and donor).
229 */
230static void
231mext_double_up_write(struct inode *orig_inode, struct inode *donor_inode)
232{ 204{
233 up_write(&EXT4_I(orig_inode)->i_data_sem); 205 up_write(&EXT4_I(orig_inode)->i_data_sem);
234 up_write(&EXT4_I(donor_inode)->i_data_sem); 206 up_write(&EXT4_I(donor_inode)->i_data_sem);
@@ -596,7 +568,7 @@ out:
596 * @tmp_oext: the extent that will belong to the donor inode 568 * @tmp_oext: the extent that will belong to the donor inode
597 * @orig_off: block offset of original inode 569 * @orig_off: block offset of original inode
598 * @donor_off: block offset of donor inode 570 * @donor_off: block offset of donor inode
599 * @max_count: the maximun length of extents 571 * @max_count: the maximum length of extents
600 * 572 *
601 * Return 0 on success, or a negative error value on failure. 573 * Return 0 on success, or a negative error value on failure.
602 */ 574 */
@@ -661,6 +633,7 @@ mext_calc_swap_extents(struct ext4_extent *tmp_dext,
661 * @donor_inode: donor inode 633 * @donor_inode: donor inode
662 * @from: block offset of orig_inode 634 * @from: block offset of orig_inode
663 * @count: block count to be replaced 635 * @count: block count to be replaced
636 * @err: pointer to save return value
664 * 637 *
665 * Replace original inode extents and donor inode extents page by page. 638 * Replace original inode extents and donor inode extents page by page.
666 * We implement this replacement in the following three steps: 639 * We implement this replacement in the following three steps:
@@ -671,33 +644,33 @@ mext_calc_swap_extents(struct ext4_extent *tmp_dext,
671 * 3. Change the block information of donor inode to point at the saved 644 * 3. Change the block information of donor inode to point at the saved
672 * original inode blocks in the dummy extents. 645 * original inode blocks in the dummy extents.
673 * 646 *
674 * Return 0 on success, or a negative error value on failure. 647 * Return replaced block count.
675 */ 648 */
676static int 649static int
677mext_replace_branches(handle_t *handle, struct inode *orig_inode, 650mext_replace_branches(handle_t *handle, struct inode *orig_inode,
678 struct inode *donor_inode, ext4_lblk_t from, 651 struct inode *donor_inode, ext4_lblk_t from,
679 ext4_lblk_t count) 652 ext4_lblk_t count, int *err)
680{ 653{
681 struct ext4_ext_path *orig_path = NULL; 654 struct ext4_ext_path *orig_path = NULL;
682 struct ext4_ext_path *donor_path = NULL; 655 struct ext4_ext_path *donor_path = NULL;
683 struct ext4_extent *oext, *dext; 656 struct ext4_extent *oext, *dext;
684 struct ext4_extent tmp_dext, tmp_oext; 657 struct ext4_extent tmp_dext, tmp_oext;
685 ext4_lblk_t orig_off = from, donor_off = from; 658 ext4_lblk_t orig_off = from, donor_off = from;
686 int err = 0;
687 int depth; 659 int depth;
688 int replaced_count = 0; 660 int replaced_count = 0;
689 int dext_alen; 661 int dext_alen;
690 662
691 mext_double_down_write(orig_inode, donor_inode); 663 /* Protect extent trees against block allocations via delalloc */
664 double_down_write_data_sem(orig_inode, donor_inode);
692 665
693 /* Get the original extent for the block "orig_off" */ 666 /* Get the original extent for the block "orig_off" */
694 err = get_ext_path(orig_inode, orig_off, &orig_path); 667 *err = get_ext_path(orig_inode, orig_off, &orig_path);
695 if (err) 668 if (*err)
696 goto out; 669 goto out;
697 670
698 /* Get the donor extent for the head */ 671 /* Get the donor extent for the head */
699 err = get_ext_path(donor_inode, donor_off, &donor_path); 672 *err = get_ext_path(donor_inode, donor_off, &donor_path);
700 if (err) 673 if (*err)
701 goto out; 674 goto out;
702 depth = ext_depth(orig_inode); 675 depth = ext_depth(orig_inode);
703 oext = orig_path[depth].p_ext; 676 oext = orig_path[depth].p_ext;
@@ -707,9 +680,9 @@ mext_replace_branches(handle_t *handle, struct inode *orig_inode,
707 dext = donor_path[depth].p_ext; 680 dext = donor_path[depth].p_ext;
708 tmp_dext = *dext; 681 tmp_dext = *dext;
709 682
710 err = mext_calc_swap_extents(&tmp_dext, &tmp_oext, orig_off, 683 *err = mext_calc_swap_extents(&tmp_dext, &tmp_oext, orig_off,
711 donor_off, count); 684 donor_off, count);
712 if (err) 685 if (*err)
713 goto out; 686 goto out;
714 687
715 /* Loop for the donor extents */ 688 /* Loop for the donor extents */
@@ -718,7 +691,7 @@ mext_replace_branches(handle_t *handle, struct inode *orig_inode,
718 if (!dext) { 691 if (!dext) {
719 ext4_error(donor_inode->i_sb, __func__, 692 ext4_error(donor_inode->i_sb, __func__,
720 "The extent for donor must be found"); 693 "The extent for donor must be found");
721 err = -EIO; 694 *err = -EIO;
722 goto out; 695 goto out;
723 } else if (donor_off != le32_to_cpu(tmp_dext.ee_block)) { 696 } else if (donor_off != le32_to_cpu(tmp_dext.ee_block)) {
724 ext4_error(donor_inode->i_sb, __func__, 697 ext4_error(donor_inode->i_sb, __func__,
@@ -726,20 +699,20 @@ mext_replace_branches(handle_t *handle, struct inode *orig_inode,
726 "extent(%u) should be equal", 699 "extent(%u) should be equal",
727 donor_off, 700 donor_off,
728 le32_to_cpu(tmp_dext.ee_block)); 701 le32_to_cpu(tmp_dext.ee_block));
729 err = -EIO; 702 *err = -EIO;
730 goto out; 703 goto out;
731 } 704 }
732 705
733 /* Set donor extent to orig extent */ 706 /* Set donor extent to orig extent */
734 err = mext_leaf_block(handle, orig_inode, 707 *err = mext_leaf_block(handle, orig_inode,
735 orig_path, &tmp_dext, &orig_off); 708 orig_path, &tmp_dext, &orig_off);
736 if (err < 0) 709 if (*err)
737 goto out; 710 goto out;
738 711
739 /* Set orig extent to donor extent */ 712 /* Set orig extent to donor extent */
740 err = mext_leaf_block(handle, donor_inode, 713 *err = mext_leaf_block(handle, donor_inode,
741 donor_path, &tmp_oext, &donor_off); 714 donor_path, &tmp_oext, &donor_off);
742 if (err < 0) 715 if (*err)
743 goto out; 716 goto out;
744 717
745 dext_alen = ext4_ext_get_actual_len(&tmp_dext); 718 dext_alen = ext4_ext_get_actual_len(&tmp_dext);
@@ -753,35 +726,25 @@ mext_replace_branches(handle_t *handle, struct inode *orig_inode,
753 726
754 if (orig_path) 727 if (orig_path)
755 ext4_ext_drop_refs(orig_path); 728 ext4_ext_drop_refs(orig_path);
756 err = get_ext_path(orig_inode, orig_off, &orig_path); 729 *err = get_ext_path(orig_inode, orig_off, &orig_path);
757 if (err) 730 if (*err)
758 goto out; 731 goto out;
759 depth = ext_depth(orig_inode); 732 depth = ext_depth(orig_inode);
760 oext = orig_path[depth].p_ext; 733 oext = orig_path[depth].p_ext;
761 if (le32_to_cpu(oext->ee_block) +
762 ext4_ext_get_actual_len(oext) <= orig_off) {
763 err = 0;
764 goto out;
765 }
766 tmp_oext = *oext; 734 tmp_oext = *oext;
767 735
768 if (donor_path) 736 if (donor_path)
769 ext4_ext_drop_refs(donor_path); 737 ext4_ext_drop_refs(donor_path);
770 err = get_ext_path(donor_inode, donor_off, &donor_path); 738 *err = get_ext_path(donor_inode, donor_off, &donor_path);
771 if (err) 739 if (*err)
772 goto out; 740 goto out;
773 depth = ext_depth(donor_inode); 741 depth = ext_depth(donor_inode);
774 dext = donor_path[depth].p_ext; 742 dext = donor_path[depth].p_ext;
775 if (le32_to_cpu(dext->ee_block) +
776 ext4_ext_get_actual_len(dext) <= donor_off) {
777 err = 0;
778 goto out;
779 }
780 tmp_dext = *dext; 743 tmp_dext = *dext;
781 744
782 err = mext_calc_swap_extents(&tmp_dext, &tmp_oext, orig_off, 745 *err = mext_calc_swap_extents(&tmp_dext, &tmp_oext, orig_off,
783 donor_off, count - replaced_count); 746 donor_off, count - replaced_count);
784 if (err) 747 if (*err)
785 goto out; 748 goto out;
786 } 749 }
787 750
@@ -795,8 +758,12 @@ out:
795 kfree(donor_path); 758 kfree(donor_path);
796 } 759 }
797 760
798 mext_double_up_write(orig_inode, donor_inode); 761 ext4_ext_invalidate_cache(orig_inode);
799 return err; 762 ext4_ext_invalidate_cache(donor_inode);
763
764 double_up_write_data_sem(orig_inode, donor_inode);
765
766 return replaced_count;
800} 767}
801 768
802/** 769/**
@@ -808,16 +775,17 @@ out:
808 * @data_offset_in_page: block index where data swapping starts 775 * @data_offset_in_page: block index where data swapping starts
809 * @block_len_in_page: the number of blocks to be swapped 776 * @block_len_in_page: the number of blocks to be swapped
810 * @uninit: orig extent is uninitialized or not 777 * @uninit: orig extent is uninitialized or not
778 * @err: pointer to save return value
811 * 779 *
812 * Save the data in original inode blocks and replace original inode extents 780 * Save the data in original inode blocks and replace original inode extents
813 * with donor inode extents by calling mext_replace_branches(). 781 * with donor inode extents by calling mext_replace_branches().
814 * Finally, write out the saved data in new original inode blocks. Return 0 782 * Finally, write out the saved data in new original inode blocks. Return
815 * on success, or a negative error value on failure. 783 * replaced block count.
816 */ 784 */
817static int 785static int
818move_extent_per_page(struct file *o_filp, struct inode *donor_inode, 786move_extent_per_page(struct file *o_filp, struct inode *donor_inode,
819 pgoff_t orig_page_offset, int data_offset_in_page, 787 pgoff_t orig_page_offset, int data_offset_in_page,
820 int block_len_in_page, int uninit) 788 int block_len_in_page, int uninit, int *err)
821{ 789{
822 struct inode *orig_inode = o_filp->f_dentry->d_inode; 790 struct inode *orig_inode = o_filp->f_dentry->d_inode;
823 struct address_space *mapping = orig_inode->i_mapping; 791 struct address_space *mapping = orig_inode->i_mapping;
@@ -829,9 +797,11 @@ move_extent_per_page(struct file *o_filp, struct inode *donor_inode,
829 long long offs = orig_page_offset << PAGE_CACHE_SHIFT; 797 long long offs = orig_page_offset << PAGE_CACHE_SHIFT;
830 unsigned long blocksize = orig_inode->i_sb->s_blocksize; 798 unsigned long blocksize = orig_inode->i_sb->s_blocksize;
831 unsigned int w_flags = 0; 799 unsigned int w_flags = 0;
832 unsigned int tmp_data_len, data_len; 800 unsigned int tmp_data_size, data_size, replaced_size;
833 void *fsdata; 801 void *fsdata;
834 int ret, i, jblocks; 802 int i, jblocks;
803 int err2 = 0;
804 int replaced_count = 0;
835 int blocks_per_page = PAGE_CACHE_SIZE >> orig_inode->i_blkbits; 805 int blocks_per_page = PAGE_CACHE_SIZE >> orig_inode->i_blkbits;
836 806
837 /* 807 /*
@@ -841,8 +811,8 @@ move_extent_per_page(struct file *o_filp, struct inode *donor_inode,
841 jblocks = ext4_writepage_trans_blocks(orig_inode) * 2; 811 jblocks = ext4_writepage_trans_blocks(orig_inode) * 2;
842 handle = ext4_journal_start(orig_inode, jblocks); 812 handle = ext4_journal_start(orig_inode, jblocks);
843 if (IS_ERR(handle)) { 813 if (IS_ERR(handle)) {
844 ret = PTR_ERR(handle); 814 *err = PTR_ERR(handle);
845 return ret; 815 return 0;
846 } 816 }
847 817
848 if (segment_eq(get_fs(), KERNEL_DS)) 818 if (segment_eq(get_fs(), KERNEL_DS))
@@ -858,39 +828,36 @@ move_extent_per_page(struct file *o_filp, struct inode *donor_inode,
858 * Just swap data blocks between orig and donor. 828 * Just swap data blocks between orig and donor.
859 */ 829 */
860 if (uninit) { 830 if (uninit) {
861 ret = mext_replace_branches(handle, orig_inode, 831 replaced_count = mext_replace_branches(handle, orig_inode,
862 donor_inode, orig_blk_offset, 832 donor_inode, orig_blk_offset,
863 block_len_in_page); 833 block_len_in_page, err);
864
865 /* Clear the inode cache not to refer to the old data */
866 ext4_ext_invalidate_cache(orig_inode);
867 ext4_ext_invalidate_cache(donor_inode);
868 goto out2; 834 goto out2;
869 } 835 }
870 836
871 offs = (long long)orig_blk_offset << orig_inode->i_blkbits; 837 offs = (long long)orig_blk_offset << orig_inode->i_blkbits;
872 838
873 /* Calculate data_len */ 839 /* Calculate data_size */
874 if ((orig_blk_offset + block_len_in_page - 1) == 840 if ((orig_blk_offset + block_len_in_page - 1) ==
875 ((orig_inode->i_size - 1) >> orig_inode->i_blkbits)) { 841 ((orig_inode->i_size - 1) >> orig_inode->i_blkbits)) {
876 /* Replace the last block */ 842 /* Replace the last block */
877 tmp_data_len = orig_inode->i_size & (blocksize - 1); 843 tmp_data_size = orig_inode->i_size & (blocksize - 1);
878 /* 844 /*
879 * If data_len equal zero, it shows data_len is multiples of 845 * If data_size equal zero, it shows data_size is multiples of
880 * blocksize. So we set appropriate value. 846 * blocksize. So we set appropriate value.
881 */ 847 */
882 if (tmp_data_len == 0) 848 if (tmp_data_size == 0)
883 tmp_data_len = blocksize; 849 tmp_data_size = blocksize;
884 850
885 data_len = tmp_data_len + 851 data_size = tmp_data_size +
886 ((block_len_in_page - 1) << orig_inode->i_blkbits); 852 ((block_len_in_page - 1) << orig_inode->i_blkbits);
887 } else { 853 } else
888 data_len = block_len_in_page << orig_inode->i_blkbits; 854 data_size = block_len_in_page << orig_inode->i_blkbits;
889 } 855
856 replaced_size = data_size;
890 857
891 ret = a_ops->write_begin(o_filp, mapping, offs, data_len, w_flags, 858 *err = a_ops->write_begin(o_filp, mapping, offs, data_size, w_flags,
892 &page, &fsdata); 859 &page, &fsdata);
893 if (unlikely(ret < 0)) 860 if (unlikely(*err < 0))
894 goto out; 861 goto out;
895 862
896 if (!PageUptodate(page)) { 863 if (!PageUptodate(page)) {
@@ -911,14 +878,17 @@ move_extent_per_page(struct file *o_filp, struct inode *donor_inode,
911 /* Release old bh and drop refs */ 878 /* Release old bh and drop refs */
912 try_to_release_page(page, 0); 879 try_to_release_page(page, 0);
913 880
914 ret = mext_replace_branches(handle, orig_inode, donor_inode, 881 replaced_count = mext_replace_branches(handle, orig_inode, donor_inode,
915 orig_blk_offset, block_len_in_page); 882 orig_blk_offset, block_len_in_page,
916 if (ret < 0) 883 &err2);
917 goto out; 884 if (err2) {
918 885 if (replaced_count) {
919 /* Clear the inode cache not to refer to the old data */ 886 block_len_in_page = replaced_count;
920 ext4_ext_invalidate_cache(orig_inode); 887 replaced_size =
921 ext4_ext_invalidate_cache(donor_inode); 888 block_len_in_page << orig_inode->i_blkbits;
889 } else
890 goto out;
891 }
922 892
923 if (!page_has_buffers(page)) 893 if (!page_has_buffers(page))
924 create_empty_buffers(page, 1 << orig_inode->i_blkbits, 0); 894 create_empty_buffers(page, 1 << orig_inode->i_blkbits, 0);
@@ -928,16 +898,16 @@ move_extent_per_page(struct file *o_filp, struct inode *donor_inode,
928 bh = bh->b_this_page; 898 bh = bh->b_this_page;
929 899
930 for (i = 0; i < block_len_in_page; i++) { 900 for (i = 0; i < block_len_in_page; i++) {
931 ret = ext4_get_block(orig_inode, 901 *err = ext4_get_block(orig_inode,
932 (sector_t)(orig_blk_offset + i), bh, 0); 902 (sector_t)(orig_blk_offset + i), bh, 0);
933 if (ret < 0) 903 if (*err < 0)
934 goto out; 904 goto out;
935 905
936 if (bh->b_this_page != NULL) 906 if (bh->b_this_page != NULL)
937 bh = bh->b_this_page; 907 bh = bh->b_this_page;
938 } 908 }
939 909
940 ret = a_ops->write_end(o_filp, mapping, offs, data_len, data_len, 910 *err = a_ops->write_end(o_filp, mapping, offs, data_size, replaced_size,
941 page, fsdata); 911 page, fsdata);
942 page = NULL; 912 page = NULL;
943 913
@@ -951,7 +921,10 @@ out:
951out2: 921out2:
952 ext4_journal_stop(handle); 922 ext4_journal_stop(handle);
953 923
954 return ret < 0 ? ret : 0; 924 if (err2)
925 *err = err2;
926
927 return replaced_count;
955} 928}
956 929
957/** 930/**
@@ -962,7 +935,6 @@ out2:
962 * @orig_start: logical start offset in block for orig 935 * @orig_start: logical start offset in block for orig
963 * @donor_start: logical start offset in block for donor 936 * @donor_start: logical start offset in block for donor
964 * @len: the number of blocks to be moved 937 * @len: the number of blocks to be moved
965 * @moved_len: moved block length
966 * 938 *
967 * Check the arguments of ext4_move_extents() whether the files can be 939 * Check the arguments of ext4_move_extents() whether the files can be
968 * exchanged with each other. 940 * exchanged with each other.
@@ -970,8 +942,8 @@ out2:
970 */ 942 */
971static int 943static int
972mext_check_arguments(struct inode *orig_inode, 944mext_check_arguments(struct inode *orig_inode,
973 struct inode *donor_inode, __u64 orig_start, 945 struct inode *donor_inode, __u64 orig_start,
974 __u64 donor_start, __u64 *len, __u64 moved_len) 946 __u64 donor_start, __u64 *len)
975{ 947{
976 ext4_lblk_t orig_blocks, donor_blocks; 948 ext4_lblk_t orig_blocks, donor_blocks;
977 unsigned int blkbits = orig_inode->i_blkbits; 949 unsigned int blkbits = orig_inode->i_blkbits;
@@ -985,6 +957,13 @@ mext_check_arguments(struct inode *orig_inode,
985 return -EINVAL; 957 return -EINVAL;
986 } 958 }
987 959
960 if (donor_inode->i_mode & (S_ISUID|S_ISGID)) {
961 ext4_debug("ext4 move extent: suid or sgid is set"
962 " to donor file [ino:orig %lu, donor %lu]\n",
963 orig_inode->i_ino, donor_inode->i_ino);
964 return -EINVAL;
965 }
966
988 /* Ext4 move extent does not support swapfile */ 967 /* Ext4 move extent does not support swapfile */
989 if (IS_SWAPFILE(orig_inode) || IS_SWAPFILE(donor_inode)) { 968 if (IS_SWAPFILE(orig_inode) || IS_SWAPFILE(donor_inode)) {
990 ext4_debug("ext4 move extent: The argument files should " 969 ext4_debug("ext4 move extent: The argument files should "
@@ -1025,13 +1004,6 @@ mext_check_arguments(struct inode *orig_inode,
1025 return -EINVAL; 1004 return -EINVAL;
1026 } 1005 }
1027 1006
1028 if (moved_len) {
1029 ext4_debug("ext4 move extent: moved_len should be 0 "
1030 "[ino:orig %lu, donor %lu]\n", orig_inode->i_ino,
1031 donor_inode->i_ino);
1032 return -EINVAL;
1033 }
1034
1035 if ((orig_start > EXT_MAX_BLOCK) || 1007 if ((orig_start > EXT_MAX_BLOCK) ||
1036 (donor_start > EXT_MAX_BLOCK) || 1008 (donor_start > EXT_MAX_BLOCK) ||
1037 (*len > EXT_MAX_BLOCK) || 1009 (*len > EXT_MAX_BLOCK) ||
@@ -1088,7 +1060,7 @@ mext_check_arguments(struct inode *orig_inode,
1088 } 1060 }
1089 1061
1090 if (!*len) { 1062 if (!*len) {
1091 ext4_debug("ext4 move extent: len shoudld not be 0 " 1063 ext4_debug("ext4 move extent: len should not be 0 "
1092 "[ino:orig %lu, donor %lu]\n", orig_inode->i_ino, 1064 "[ino:orig %lu, donor %lu]\n", orig_inode->i_ino,
1093 donor_inode->i_ino); 1065 donor_inode->i_ino);
1094 return -EINVAL; 1066 return -EINVAL;
@@ -1232,16 +1204,16 @@ ext4_move_extents(struct file *o_filp, struct file *d_filp,
1232 return -EINVAL; 1204 return -EINVAL;
1233 } 1205 }
1234 1206
1235 /* protect orig and donor against a truncate */ 1207 /* Protect orig and donor inodes against a truncate */
1236 ret1 = mext_inode_double_lock(orig_inode, donor_inode); 1208 ret1 = mext_inode_double_lock(orig_inode, donor_inode);
1237 if (ret1 < 0) 1209 if (ret1 < 0)
1238 return ret1; 1210 return ret1;
1239 1211
1240 mext_double_down_read(orig_inode, donor_inode); 1212 /* Protect extent tree against block allocations via delalloc */
1213 double_down_write_data_sem(orig_inode, donor_inode);
1241 /* Check the filesystem environment whether move_extent can be done */ 1214 /* Check the filesystem environment whether move_extent can be done */
1242 ret1 = mext_check_arguments(orig_inode, donor_inode, orig_start, 1215 ret1 = mext_check_arguments(orig_inode, donor_inode, orig_start,
1243 donor_start, &len, *moved_len); 1216 donor_start, &len);
1244 mext_double_up_read(orig_inode, donor_inode);
1245 if (ret1) 1217 if (ret1)
1246 goto out; 1218 goto out;
1247 1219
@@ -1355,36 +1327,39 @@ ext4_move_extents(struct file *o_filp, struct file *d_filp,
1355 seq_start = le32_to_cpu(ext_cur->ee_block); 1327 seq_start = le32_to_cpu(ext_cur->ee_block);
1356 rest_blocks = seq_blocks; 1328 rest_blocks = seq_blocks;
1357 1329
1358 /* Discard preallocations of two inodes */ 1330 /*
1359 down_write(&EXT4_I(orig_inode)->i_data_sem); 1331 * Up semaphore to avoid following problems:
1360 ext4_discard_preallocations(orig_inode); 1332 * a. transaction deadlock among ext4_journal_start,
1361 up_write(&EXT4_I(orig_inode)->i_data_sem); 1333 * ->write_begin via pagefault, and jbd2_journal_commit
1362 1334 * b. racing with ->readpage, ->write_begin, and ext4_get_block
1363 down_write(&EXT4_I(donor_inode)->i_data_sem); 1335 * in move_extent_per_page
1364 ext4_discard_preallocations(donor_inode); 1336 */
1365 up_write(&EXT4_I(donor_inode)->i_data_sem); 1337 double_up_write_data_sem(orig_inode, donor_inode);
1366 1338
1367 while (orig_page_offset <= seq_end_page) { 1339 while (orig_page_offset <= seq_end_page) {
1368 1340
1369 /* Swap original branches with new branches */ 1341 /* Swap original branches with new branches */
1370 ret1 = move_extent_per_page(o_filp, donor_inode, 1342 block_len_in_page = move_extent_per_page(
1343 o_filp, donor_inode,
1371 orig_page_offset, 1344 orig_page_offset,
1372 data_offset_in_page, 1345 data_offset_in_page,
1373 block_len_in_page, uninit); 1346 block_len_in_page, uninit,
1374 if (ret1 < 0) 1347 &ret1);
1375 goto out; 1348
1376 orig_page_offset++;
1377 /* Count how many blocks we have exchanged */ 1349 /* Count how many blocks we have exchanged */
1378 *moved_len += block_len_in_page; 1350 *moved_len += block_len_in_page;
1351 if (ret1 < 0)
1352 break;
1379 if (*moved_len > len) { 1353 if (*moved_len > len) {
1380 ext4_error(orig_inode->i_sb, __func__, 1354 ext4_error(orig_inode->i_sb, __func__,
1381 "We replaced blocks too much! " 1355 "We replaced blocks too much! "
1382 "sum of replaced: %llu requested: %llu", 1356 "sum of replaced: %llu requested: %llu",
1383 *moved_len, len); 1357 *moved_len, len);
1384 ret1 = -EIO; 1358 ret1 = -EIO;
1385 goto out; 1359 break;
1386 } 1360 }
1387 1361
1362 orig_page_offset++;
1388 data_offset_in_page = 0; 1363 data_offset_in_page = 0;
1389 rest_blocks -= block_len_in_page; 1364 rest_blocks -= block_len_in_page;
1390 if (rest_blocks > blocks_per_page) 1365 if (rest_blocks > blocks_per_page)
@@ -1393,6 +1368,10 @@ ext4_move_extents(struct file *o_filp, struct file *d_filp,
1393 block_len_in_page = rest_blocks; 1368 block_len_in_page = rest_blocks;
1394 } 1369 }
1395 1370
1371 double_down_write_data_sem(orig_inode, donor_inode);
1372 if (ret1 < 0)
1373 break;
1374
1396 /* Decrease buffer counter */ 1375 /* Decrease buffer counter */
1397 if (holecheck_path) 1376 if (holecheck_path)
1398 ext4_ext_drop_refs(holecheck_path); 1377 ext4_ext_drop_refs(holecheck_path);
@@ -1414,6 +1393,11 @@ ext4_move_extents(struct file *o_filp, struct file *d_filp,
1414 1393
1415 } 1394 }
1416out: 1395out:
1396 if (*moved_len) {
1397 ext4_discard_preallocations(orig_inode);
1398 ext4_discard_preallocations(donor_inode);
1399 }
1400
1417 if (orig_path) { 1401 if (orig_path) {
1418 ext4_ext_drop_refs(orig_path); 1402 ext4_ext_drop_refs(orig_path);
1419 kfree(orig_path); 1403 kfree(orig_path);
@@ -1422,7 +1406,7 @@ out:
1422 ext4_ext_drop_refs(holecheck_path); 1406 ext4_ext_drop_refs(holecheck_path);
1423 kfree(holecheck_path); 1407 kfree(holecheck_path);
1424 } 1408 }
1425 1409 double_up_write_data_sem(orig_inode, donor_inode);
1426 ret2 = mext_inode_double_unlock(orig_inode, donor_inode); 1410 ret2 = mext_inode_double_unlock(orig_inode, donor_inode);
1427 1411
1428 if (ret1) 1412 if (ret1)