@@ -5421,53 +5421,45 @@ static int ext4_insert_range(struct file *file, loff_t offset, loff_t len)
5421
5421
handle_t * handle ;
5422
5422
struct ext4_ext_path * path ;
5423
5423
struct ext4_extent * extent ;
5424
- ext4_lblk_t offset_lblk , len_lblk , ee_start_lblk = 0 ;
5424
+ ext4_lblk_t start_lblk , len_lblk , ee_start_lblk = 0 ;
5425
5425
unsigned int credits , ee_len ;
5426
- int ret = 0 , depth , split_flag = 0 ;
5427
- loff_t ioffset ;
5428
-
5429
- /*
5430
- * We need to test this early because xfstests assumes that an
5431
- * insert range of (0, 1) will return EOPNOTSUPP if the file
5432
- * system does not support insert range.
5433
- */
5434
- if (!ext4_test_inode_flag (inode , EXT4_INODE_EXTENTS ))
5435
- return - EOPNOTSUPP ;
5436
-
5437
- /* Insert range works only on fs cluster size aligned regions. */
5438
- if (!IS_ALIGNED (offset | len , EXT4_CLUSTER_SIZE (sb )))
5439
- return - EINVAL ;
5426
+ int ret , depth , split_flag = 0 ;
5427
+ loff_t start ;
5440
5428
5441
5429
trace_ext4_insert_range (inode , offset , len );
5442
5430
5443
- offset_lblk = offset >> EXT4_BLOCK_SIZE_BITS (sb );
5444
- len_lblk = len >> EXT4_BLOCK_SIZE_BITS (sb );
5445
-
5446
5431
inode_lock (inode );
5432
+
5447
5433
/* Currently just for extent based files */
5448
5434
if (!ext4_test_inode_flag (inode , EXT4_INODE_EXTENTS )) {
5449
5435
ret = - EOPNOTSUPP ;
5450
- goto out_mutex ;
5436
+ goto out ;
5451
5437
}
5452
5438
5453
- /* Check whether the maximum file size would be exceeded */
5454
- if (len > inode -> i_sb -> s_maxbytes - inode -> i_size ) {
5455
- ret = - EFBIG ;
5456
- goto out_mutex ;
5439
+ /* Insert range works only on fs cluster size aligned regions. */
5440
+ if (! IS_ALIGNED ( offset | len , EXT4_CLUSTER_SIZE ( sb )) ) {
5441
+ ret = - EINVAL ;
5442
+ goto out ;
5457
5443
}
5458
5444
5459
5445
/* Offset must be less than i_size */
5460
5446
if (offset >= inode -> i_size ) {
5461
5447
ret = - EINVAL ;
5462
- goto out_mutex ;
5448
+ goto out ;
5449
+ }
5450
+
5451
+ /* Check whether the maximum file size would be exceeded */
5452
+ if (len > inode -> i_sb -> s_maxbytes - inode -> i_size ) {
5453
+ ret = - EFBIG ;
5454
+ goto out ;
5463
5455
}
5464
5456
5465
5457
/* Wait for existing dio to complete */
5466
5458
inode_dio_wait (inode );
5467
5459
5468
5460
ret = file_modified (file );
5469
5461
if (ret )
5470
- goto out_mutex ;
5462
+ goto out ;
5471
5463
5472
5464
/*
5473
5465
* Prevent page faults from reinstantiating pages we have released from
@@ -5477,25 +5469,24 @@ static int ext4_insert_range(struct file *file, loff_t offset, loff_t len)
5477
5469
5478
5470
ret = ext4_break_layouts (inode );
5479
5471
if (ret )
5480
- goto out_mmap ;
5472
+ goto out_invalidate_lock ;
5481
5473
5482
5474
/*
5483
- * Need to round down to align start offset to page size boundary
5484
- * for page size > block size.
5475
+ * Write out all dirty pages. Need to round down to align start offset
5476
+ * to page size boundary for page size > block size.
5485
5477
*/
5486
- ioffset = round_down (offset , PAGE_SIZE );
5487
- /* Write out all dirty pages */
5488
- ret = filemap_write_and_wait_range (inode -> i_mapping , ioffset ,
5489
- LLONG_MAX );
5478
+ start = round_down (offset , PAGE_SIZE );
5479
+ ret = filemap_write_and_wait_range (mapping , start , LLONG_MAX );
5490
5480
if (ret )
5491
- goto out_mmap ;
5492
- truncate_pagecache (inode , ioffset );
5481
+ goto out_invalidate_lock ;
5482
+
5483
+ truncate_pagecache (inode , start );
5493
5484
5494
5485
credits = ext4_writepage_trans_blocks (inode );
5495
5486
handle = ext4_journal_start (inode , EXT4_HT_TRUNCATE , credits );
5496
5487
if (IS_ERR (handle )) {
5497
5488
ret = PTR_ERR (handle );
5498
- goto out_mmap ;
5489
+ goto out_invalidate_lock ;
5499
5490
}
5500
5491
ext4_fc_mark_ineligible (sb , EXT4_FC_REASON_FALLOC_RANGE , handle );
5501
5492
@@ -5504,16 +5495,19 @@ static int ext4_insert_range(struct file *file, loff_t offset, loff_t len)
5504
5495
EXT4_I (inode )-> i_disksize += len ;
5505
5496
ret = ext4_mark_inode_dirty (handle , inode );
5506
5497
if (ret )
5507
- goto out_stop ;
5498
+ goto out_handle ;
5499
+
5500
+ start_lblk = offset >> inode -> i_blkbits ;
5501
+ len_lblk = len >> inode -> i_blkbits ;
5508
5502
5509
5503
down_write (& EXT4_I (inode )-> i_data_sem );
5510
5504
ext4_discard_preallocations (inode );
5511
5505
5512
- path = ext4_find_extent (inode , offset_lblk , NULL , 0 );
5506
+ path = ext4_find_extent (inode , start_lblk , NULL , 0 );
5513
5507
if (IS_ERR (path )) {
5514
5508
up_write (& EXT4_I (inode )-> i_data_sem );
5515
5509
ret = PTR_ERR (path );
5516
- goto out_stop ;
5510
+ goto out_handle ;
5517
5511
}
5518
5512
5519
5513
depth = ext_depth (inode );
@@ -5523,16 +5517,16 @@ static int ext4_insert_range(struct file *file, loff_t offset, loff_t len)
5523
5517
ee_len = ext4_ext_get_actual_len (extent );
5524
5518
5525
5519
/*
5526
- * If offset_lblk is not the starting block of extent, split
5527
- * the extent @offset_lblk
5520
+ * If start_lblk is not the starting block of extent, split
5521
+ * the extent @start_lblk
5528
5522
*/
5529
- if ((offset_lblk > ee_start_lblk ) &&
5530
- (offset_lblk < (ee_start_lblk + ee_len ))) {
5523
+ if ((start_lblk > ee_start_lblk ) &&
5524
+ (start_lblk < (ee_start_lblk + ee_len ))) {
5531
5525
if (ext4_ext_is_unwritten (extent ))
5532
5526
split_flag = EXT4_EXT_MARK_UNWRIT1 |
5533
5527
EXT4_EXT_MARK_UNWRIT2 ;
5534
5528
path = ext4_split_extent_at (handle , inode , path ,
5535
- offset_lblk , split_flag ,
5529
+ start_lblk , split_flag ,
5536
5530
EXT4_EX_NOCACHE |
5537
5531
EXT4_GET_BLOCKS_PRE_IO |
5538
5532
EXT4_GET_BLOCKS_METADATA_NOFAIL );
@@ -5541,31 +5535,32 @@ static int ext4_insert_range(struct file *file, loff_t offset, loff_t len)
5541
5535
if (IS_ERR (path )) {
5542
5536
up_write (& EXT4_I (inode )-> i_data_sem );
5543
5537
ret = PTR_ERR (path );
5544
- goto out_stop ;
5538
+ goto out_handle ;
5545
5539
}
5546
5540
}
5547
5541
5548
5542
ext4_free_ext_path (path );
5549
- ext4_es_remove_extent (inode , offset_lblk , EXT_MAX_BLOCKS - offset_lblk );
5543
+ ext4_es_remove_extent (inode , start_lblk , EXT_MAX_BLOCKS - start_lblk );
5550
5544
5551
5545
/*
5552
- * if offset_lblk lies in a hole which is at start of file, use
5546
+ * if start_lblk lies in a hole which is at start of file, use
5553
5547
* ee_start_lblk to shift extents
5554
5548
*/
5555
5549
ret = ext4_ext_shift_extents (inode , handle ,
5556
- max (ee_start_lblk , offset_lblk ), len_lblk , SHIFT_RIGHT );
5557
-
5550
+ max (ee_start_lblk , start_lblk ), len_lblk , SHIFT_RIGHT );
5558
5551
up_write (& EXT4_I (inode )-> i_data_sem );
5552
+ if (ret )
5553
+ goto out_handle ;
5554
+
5555
+ ext4_update_inode_fsync_trans (handle , inode , 1 );
5559
5556
if (IS_SYNC (inode ))
5560
5557
ext4_handle_sync (handle );
5561
- if (ret >= 0 )
5562
- ext4_update_inode_fsync_trans (handle , inode , 1 );
5563
5558
5564
- out_stop :
5559
+ out_handle :
5565
5560
ext4_journal_stop (handle );
5566
- out_mmap :
5561
+ out_invalidate_lock :
5567
5562
filemap_invalidate_unlock (mapping );
5568
- out_mutex :
5563
+ out :
5569
5564
inode_unlock (inode );
5570
5565
return ret ;
5571
5566
}
0 commit comments