@@ -4571,30 +4571,30 @@ int ext4_ext_truncate(handle_t *handle, struct inode *inode)
45714571 return err ;
45724572}
45734573
4574- static int ext4_alloc_file_blocks (struct file * file , ext4_lblk_t offset ,
4575- ext4_lblk_t len , loff_t new_size ,
4576- int flags )
4574+ static int ext4_alloc_file_blocks (struct file * file , loff_t offset , loff_t len ,
4575+ loff_t new_size , int flags )
45774576{
45784577 struct inode * inode = file_inode (file );
45794578 handle_t * handle ;
45804579 int ret = 0 , ret2 = 0 , ret3 = 0 ;
45814580 int retries = 0 ;
45824581 int depth = 0 ;
4582+ ext4_lblk_t len_lblk ;
45834583 struct ext4_map_blocks map ;
45844584 unsigned int credits ;
45854585 loff_t epos , old_size = i_size_read (inode );
45864586 unsigned int blkbits = inode -> i_blkbits ;
45874587 bool alloc_zero = false;
45884588
45894589 BUG_ON (!ext4_test_inode_flag (inode , EXT4_INODE_EXTENTS ));
4590- map .m_lblk = offset ;
4591- map .m_len = len ;
4590+ map .m_lblk = offset >> blkbits ;
4591+ map .m_len = len_lblk = EXT4_MAX_BLOCKS ( len , offset , blkbits ) ;
45924592 /*
45934593 * Don't normalize the request if it can fit in one extent so
45944594 * that it doesn't get unnecessarily split into multiple
45954595 * extents.
45964596 */
4597- if (len <= EXT_UNWRITTEN_MAX_LEN )
4597+ if (len_lblk <= EXT_UNWRITTEN_MAX_LEN )
45984598 flags |= EXT4_GET_BLOCKS_NO_NORMALIZE ;
45994599
46004600 /*
@@ -4611,16 +4611,16 @@ static int ext4_alloc_file_blocks(struct file *file, ext4_lblk_t offset,
46114611 /*
46124612 * credits to insert 1 extent into extent tree
46134613 */
4614- credits = ext4_chunk_trans_blocks (inode , len );
4614+ credits = ext4_chunk_trans_blocks (inode , len_lblk );
46154615 depth = ext_depth (inode );
46164616
46174617retry :
4618- while (len ) {
4618+ while (len_lblk ) {
46194619 /*
46204620 * Recalculate credits when extent tree depth changes.
46214621 */
46224622 if (depth != ext_depth (inode )) {
4623- credits = ext4_chunk_trans_blocks (inode , len );
4623+ credits = ext4_chunk_trans_blocks (inode , len_lblk );
46244624 depth = ext_depth (inode );
46254625 }
46264626
@@ -4677,7 +4677,7 @@ static int ext4_alloc_file_blocks(struct file *file, ext4_lblk_t offset,
46774677 }
46784678
46794679 map .m_lblk += ret ;
4680- map .m_len = len = len - ret ;
4680+ map .m_len = len_lblk = len_lblk - ret ;
46814681 }
46824682 if (ret == - ENOSPC && ext4_should_retry_alloc (inode -> i_sb , & retries ))
46834683 goto retry ;
@@ -4694,11 +4694,9 @@ static long ext4_zero_range(struct file *file, loff_t offset,
46944694{
46954695 struct inode * inode = file_inode (file );
46964696 handle_t * handle = NULL ;
4697- loff_t new_size = 0 ;
4697+ loff_t align_start , align_end , new_size = 0 ;
46984698 loff_t end = offset + len ;
4699- ext4_lblk_t start_lblk , end_lblk ;
47004699 unsigned int blocksize = i_blocksize (inode );
4701- unsigned int blkbits = inode -> i_blkbits ;
47024700 int ret , flags , credits ;
47034701
47044702 trace_ext4_zero_range (inode , offset , len , mode );
@@ -4719,11 +4717,8 @@ static long ext4_zero_range(struct file *file, loff_t offset,
47194717 flags = EXT4_GET_BLOCKS_CREATE_UNWRIT_EXT ;
47204718 /* Preallocate the range including the unaligned edges */
47214719 if (!IS_ALIGNED (offset | end , blocksize )) {
4722- ext4_lblk_t alloc_lblk = offset >> blkbits ;
4723- ext4_lblk_t len_lblk = EXT4_MAX_BLOCKS (len , offset , blkbits );
4724-
4725- ret = ext4_alloc_file_blocks (file , alloc_lblk , len_lblk ,
4726- new_size , flags );
4720+ ret = ext4_alloc_file_blocks (file , offset , len , new_size ,
4721+ flags );
47274722 if (ret )
47284723 return ret ;
47294724 }
@@ -4738,18 +4733,17 @@ static long ext4_zero_range(struct file *file, loff_t offset,
47384733 return ret ;
47394734
47404735 /* Zero range excluding the unaligned edges */
4741- start_lblk = EXT4_B_TO_LBLK (inode , offset );
4742- end_lblk = end >> blkbits ;
4743- if (end_lblk > start_lblk ) {
4744- ext4_lblk_t zero_blks = end_lblk - start_lblk ;
4745-
4736+ align_start = round_up (offset , blocksize );
4737+ align_end = round_down (end , blocksize );
4738+ if (align_end > align_start ) {
47464739 if (mode & FALLOC_FL_WRITE_ZEROES )
47474740 flags = EXT4_GET_BLOCKS_CREATE_ZERO | EXT4_EX_NOCACHE ;
47484741 else
47494742 flags |= (EXT4_GET_BLOCKS_CONVERT_UNWRITTEN |
47504743 EXT4_EX_NOCACHE );
4751- ret = ext4_alloc_file_blocks (file , start_lblk , zero_blks ,
4752- new_size , flags );
4744+ ret = ext4_alloc_file_blocks (file , align_start ,
4745+ align_end - align_start , new_size ,
4746+ flags );
47534747 if (ret )
47544748 return ret ;
47554749 }
@@ -4797,15 +4791,11 @@ static long ext4_do_fallocate(struct file *file, loff_t offset,
47974791 struct inode * inode = file_inode (file );
47984792 loff_t end = offset + len ;
47994793 loff_t new_size = 0 ;
4800- ext4_lblk_t start_lblk , len_lblk ;
48014794 int ret ;
48024795
48034796 trace_ext4_fallocate_enter (inode , offset , len , mode );
48044797 WARN_ON_ONCE (!inode_is_locked (inode ));
48054798
4806- start_lblk = offset >> inode -> i_blkbits ;
4807- len_lblk = EXT4_MAX_BLOCKS (len , offset , inode -> i_blkbits );
4808-
48094799 /* We only support preallocation for extent-based files only. */
48104800 if (!(ext4_test_inode_flag (inode , EXT4_INODE_EXTENTS ))) {
48114801 ret = - EOPNOTSUPP ;
@@ -4820,7 +4810,7 @@ static long ext4_do_fallocate(struct file *file, loff_t offset,
48204810 goto out ;
48214811 }
48224812
4823- ret = ext4_alloc_file_blocks (file , start_lblk , len_lblk , new_size ,
4813+ ret = ext4_alloc_file_blocks (file , offset , len , new_size ,
48244814 EXT4_GET_BLOCKS_CREATE_UNWRIT_EXT );
48254815 if (ret )
48264816 goto out ;
@@ -4830,7 +4820,8 @@ static long ext4_do_fallocate(struct file *file, loff_t offset,
48304820 EXT4_I (inode )-> i_sync_tid );
48314821 }
48324822out :
4833- trace_ext4_fallocate_exit (inode , offset , len_lblk , ret );
4823+ trace_ext4_fallocate_exit (inode , offset ,
4824+ EXT4_MAX_BLOCKS (len , offset , inode -> i_blkbits ), ret );
48344825 return ret ;
48354826}
48364827
0 commit comments