diff options
Diffstat (limited to 'fs/ext4/move_extent.c')
-rw-r--r-- | fs/ext4/move_extent.c | 27 |
1 files changed, 17 insertions, 10 deletions
diff --git a/fs/ext4/move_extent.c b/fs/ext4/move_extent.c index 4098acc701c3..325cef48b39a 100644 --- a/fs/ext4/move_extent.c +++ b/fs/ext4/move_extent.c | |||
@@ -60,10 +60,10 @@ ext4_double_down_write_data_sem(struct inode *first, struct inode *second) | |||
60 | { | 60 | { |
61 | if (first < second) { | 61 | if (first < second) { |
62 | down_write(&EXT4_I(first)->i_data_sem); | 62 | down_write(&EXT4_I(first)->i_data_sem); |
63 | down_write_nested(&EXT4_I(second)->i_data_sem, SINGLE_DEPTH_NESTING); | 63 | down_write_nested(&EXT4_I(second)->i_data_sem, I_DATA_SEM_OTHER); |
64 | } else { | 64 | } else { |
65 | down_write(&EXT4_I(second)->i_data_sem); | 65 | down_write(&EXT4_I(second)->i_data_sem); |
66 | down_write_nested(&EXT4_I(first)->i_data_sem, SINGLE_DEPTH_NESTING); | 66 | down_write_nested(&EXT4_I(first)->i_data_sem, I_DATA_SEM_OTHER); |
67 | 67 | ||
68 | } | 68 | } |
69 | } | 69 | } |
@@ -156,7 +156,7 @@ mext_page_double_lock(struct inode *inode1, struct inode *inode2, | |||
156 | page[1] = grab_cache_page_write_begin(mapping[1], index2, fl); | 156 | page[1] = grab_cache_page_write_begin(mapping[1], index2, fl); |
157 | if (!page[1]) { | 157 | if (!page[1]) { |
158 | unlock_page(page[0]); | 158 | unlock_page(page[0]); |
159 | page_cache_release(page[0]); | 159 | put_page(page[0]); |
160 | return -ENOMEM; | 160 | return -ENOMEM; |
161 | } | 161 | } |
162 | /* | 162 | /* |
@@ -192,7 +192,7 @@ mext_page_mkuptodate(struct page *page, unsigned from, unsigned to) | |||
192 | create_empty_buffers(page, blocksize, 0); | 192 | create_empty_buffers(page, blocksize, 0); |
193 | 193 | ||
194 | head = page_buffers(page); | 194 | head = page_buffers(page); |
195 | block = (sector_t)page->index << (PAGE_CACHE_SHIFT - inode->i_blkbits); | 195 | block = (sector_t)page->index << (PAGE_SHIFT - inode->i_blkbits); |
196 | for (bh = head, block_start = 0; bh != head || !block_start; | 196 | for (bh = head, block_start = 0; bh != head || !block_start; |
197 | block++, block_start = block_end, bh = bh->b_this_page) { | 197 | block++, block_start = block_end, bh = bh->b_this_page) { |
198 | block_end = block_start + blocksize; | 198 | block_end = block_start + blocksize; |
@@ -268,7 +268,7 @@ move_extent_per_page(struct file *o_filp, struct inode *donor_inode, | |||
268 | int i, err2, jblocks, retries = 0; | 268 | int i, err2, jblocks, retries = 0; |
269 | int replaced_count = 0; | 269 | int replaced_count = 0; |
270 | int from = data_offset_in_page << orig_inode->i_blkbits; | 270 | int from = data_offset_in_page << orig_inode->i_blkbits; |
271 | int blocks_per_page = PAGE_CACHE_SIZE >> orig_inode->i_blkbits; | 271 | int blocks_per_page = PAGE_SIZE >> orig_inode->i_blkbits; |
272 | struct super_block *sb = orig_inode->i_sb; | 272 | struct super_block *sb = orig_inode->i_sb; |
273 | struct buffer_head *bh = NULL; | 273 | struct buffer_head *bh = NULL; |
274 | 274 | ||
@@ -404,9 +404,9 @@ data_copy: | |||
404 | 404 | ||
405 | unlock_pages: | 405 | unlock_pages: |
406 | unlock_page(pagep[0]); | 406 | unlock_page(pagep[0]); |
407 | page_cache_release(pagep[0]); | 407 | put_page(pagep[0]); |
408 | unlock_page(pagep[1]); | 408 | unlock_page(pagep[1]); |
409 | page_cache_release(pagep[1]); | 409 | put_page(pagep[1]); |
410 | stop_journal: | 410 | stop_journal: |
411 | ext4_journal_stop(handle); | 411 | ext4_journal_stop(handle); |
412 | if (*err == -ENOSPC && | 412 | if (*err == -ENOSPC && |
@@ -484,6 +484,13 @@ mext_check_arguments(struct inode *orig_inode, | |||
484 | return -EBUSY; | 484 | return -EBUSY; |
485 | } | 485 | } |
486 | 486 | ||
487 | if (IS_NOQUOTA(orig_inode) || IS_NOQUOTA(donor_inode)) { | ||
488 | ext4_debug("ext4 move extent: The argument files should " | ||
489 | "not be quota files [ino:orig %lu, donor %lu]\n", | ||
490 | orig_inode->i_ino, donor_inode->i_ino); | ||
491 | return -EBUSY; | ||
492 | } | ||
493 | |||
487 | /* Ext4 move extent supports only extent based file */ | 494 | /* Ext4 move extent supports only extent based file */ |
488 | if (!(ext4_test_inode_flag(orig_inode, EXT4_INODE_EXTENTS))) { | 495 | if (!(ext4_test_inode_flag(orig_inode, EXT4_INODE_EXTENTS))) { |
489 | ext4_debug("ext4 move extent: orig file is not extents " | 496 | ext4_debug("ext4 move extent: orig file is not extents " |
@@ -554,7 +561,7 @@ ext4_move_extents(struct file *o_filp, struct file *d_filp, __u64 orig_blk, | |||
554 | struct inode *orig_inode = file_inode(o_filp); | 561 | struct inode *orig_inode = file_inode(o_filp); |
555 | struct inode *donor_inode = file_inode(d_filp); | 562 | struct inode *donor_inode = file_inode(d_filp); |
556 | struct ext4_ext_path *path = NULL; | 563 | struct ext4_ext_path *path = NULL; |
557 | int blocks_per_page = PAGE_CACHE_SIZE >> orig_inode->i_blkbits; | 564 | int blocks_per_page = PAGE_SIZE >> orig_inode->i_blkbits; |
558 | ext4_lblk_t o_end, o_start = orig_blk; | 565 | ext4_lblk_t o_end, o_start = orig_blk; |
559 | ext4_lblk_t d_start = donor_blk; | 566 | ext4_lblk_t d_start = donor_blk; |
560 | int ret; | 567 | int ret; |
@@ -648,9 +655,9 @@ ext4_move_extents(struct file *o_filp, struct file *d_filp, __u64 orig_blk, | |||
648 | if (o_end - o_start < cur_len) | 655 | if (o_end - o_start < cur_len) |
649 | cur_len = o_end - o_start; | 656 | cur_len = o_end - o_start; |
650 | 657 | ||
651 | orig_page_index = o_start >> (PAGE_CACHE_SHIFT - | 658 | orig_page_index = o_start >> (PAGE_SHIFT - |
652 | orig_inode->i_blkbits); | 659 | orig_inode->i_blkbits); |
653 | donor_page_index = d_start >> (PAGE_CACHE_SHIFT - | 660 | donor_page_index = d_start >> (PAGE_SHIFT - |
654 | donor_inode->i_blkbits); | 661 | donor_inode->i_blkbits); |
655 | offset_in_page = o_start % blocks_per_page; | 662 | offset_in_page = o_start % blocks_per_page; |
656 | if (cur_len > blocks_per_page- offset_in_page) | 663 | if (cur_len > blocks_per_page- offset_in_page) |