aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ext4/inode.c
diff options
context:
space:
mode:
authorTheodore Ts'o <tytso@mit.edu>2013-04-03 12:47:17 -0400
committerTheodore Ts'o <tytso@mit.edu>2013-04-03 12:47:17 -0400
commit819c4920b7e60ecfd6f0f61d890af4cdf3873d18 (patch)
tree85f995b14c7308080d196d85b9b3d148337a6382 /fs/ext4/inode.c
parent26a4c0c6ccecf6814cf44f951c97222bd795bc1a (diff)
ext4: refactor truncate code
Move common code in ext4_ind_truncate() and ext4_ext_truncate() into ext4_truncate(). This saves over 60 lines of code. Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
Diffstat (limited to 'fs/ext4/inode.c')
-rw-r--r--fs/ext4/inode.c74
1 files changed, 71 insertions, 3 deletions
diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
index 9bda50aa34e2..49c80e4ac5ac 100644
--- a/fs/ext4/inode.c
+++ b/fs/ext4/inode.c
@@ -3738,9 +3738,9 @@ int ext4_punch_hole(struct file *file, loff_t offset, loff_t length)
3738 stop_block); 3738 stop_block);
3739 3739
3740 ext4_discard_preallocations(inode); 3740 ext4_discard_preallocations(inode);
3741 up_write(&EXT4_I(inode)->i_data_sem);
3741 if (IS_SYNC(inode)) 3742 if (IS_SYNC(inode))
3742 ext4_handle_sync(handle); 3743 ext4_handle_sync(handle);
3743 up_write(&EXT4_I(inode)->i_data_sem);
3744 inode->i_mtime = inode->i_ctime = ext4_current_time(inode); 3744 inode->i_mtime = inode->i_ctime = ext4_current_time(inode);
3745 ext4_mark_inode_dirty(handle, inode); 3745 ext4_mark_inode_dirty(handle, inode);
3746out_stop: 3746out_stop:
@@ -3782,6 +3782,12 @@ out_mutex:
3782 */ 3782 */
3783void ext4_truncate(struct inode *inode) 3783void ext4_truncate(struct inode *inode)
3784{ 3784{
3785 struct ext4_inode_info *ei = EXT4_I(inode);
3786 unsigned int credits;
3787 handle_t *handle;
3788 struct address_space *mapping = inode->i_mapping;
3789 loff_t page_len;
3790
3785 trace_ext4_truncate_enter(inode); 3791 trace_ext4_truncate_enter(inode);
3786 3792
3787 if (!ext4_can_truncate(inode)) 3793 if (!ext4_can_truncate(inode))
@@ -3800,10 +3806,72 @@ void ext4_truncate(struct inode *inode)
3800 return; 3806 return;
3801 } 3807 }
3802 3808
3809 /*
3810 * finish any pending end_io work so we won't run the risk of
3811 * converting any truncated blocks to initialized later
3812 */
3813 ext4_flush_unwritten_io(inode);
3814
3815 if (ext4_test_inode_flag(inode, EXT4_INODE_EXTENTS))
3816 credits = ext4_writepage_trans_blocks(inode);
3817 else
3818 credits = ext4_blocks_for_truncate(inode);
3819
3820 handle = ext4_journal_start(inode, EXT4_HT_TRUNCATE, credits);
3821 if (IS_ERR(handle)) {
3822 ext4_std_error(inode->i_sb, PTR_ERR(handle));
3823 return;
3824 }
3825
3826 if (inode->i_size % PAGE_CACHE_SIZE != 0) {
3827 page_len = PAGE_CACHE_SIZE -
3828 (inode->i_size & (PAGE_CACHE_SIZE - 1));
3829
3830 if (ext4_discard_partial_page_buffers(handle,
3831 mapping, inode->i_size, page_len, 0))
3832 goto out_stop;
3833 }
3834
3835 /*
3836 * We add the inode to the orphan list, so that if this
3837 * truncate spans multiple transactions, and we crash, we will
3838 * resume the truncate when the filesystem recovers. It also
3839 * marks the inode dirty, to catch the new size.
3840 *
3841 * Implication: the file must always be in a sane, consistent
3842 * truncatable state while each transaction commits.
3843 */
3844 if (ext4_orphan_add(handle, inode))
3845 goto out_stop;
3846
3847 down_write(&EXT4_I(inode)->i_data_sem);
3848
3849 ext4_discard_preallocations(inode);
3850
3803 if (ext4_test_inode_flag(inode, EXT4_INODE_EXTENTS)) 3851 if (ext4_test_inode_flag(inode, EXT4_INODE_EXTENTS))
3804 ext4_ext_truncate(inode); 3852 ext4_ext_truncate(handle, inode);
3805 else 3853 else
3806 ext4_ind_truncate(inode); 3854 ext4_ind_truncate(handle, inode);
3855
3856 up_write(&ei->i_data_sem);
3857
3858 if (IS_SYNC(inode))
3859 ext4_handle_sync(handle);
3860
3861out_stop:
3862 /*
3863 * If this was a simple ftruncate() and the file will remain alive,
3864 * then we need to clear up the orphan record which we created above.
3865 * However, if this was a real unlink then we were called by
3866 * ext4_delete_inode(), and we allow that function to clean up the
3867 * orphan info for us.
3868 */
3869 if (inode->i_nlink)
3870 ext4_orphan_del(handle, inode);
3871
3872 inode->i_mtime = inode->i_ctime = ext4_current_time(inode);
3873 ext4_mark_inode_dirty(handle, inode);
3874 ext4_journal_stop(handle);
3807 3875
3808 trace_ext4_truncate_exit(inode); 3876 trace_ext4_truncate_exit(inode);
3809} 3877}