@@ -5421,53 +5421,45 @@ static int ext4_insert_range(struct file *file, loff_t offset, loff_t len)
54215421 handle_t * handle ;
54225422 struct ext4_ext_path * path ;
54235423 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 ;
54255425 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 ;
54405428
54415429 trace_ext4_insert_range (inode , offset , len );
54425430
5443- offset_lblk = offset >> EXT4_BLOCK_SIZE_BITS (sb );
5444- len_lblk = len >> EXT4_BLOCK_SIZE_BITS (sb );
5445-
54465431 inode_lock (inode );
5432+
54475433 /* Currently just for extent based files */
54485434 if (!ext4_test_inode_flag (inode , EXT4_INODE_EXTENTS )) {
54495435 ret = - EOPNOTSUPP ;
5450- goto out_mutex ;
5436+ goto out ;
54515437 }
54525438
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 ;
54575443 }
54585444
54595445 /* Offset must be less than i_size */
54605446 if (offset >= inode -> i_size ) {
54615447 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 ;
54635455 }
54645456
54655457 /* Wait for existing dio to complete */
54665458 inode_dio_wait (inode );
54675459
54685460 ret = file_modified (file );
54695461 if (ret )
5470- goto out_mutex ;
5462+ goto out ;
54715463
54725464 /*
54735465 * 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)
54775469
54785470 ret = ext4_break_layouts (inode );
54795471 if (ret )
5480- goto out_mmap ;
5472+ goto out_invalidate_lock ;
54815473
54825474 /*
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.
54855477 */
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 );
54905480 if (ret )
5491- goto out_mmap ;
5492- truncate_pagecache (inode , ioffset );
5481+ goto out_invalidate_lock ;
5482+
5483+ truncate_pagecache (inode , start );
54935484
54945485 credits = ext4_writepage_trans_blocks (inode );
54955486 handle = ext4_journal_start (inode , EXT4_HT_TRUNCATE , credits );
54965487 if (IS_ERR (handle )) {
54975488 ret = PTR_ERR (handle );
5498- goto out_mmap ;
5489+ goto out_invalidate_lock ;
54995490 }
55005491 ext4_fc_mark_ineligible (sb , EXT4_FC_REASON_FALLOC_RANGE , handle );
55015492
@@ -5504,16 +5495,19 @@ static int ext4_insert_range(struct file *file, loff_t offset, loff_t len)
55045495 EXT4_I (inode )-> i_disksize += len ;
55055496 ret = ext4_mark_inode_dirty (handle , inode );
55065497 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 ;
55085502
55095503 down_write (& EXT4_I (inode )-> i_data_sem );
55105504 ext4_discard_preallocations (inode );
55115505
5512- path = ext4_find_extent (inode , offset_lblk , NULL , 0 );
5506+ path = ext4_find_extent (inode , start_lblk , NULL , 0 );
55135507 if (IS_ERR (path )) {
55145508 up_write (& EXT4_I (inode )-> i_data_sem );
55155509 ret = PTR_ERR (path );
5516- goto out_stop ;
5510+ goto out_handle ;
55175511 }
55185512
55195513 depth = ext_depth (inode );
@@ -5523,16 +5517,16 @@ static int ext4_insert_range(struct file *file, loff_t offset, loff_t len)
55235517 ee_len = ext4_ext_get_actual_len (extent );
55245518
55255519 /*
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
55285522 */
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 ))) {
55315525 if (ext4_ext_is_unwritten (extent ))
55325526 split_flag = EXT4_EXT_MARK_UNWRIT1 |
55335527 EXT4_EXT_MARK_UNWRIT2 ;
55345528 path = ext4_split_extent_at (handle , inode , path ,
5535- offset_lblk , split_flag ,
5529+ start_lblk , split_flag ,
55365530 EXT4_EX_NOCACHE |
55375531 EXT4_GET_BLOCKS_PRE_IO |
55385532 EXT4_GET_BLOCKS_METADATA_NOFAIL );
@@ -5541,31 +5535,32 @@ static int ext4_insert_range(struct file *file, loff_t offset, loff_t len)
55415535 if (IS_ERR (path )) {
55425536 up_write (& EXT4_I (inode )-> i_data_sem );
55435537 ret = PTR_ERR (path );
5544- goto out_stop ;
5538+ goto out_handle ;
55455539 }
55465540 }
55475541
55485542 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 );
55505544
55515545 /*
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
55535547 * ee_start_lblk to shift extents
55545548 */
55555549 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 );
55585551 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 );
55595556 if (IS_SYNC (inode ))
55605557 ext4_handle_sync (handle );
5561- if (ret >= 0 )
5562- ext4_update_inode_fsync_trans (handle , inode , 1 );
55635558
5564- out_stop :
5559+ out_handle :
55655560 ext4_journal_stop (handle );
5566- out_mmap :
5561+ out_invalidate_lock :
55675562 filemap_invalidate_unlock (mapping );
5568- out_mutex :
5563+ out :
55695564 inode_unlock (inode );
55705565 return ret ;
55715566}
0 commit comments