diff options
Diffstat (limited to 'fs/ext4/extents.c')
-rw-r--r-- | fs/ext4/extents.c | 153 |
1 files changed, 83 insertions, 70 deletions
diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c index 551353b1b17a..b52fea3b7219 100644 --- a/fs/ext4/extents.c +++ b/fs/ext4/extents.c | |||
@@ -3119,19 +3119,11 @@ static int ext4_ext_zeroout(struct inode *inode, struct ext4_extent *ex) | |||
3119 | { | 3119 | { |
3120 | ext4_fsblk_t ee_pblock; | 3120 | ext4_fsblk_t ee_pblock; |
3121 | unsigned int ee_len; | 3121 | unsigned int ee_len; |
3122 | int ret; | ||
3123 | 3122 | ||
3124 | ee_len = ext4_ext_get_actual_len(ex); | 3123 | ee_len = ext4_ext_get_actual_len(ex); |
3125 | ee_pblock = ext4_ext_pblock(ex); | 3124 | ee_pblock = ext4_ext_pblock(ex); |
3126 | 3125 | return ext4_issue_zeroout(inode, le32_to_cpu(ex->ee_block), ee_pblock, | |
3127 | if (ext4_encrypted_inode(inode)) | 3126 | ee_len); |
3128 | return ext4_encrypted_zeroout(inode, ex); | ||
3129 | |||
3130 | ret = sb_issue_zeroout(inode->i_sb, ee_pblock, ee_len, GFP_NOFS); | ||
3131 | if (ret > 0) | ||
3132 | ret = 0; | ||
3133 | |||
3134 | return ret; | ||
3135 | } | 3127 | } |
3136 | 3128 | ||
3137 | /* | 3129 | /* |
@@ -4052,6 +4044,14 @@ ext4_ext_handle_unwritten_extents(handle_t *handle, struct inode *inode, | |||
4052 | } | 4044 | } |
4053 | /* IO end_io complete, convert the filled extent to written */ | 4045 | /* IO end_io complete, convert the filled extent to written */ |
4054 | if (flags & EXT4_GET_BLOCKS_CONVERT) { | 4046 | if (flags & EXT4_GET_BLOCKS_CONVERT) { |
4047 | if (flags & EXT4_GET_BLOCKS_ZERO) { | ||
4048 | if (allocated > map->m_len) | ||
4049 | allocated = map->m_len; | ||
4050 | err = ext4_issue_zeroout(inode, map->m_lblk, newblock, | ||
4051 | allocated); | ||
4052 | if (err < 0) | ||
4053 | goto out2; | ||
4054 | } | ||
4055 | ret = ext4_convert_unwritten_extents_endio(handle, inode, map, | 4055 | ret = ext4_convert_unwritten_extents_endio(handle, inode, map, |
4056 | ppath); | 4056 | ppath); |
4057 | if (ret >= 0) { | 4057 | if (ret >= 0) { |
@@ -4685,10 +4685,6 @@ static int ext4_alloc_file_blocks(struct file *file, ext4_lblk_t offset, | |||
4685 | if (len <= EXT_UNWRITTEN_MAX_LEN) | 4685 | if (len <= EXT_UNWRITTEN_MAX_LEN) |
4686 | flags |= EXT4_GET_BLOCKS_NO_NORMALIZE; | 4686 | flags |= EXT4_GET_BLOCKS_NO_NORMALIZE; |
4687 | 4687 | ||
4688 | /* Wait all existing dio workers, newcomers will block on i_mutex */ | ||
4689 | ext4_inode_block_unlocked_dio(inode); | ||
4690 | inode_dio_wait(inode); | ||
4691 | |||
4692 | /* | 4688 | /* |
4693 | * credits to insert 1 extent into extent tree | 4689 | * credits to insert 1 extent into extent tree |
4694 | */ | 4690 | */ |
@@ -4752,8 +4748,6 @@ retry: | |||
4752 | goto retry; | 4748 | goto retry; |
4753 | } | 4749 | } |
4754 | 4750 | ||
4755 | ext4_inode_resume_unlocked_dio(inode); | ||
4756 | |||
4757 | return ret > 0 ? ret2 : ret; | 4751 | return ret > 0 ? ret2 : ret; |
4758 | } | 4752 | } |
4759 | 4753 | ||
@@ -4770,7 +4764,6 @@ static long ext4_zero_range(struct file *file, loff_t offset, | |||
4770 | int partial_begin, partial_end; | 4764 | int partial_begin, partial_end; |
4771 | loff_t start, end; | 4765 | loff_t start, end; |
4772 | ext4_lblk_t lblk; | 4766 | ext4_lblk_t lblk; |
4773 | struct address_space *mapping = inode->i_mapping; | ||
4774 | unsigned int blkbits = inode->i_blkbits; | 4767 | unsigned int blkbits = inode->i_blkbits; |
4775 | 4768 | ||
4776 | trace_ext4_zero_range(inode, offset, len, mode); | 4769 | trace_ext4_zero_range(inode, offset, len, mode); |
@@ -4786,17 +4779,6 @@ static long ext4_zero_range(struct file *file, loff_t offset, | |||
4786 | } | 4779 | } |
4787 | 4780 | ||
4788 | /* | 4781 | /* |
4789 | * Write out all dirty pages to avoid race conditions | ||
4790 | * Then release them. | ||
4791 | */ | ||
4792 | if (mapping->nrpages && mapping_tagged(mapping, PAGECACHE_TAG_DIRTY)) { | ||
4793 | ret = filemap_write_and_wait_range(mapping, offset, | ||
4794 | offset + len - 1); | ||
4795 | if (ret) | ||
4796 | return ret; | ||
4797 | } | ||
4798 | |||
4799 | /* | ||
4800 | * Round up offset. This is not fallocate, we neet to zero out | 4782 | * Round up offset. This is not fallocate, we neet to zero out |
4801 | * blocks, so convert interior block aligned part of the range to | 4783 | * blocks, so convert interior block aligned part of the range to |
4802 | * unwritten and possibly manually zero out unaligned parts of the | 4784 | * unwritten and possibly manually zero out unaligned parts of the |
@@ -4839,6 +4821,10 @@ static long ext4_zero_range(struct file *file, loff_t offset, | |||
4839 | if (mode & FALLOC_FL_KEEP_SIZE) | 4821 | if (mode & FALLOC_FL_KEEP_SIZE) |
4840 | flags |= EXT4_GET_BLOCKS_KEEP_SIZE; | 4822 | flags |= EXT4_GET_BLOCKS_KEEP_SIZE; |
4841 | 4823 | ||
4824 | /* Wait all existing dio workers, newcomers will block on i_mutex */ | ||
4825 | ext4_inode_block_unlocked_dio(inode); | ||
4826 | inode_dio_wait(inode); | ||
4827 | |||
4842 | /* Preallocate the range including the unaligned edges */ | 4828 | /* Preallocate the range including the unaligned edges */ |
4843 | if (partial_begin || partial_end) { | 4829 | if (partial_begin || partial_end) { |
4844 | ret = ext4_alloc_file_blocks(file, | 4830 | ret = ext4_alloc_file_blocks(file, |
@@ -4847,7 +4833,7 @@ static long ext4_zero_range(struct file *file, loff_t offset, | |||
4847 | round_down(offset, 1 << blkbits)) >> blkbits, | 4833 | round_down(offset, 1 << blkbits)) >> blkbits, |
4848 | new_size, flags, mode); | 4834 | new_size, flags, mode); |
4849 | if (ret) | 4835 | if (ret) |
4850 | goto out_mutex; | 4836 | goto out_dio; |
4851 | 4837 | ||
4852 | } | 4838 | } |
4853 | 4839 | ||
@@ -4856,16 +4842,23 @@ static long ext4_zero_range(struct file *file, loff_t offset, | |||
4856 | flags |= (EXT4_GET_BLOCKS_CONVERT_UNWRITTEN | | 4842 | flags |= (EXT4_GET_BLOCKS_CONVERT_UNWRITTEN | |
4857 | EXT4_EX_NOCACHE); | 4843 | EXT4_EX_NOCACHE); |
4858 | 4844 | ||
4859 | /* Now release the pages and zero block aligned part of pages*/ | 4845 | /* |
4846 | * Prevent page faults from reinstantiating pages we have | ||
4847 | * released from page cache. | ||
4848 | */ | ||
4849 | down_write(&EXT4_I(inode)->i_mmap_sem); | ||
4850 | ret = ext4_update_disksize_before_punch(inode, offset, len); | ||
4851 | if (ret) { | ||
4852 | up_write(&EXT4_I(inode)->i_mmap_sem); | ||
4853 | goto out_dio; | ||
4854 | } | ||
4855 | /* Now release the pages and zero block aligned part of pages */ | ||
4860 | truncate_pagecache_range(inode, start, end - 1); | 4856 | truncate_pagecache_range(inode, start, end - 1); |
4861 | inode->i_mtime = inode->i_ctime = ext4_current_time(inode); | 4857 | inode->i_mtime = inode->i_ctime = ext4_current_time(inode); |
4862 | 4858 | ||
4863 | /* Wait all existing dio workers, newcomers will block on i_mutex */ | ||
4864 | ext4_inode_block_unlocked_dio(inode); | ||
4865 | inode_dio_wait(inode); | ||
4866 | |||
4867 | ret = ext4_alloc_file_blocks(file, lblk, max_blocks, new_size, | 4859 | ret = ext4_alloc_file_blocks(file, lblk, max_blocks, new_size, |
4868 | flags, mode); | 4860 | flags, mode); |
4861 | up_write(&EXT4_I(inode)->i_mmap_sem); | ||
4869 | if (ret) | 4862 | if (ret) |
4870 | goto out_dio; | 4863 | goto out_dio; |
4871 | } | 4864 | } |
@@ -4998,8 +4991,13 @@ long ext4_fallocate(struct file *file, int mode, loff_t offset, loff_t len) | |||
4998 | goto out; | 4991 | goto out; |
4999 | } | 4992 | } |
5000 | 4993 | ||
4994 | /* Wait all existing dio workers, newcomers will block on i_mutex */ | ||
4995 | ext4_inode_block_unlocked_dio(inode); | ||
4996 | inode_dio_wait(inode); | ||
4997 | |||
5001 | ret = ext4_alloc_file_blocks(file, lblk, max_blocks, new_size, | 4998 | ret = ext4_alloc_file_blocks(file, lblk, max_blocks, new_size, |
5002 | flags, mode); | 4999 | flags, mode); |
5000 | ext4_inode_resume_unlocked_dio(inode); | ||
5003 | if (ret) | 5001 | if (ret) |
5004 | goto out; | 5002 | goto out; |
5005 | 5003 | ||
@@ -5494,21 +5492,7 @@ int ext4_collapse_range(struct inode *inode, loff_t offset, loff_t len) | |||
5494 | return ret; | 5492 | return ret; |
5495 | } | 5493 | } |
5496 | 5494 | ||
5497 | /* | ||
5498 | * Need to round down offset to be aligned with page size boundary | ||
5499 | * for page size > block size. | ||
5500 | */ | ||
5501 | ioffset = round_down(offset, PAGE_SIZE); | ||
5502 | |||
5503 | /* Write out all dirty pages */ | ||
5504 | ret = filemap_write_and_wait_range(inode->i_mapping, ioffset, | ||
5505 | LLONG_MAX); | ||
5506 | if (ret) | ||
5507 | return ret; | ||
5508 | |||
5509 | /* Take mutex lock */ | ||
5510 | mutex_lock(&inode->i_mutex); | 5495 | mutex_lock(&inode->i_mutex); |
5511 | |||
5512 | /* | 5496 | /* |
5513 | * There is no need to overlap collapse range with EOF, in which case | 5497 | * There is no need to overlap collapse range with EOF, in which case |
5514 | * it is effectively a truncate operation | 5498 | * it is effectively a truncate operation |
@@ -5524,17 +5508,43 @@ int ext4_collapse_range(struct inode *inode, loff_t offset, loff_t len) | |||
5524 | goto out_mutex; | 5508 | goto out_mutex; |
5525 | } | 5509 | } |
5526 | 5510 | ||
5527 | truncate_pagecache(inode, ioffset); | ||
5528 | |||
5529 | /* Wait for existing dio to complete */ | 5511 | /* Wait for existing dio to complete */ |
5530 | ext4_inode_block_unlocked_dio(inode); | 5512 | ext4_inode_block_unlocked_dio(inode); |
5531 | inode_dio_wait(inode); | 5513 | inode_dio_wait(inode); |
5532 | 5514 | ||
5515 | /* | ||
5516 | * Prevent page faults from reinstantiating pages we have released from | ||
5517 | * page cache. | ||
5518 | */ | ||
5519 | down_write(&EXT4_I(inode)->i_mmap_sem); | ||
5520 | /* | ||
5521 | * Need to round down offset to be aligned with page size boundary | ||
5522 | * for page size > block size. | ||
5523 | */ | ||
5524 | ioffset = round_down(offset, PAGE_SIZE); | ||
5525 | /* | ||
5526 | * Write tail of the last page before removed range since it will get | ||
5527 | * removed from the page cache below. | ||
5528 | */ | ||
5529 | ret = filemap_write_and_wait_range(inode->i_mapping, ioffset, offset); | ||
5530 | if (ret) | ||
5531 | goto out_mmap; | ||
5532 | /* | ||
5533 | * Write data that will be shifted to preserve them when discarding | ||
5534 | * page cache below. We are also protected from pages becoming dirty | ||
5535 | * by i_mmap_sem. | ||
5536 | */ | ||
5537 | ret = filemap_write_and_wait_range(inode->i_mapping, offset + len, | ||
5538 | LLONG_MAX); | ||
5539 | if (ret) | ||
5540 | goto out_mmap; | ||
5541 | truncate_pagecache(inode, ioffset); | ||
5542 | |||
5533 | credits = ext4_writepage_trans_blocks(inode); | 5543 | credits = ext4_writepage_trans_blocks(inode); |
5534 | handle = ext4_journal_start(inode, EXT4_HT_TRUNCATE, credits); | 5544 | handle = ext4_journal_start(inode, EXT4_HT_TRUNCATE, credits); |
5535 | if (IS_ERR(handle)) { | 5545 | if (IS_ERR(handle)) { |
5536 | ret = PTR_ERR(handle); | 5546 | ret = PTR_ERR(handle); |
5537 | goto out_dio; | 5547 | goto out_mmap; |
5538 | } | 5548 | } |
5539 | 5549 | ||
5540 | down_write(&EXT4_I(inode)->i_data_sem); | 5550 | down_write(&EXT4_I(inode)->i_data_sem); |
@@ -5573,7 +5583,8 @@ int ext4_collapse_range(struct inode *inode, loff_t offset, loff_t len) | |||
5573 | 5583 | ||
5574 | out_stop: | 5584 | out_stop: |
5575 | ext4_journal_stop(handle); | 5585 | ext4_journal_stop(handle); |
5576 | out_dio: | 5586 | out_mmap: |
5587 | up_write(&EXT4_I(inode)->i_mmap_sem); | ||
5577 | ext4_inode_resume_unlocked_dio(inode); | 5588 | ext4_inode_resume_unlocked_dio(inode); |
5578 | out_mutex: | 5589 | out_mutex: |
5579 | mutex_unlock(&inode->i_mutex); | 5590 | mutex_unlock(&inode->i_mutex); |
@@ -5627,21 +5638,7 @@ int ext4_insert_range(struct inode *inode, loff_t offset, loff_t len) | |||
5627 | return ret; | 5638 | return ret; |
5628 | } | 5639 | } |
5629 | 5640 | ||
5630 | /* | ||
5631 | * Need to round down to align start offset to page size boundary | ||
5632 | * for page size > block size. | ||
5633 | */ | ||
5634 | ioffset = round_down(offset, PAGE_SIZE); | ||
5635 | |||
5636 | /* Write out all dirty pages */ | ||
5637 | ret = filemap_write_and_wait_range(inode->i_mapping, ioffset, | ||
5638 | LLONG_MAX); | ||
5639 | if (ret) | ||
5640 | return ret; | ||
5641 | |||
5642 | /* Take mutex lock */ | ||
5643 | mutex_lock(&inode->i_mutex); | 5641 | mutex_lock(&inode->i_mutex); |
5644 | |||
5645 | /* Currently just for extent based files */ | 5642 | /* Currently just for extent based files */ |
5646 | if (!ext4_test_inode_flag(inode, EXT4_INODE_EXTENTS)) { | 5643 | if (!ext4_test_inode_flag(inode, EXT4_INODE_EXTENTS)) { |
5647 | ret = -EOPNOTSUPP; | 5644 | ret = -EOPNOTSUPP; |
@@ -5660,17 +5657,32 @@ int ext4_insert_range(struct inode *inode, loff_t offset, loff_t len) | |||
5660 | goto out_mutex; | 5657 | goto out_mutex; |
5661 | } | 5658 | } |
5662 | 5659 | ||
5663 | truncate_pagecache(inode, ioffset); | ||
5664 | |||
5665 | /* Wait for existing dio to complete */ | 5660 | /* Wait for existing dio to complete */ |
5666 | ext4_inode_block_unlocked_dio(inode); | 5661 | ext4_inode_block_unlocked_dio(inode); |
5667 | inode_dio_wait(inode); | 5662 | inode_dio_wait(inode); |
5668 | 5663 | ||
5664 | /* | ||
5665 | * Prevent page faults from reinstantiating pages we have released from | ||
5666 | * page cache. | ||
5667 | */ | ||
5668 | down_write(&EXT4_I(inode)->i_mmap_sem); | ||
5669 | /* | ||
5670 | * Need to round down to align start offset to page size boundary | ||
5671 | * for page size > block size. | ||
5672 | */ | ||
5673 | ioffset = round_down(offset, PAGE_SIZE); | ||
5674 | /* Write out all dirty pages */ | ||
5675 | ret = filemap_write_and_wait_range(inode->i_mapping, ioffset, | ||
5676 | LLONG_MAX); | ||
5677 | if (ret) | ||
5678 | goto out_mmap; | ||
5679 | truncate_pagecache(inode, ioffset); | ||
5680 | |||
5669 | credits = ext4_writepage_trans_blocks(inode); | 5681 | credits = ext4_writepage_trans_blocks(inode); |
5670 | handle = ext4_journal_start(inode, EXT4_HT_TRUNCATE, credits); | 5682 | handle = ext4_journal_start(inode, EXT4_HT_TRUNCATE, credits); |
5671 | if (IS_ERR(handle)) { | 5683 | if (IS_ERR(handle)) { |
5672 | ret = PTR_ERR(handle); | 5684 | ret = PTR_ERR(handle); |
5673 | goto out_dio; | 5685 | goto out_mmap; |
5674 | } | 5686 | } |
5675 | 5687 | ||
5676 | /* Expand file to avoid data loss if there is error while shifting */ | 5688 | /* Expand file to avoid data loss if there is error while shifting */ |
@@ -5741,7 +5753,8 @@ int ext4_insert_range(struct inode *inode, loff_t offset, loff_t len) | |||
5741 | 5753 | ||
5742 | out_stop: | 5754 | out_stop: |
5743 | ext4_journal_stop(handle); | 5755 | ext4_journal_stop(handle); |
5744 | out_dio: | 5756 | out_mmap: |
5757 | up_write(&EXT4_I(inode)->i_mmap_sem); | ||
5745 | ext4_inode_resume_unlocked_dio(inode); | 5758 | ext4_inode_resume_unlocked_dio(inode); |
5746 | out_mutex: | 5759 | out_mutex: |
5747 | mutex_unlock(&inode->i_mutex); | 5760 | mutex_unlock(&inode->i_mutex); |