diff options
Diffstat (limited to 'fs/ext4')
-rw-r--r-- | fs/ext4/move_extent.c | 30 |
1 files changed, 9 insertions, 21 deletions
diff --git a/fs/ext4/move_extent.c b/fs/ext4/move_extent.c index 445ecd7616a6..cad1e2edda7e 100644 --- a/fs/ext4/move_extent.c +++ b/fs/ext4/move_extent.c | |||
@@ -660,6 +660,9 @@ mext_replace_branches(handle_t *handle, struct inode *orig_inode, | |||
660 | int replaced_count = 0; | 660 | int replaced_count = 0; |
661 | int dext_alen; | 661 | int dext_alen; |
662 | 662 | ||
663 | /* Protect extent trees against block allocations via delalloc */ | ||
664 | double_down_write_data_sem(orig_inode, donor_inode); | ||
665 | |||
663 | /* Get the original extent for the block "orig_off" */ | 666 | /* Get the original extent for the block "orig_off" */ |
664 | *err = get_ext_path(orig_inode, orig_off, &orig_path); | 667 | *err = get_ext_path(orig_inode, orig_off, &orig_path); |
665 | if (*err) | 668 | if (*err) |
@@ -755,6 +758,11 @@ out: | |||
755 | kfree(donor_path); | 758 | kfree(donor_path); |
756 | } | 759 | } |
757 | 760 | ||
761 | ext4_ext_invalidate_cache(orig_inode); | ||
762 | ext4_ext_invalidate_cache(donor_inode); | ||
763 | |||
764 | double_up_write_data_sem(orig_inode, donor_inode); | ||
765 | |||
758 | return replaced_count; | 766 | return replaced_count; |
759 | } | 767 | } |
760 | 768 | ||
@@ -820,19 +828,9 @@ move_extent_per_page(struct file *o_filp, struct inode *donor_inode, | |||
820 | * Just swap data blocks between orig and donor. | 828 | * Just swap data blocks between orig and donor. |
821 | */ | 829 | */ |
822 | if (uninit) { | 830 | if (uninit) { |
823 | /* | ||
824 | * Protect extent trees against block allocations | ||
825 | * via delalloc | ||
826 | */ | ||
827 | double_down_write_data_sem(orig_inode, donor_inode); | ||
828 | replaced_count = mext_replace_branches(handle, orig_inode, | 831 | replaced_count = mext_replace_branches(handle, orig_inode, |
829 | donor_inode, orig_blk_offset, | 832 | donor_inode, orig_blk_offset, |
830 | block_len_in_page, err); | 833 | block_len_in_page, err); |
831 | |||
832 | /* Clear the inode cache not to refer to the old data */ | ||
833 | ext4_ext_invalidate_cache(orig_inode); | ||
834 | ext4_ext_invalidate_cache(donor_inode); | ||
835 | double_up_write_data_sem(orig_inode, donor_inode); | ||
836 | goto out2; | 834 | goto out2; |
837 | } | 835 | } |
838 | 836 | ||
@@ -880,8 +878,6 @@ move_extent_per_page(struct file *o_filp, struct inode *donor_inode, | |||
880 | /* Release old bh and drop refs */ | 878 | /* Release old bh and drop refs */ |
881 | try_to_release_page(page, 0); | 879 | try_to_release_page(page, 0); |
882 | 880 | ||
883 | /* Protect extent trees against block allocations via delalloc */ | ||
884 | double_down_write_data_sem(orig_inode, donor_inode); | ||
885 | replaced_count = mext_replace_branches(handle, orig_inode, donor_inode, | 881 | replaced_count = mext_replace_branches(handle, orig_inode, donor_inode, |
886 | orig_blk_offset, block_len_in_page, | 882 | orig_blk_offset, block_len_in_page, |
887 | &err2); | 883 | &err2); |
@@ -890,18 +886,10 @@ move_extent_per_page(struct file *o_filp, struct inode *donor_inode, | |||
890 | block_len_in_page = replaced_count; | 886 | block_len_in_page = replaced_count; |
891 | replaced_size = | 887 | replaced_size = |
892 | block_len_in_page << orig_inode->i_blkbits; | 888 | block_len_in_page << orig_inode->i_blkbits; |
893 | } else { | 889 | } else |
894 | double_up_write_data_sem(orig_inode, donor_inode); | ||
895 | goto out; | 890 | goto out; |
896 | } | ||
897 | } | 891 | } |
898 | 892 | ||
899 | /* Clear the inode cache not to refer to the old data */ | ||
900 | ext4_ext_invalidate_cache(orig_inode); | ||
901 | ext4_ext_invalidate_cache(donor_inode); | ||
902 | |||
903 | double_up_write_data_sem(orig_inode, donor_inode); | ||
904 | |||
905 | if (!page_has_buffers(page)) | 893 | if (!page_has_buffers(page)) |
906 | create_empty_buffers(page, 1 << orig_inode->i_blkbits, 0); | 894 | create_empty_buffers(page, 1 << orig_inode->i_blkbits, 0); |
907 | 895 | ||