@@ -4690,6 +4690,58 @@ static long ext4_zero_range(struct file *file, loff_t offset,
4690
4690
return ret ;
4691
4691
}
4692
4692
4693
+ static long ext4_do_fallocate (struct file * file , loff_t offset ,
4694
+ loff_t len , int mode )
4695
+ {
4696
+ struct inode * inode = file_inode (file );
4697
+ loff_t end = offset + len ;
4698
+ loff_t new_size = 0 ;
4699
+ ext4_lblk_t start_lblk , len_lblk ;
4700
+ int ret ;
4701
+
4702
+ trace_ext4_fallocate_enter (inode , offset , len , mode );
4703
+
4704
+ start_lblk = offset >> inode -> i_blkbits ;
4705
+ len_lblk = EXT4_MAX_BLOCKS (len , offset , inode -> i_blkbits );
4706
+
4707
+ inode_lock (inode );
4708
+
4709
+ /* We only support preallocation for extent-based files only. */
4710
+ if (!(ext4_test_inode_flag (inode , EXT4_INODE_EXTENTS ))) {
4711
+ ret = - EOPNOTSUPP ;
4712
+ goto out ;
4713
+ }
4714
+
4715
+ if (!(mode & FALLOC_FL_KEEP_SIZE ) &&
4716
+ (end > inode -> i_size || end > EXT4_I (inode )-> i_disksize )) {
4717
+ new_size = end ;
4718
+ ret = inode_newsize_ok (inode , new_size );
4719
+ if (ret )
4720
+ goto out ;
4721
+ }
4722
+
4723
+ /* Wait all existing dio workers, newcomers will block on i_rwsem */
4724
+ inode_dio_wait (inode );
4725
+
4726
+ ret = file_modified (file );
4727
+ if (ret )
4728
+ goto out ;
4729
+
4730
+ ret = ext4_alloc_file_blocks (file , start_lblk , len_lblk , new_size ,
4731
+ EXT4_GET_BLOCKS_CREATE_UNWRIT_EXT );
4732
+ if (ret )
4733
+ goto out ;
4734
+
4735
+ if (file -> f_flags & O_SYNC && EXT4_SB (inode -> i_sb )-> s_journal ) {
4736
+ ret = ext4_fc_commit (EXT4_SB (inode -> i_sb )-> s_journal ,
4737
+ EXT4_I (inode )-> i_sync_tid );
4738
+ }
4739
+ out :
4740
+ inode_unlock (inode );
4741
+ trace_ext4_fallocate_exit (inode , offset , len_lblk , ret );
4742
+ return ret ;
4743
+ }
4744
+
4693
4745
/*
4694
4746
* preallocate space for a file. This implements ext4's fallocate file
4695
4747
* operation, which gets called from sys_fallocate system call.
@@ -4700,12 +4752,7 @@ static long ext4_zero_range(struct file *file, loff_t offset,
4700
4752
long ext4_fallocate (struct file * file , int mode , loff_t offset , loff_t len )
4701
4753
{
4702
4754
struct inode * inode = file_inode (file );
4703
- loff_t new_size = 0 ;
4704
- unsigned int max_blocks ;
4705
- int ret = 0 ;
4706
- int flags ;
4707
- ext4_lblk_t lblk ;
4708
- unsigned int blkbits = inode -> i_blkbits ;
4755
+ int ret ;
4709
4756
4710
4757
/*
4711
4758
* Encrypted inodes can't handle collapse range or insert
@@ -4727,71 +4774,19 @@ long ext4_fallocate(struct file *file, int mode, loff_t offset, loff_t len)
4727
4774
ret = ext4_convert_inline_data (inode );
4728
4775
inode_unlock (inode );
4729
4776
if (ret )
4730
- goto exit ;
4777
+ return ret ;
4731
4778
4732
- if (mode & FALLOC_FL_PUNCH_HOLE ) {
4779
+ if (mode & FALLOC_FL_PUNCH_HOLE )
4733
4780
ret = ext4_punch_hole (file , offset , len );
4734
- goto exit ;
4735
- }
4736
-
4737
- if (mode & FALLOC_FL_COLLAPSE_RANGE ) {
4781
+ else if (mode & FALLOC_FL_COLLAPSE_RANGE )
4738
4782
ret = ext4_collapse_range (file , offset , len );
4739
- goto exit ;
4740
- }
4741
-
4742
- if (mode & FALLOC_FL_INSERT_RANGE ) {
4783
+ else if (mode & FALLOC_FL_INSERT_RANGE )
4743
4784
ret = ext4_insert_range (file , offset , len );
4744
- goto exit ;
4745
- }
4746
-
4747
- if (mode & FALLOC_FL_ZERO_RANGE ) {
4785
+ else if (mode & FALLOC_FL_ZERO_RANGE )
4748
4786
ret = ext4_zero_range (file , offset , len , mode );
4749
- goto exit ;
4750
- }
4751
- trace_ext4_fallocate_enter (inode , offset , len , mode );
4752
- lblk = offset >> blkbits ;
4753
-
4754
- max_blocks = EXT4_MAX_BLOCKS (len , offset , blkbits );
4755
- flags = EXT4_GET_BLOCKS_CREATE_UNWRIT_EXT ;
4756
-
4757
- inode_lock (inode );
4758
-
4759
- /*
4760
- * We only support preallocation for extent-based files only
4761
- */
4762
- if (!(ext4_test_inode_flag (inode , EXT4_INODE_EXTENTS ))) {
4763
- ret = - EOPNOTSUPP ;
4764
- goto out ;
4765
- }
4766
-
4767
- if (!(mode & FALLOC_FL_KEEP_SIZE ) &&
4768
- (offset + len > inode -> i_size ||
4769
- offset + len > EXT4_I (inode )-> i_disksize )) {
4770
- new_size = offset + len ;
4771
- ret = inode_newsize_ok (inode , new_size );
4772
- if (ret )
4773
- goto out ;
4774
- }
4775
-
4776
- /* Wait all existing dio workers, newcomers will block on i_rwsem */
4777
- inode_dio_wait (inode );
4778
-
4779
- ret = file_modified (file );
4780
- if (ret )
4781
- goto out ;
4782
-
4783
- ret = ext4_alloc_file_blocks (file , lblk , max_blocks , new_size , flags );
4784
- if (ret )
4785
- goto out ;
4787
+ else
4788
+ ret = ext4_do_fallocate (file , offset , len , mode );
4786
4789
4787
- if (file -> f_flags & O_SYNC && EXT4_SB (inode -> i_sb )-> s_journal ) {
4788
- ret = ext4_fc_commit (EXT4_SB (inode -> i_sb )-> s_journal ,
4789
- EXT4_I (inode )-> i_sync_tid );
4790
- }
4791
- out :
4792
- inode_unlock (inode );
4793
- trace_ext4_fallocate_exit (inode , offset , max_blocks , ret );
4794
- exit :
4795
4790
return ret ;
4796
4791
}
4797
4792
0 commit comments