@@ -3553,74 +3553,32 @@ static int ext4_iomap_alloc(struct inode *inode, struct ext4_map_blocks *map,
3553
3553
static int ext4_iomap_begin (struct inode * inode , loff_t offset , loff_t length ,
3554
3554
unsigned flags , struct iomap * iomap , struct iomap * srcmap )
3555
3555
{
3556
- unsigned int blkbits = inode -> i_blkbits ;
3557
- unsigned long first_block , last_block ;
3558
- struct ext4_map_blocks map ;
3559
- bool delalloc = false;
3560
3556
int ret ;
3557
+ struct ext4_map_blocks map ;
3558
+ u8 blkbits = inode -> i_blkbits ;
3561
3559
3562
3560
if ((offset >> blkbits ) > EXT4_MAX_LOGICAL_BLOCK )
3563
3561
return - EINVAL ;
3564
- first_block = offset >> blkbits ;
3565
- last_block = min_t (loff_t , (offset + length - 1 ) >> blkbits ,
3566
- EXT4_MAX_LOGICAL_BLOCK );
3567
-
3568
- if (flags & IOMAP_REPORT ) {
3569
- if (ext4_has_inline_data (inode )) {
3570
- ret = ext4_inline_data_iomap (inode , iomap );
3571
- if (ret != - EAGAIN ) {
3572
- if (ret == 0 && offset >= iomap -> length )
3573
- ret = - ENOENT ;
3574
- return ret ;
3575
- }
3576
- }
3577
- } else {
3578
- if (WARN_ON_ONCE (ext4_has_inline_data (inode )))
3579
- return - ERANGE ;
3580
- }
3581
3562
3582
- map .m_lblk = first_block ;
3583
- map .m_len = last_block - first_block + 1 ;
3584
-
3585
- if (flags & IOMAP_REPORT ) {
3586
- ret = ext4_map_blocks (NULL , inode , & map , 0 );
3587
- if (ret < 0 )
3588
- return ret ;
3589
-
3590
- if (ret == 0 ) {
3591
- ext4_lblk_t end = map .m_lblk + map .m_len - 1 ;
3592
- struct extent_status es ;
3593
-
3594
- ext4_es_find_extent_range (inode , & ext4_es_is_delayed ,
3595
- map .m_lblk , end , & es );
3563
+ if (WARN_ON_ONCE (ext4_has_inline_data (inode )))
3564
+ return - ERANGE ;
3596
3565
3597
- if (!es .es_len || es .es_lblk > end ) {
3598
- /* entire range is a hole */
3599
- } else if (es .es_lblk > map .m_lblk ) {
3600
- /* range starts with a hole */
3601
- map .m_len = es .es_lblk - map .m_lblk ;
3602
- } else {
3603
- ext4_lblk_t offs = 0 ;
3566
+ /*
3567
+ * Calculate the first and last logical blocks respectively.
3568
+ */
3569
+ map .m_lblk = offset >> blkbits ;
3570
+ map .m_len = min_t (loff_t , (offset + length - 1 ) >> blkbits ,
3571
+ EXT4_MAX_LOGICAL_BLOCK ) - map .m_lblk + 1 ;
3604
3572
3605
- if (es .es_lblk < map .m_lblk )
3606
- offs = map .m_lblk - es .es_lblk ;
3607
- map .m_lblk = es .es_lblk + offs ;
3608
- map .m_len = es .es_len - offs ;
3609
- delalloc = true;
3610
- }
3611
- }
3612
- } else if (flags & IOMAP_WRITE ) {
3573
+ if (flags & IOMAP_WRITE )
3613
3574
ret = ext4_iomap_alloc (inode , & map , flags );
3614
- } else {
3575
+ else
3615
3576
ret = ext4_map_blocks (NULL , inode , & map , 0 );
3616
- }
3617
3577
3618
3578
if (ret < 0 )
3619
3579
return ret ;
3620
3580
3621
3581
ext4_set_iomap (inode , iomap , & map , offset , length );
3622
- if (delalloc && iomap -> type == IOMAP_HOLE )
3623
- iomap -> type = IOMAP_DELALLOC ;
3624
3582
3625
3583
return 0 ;
3626
3584
}
@@ -3682,6 +3640,74 @@ const struct iomap_ops ext4_iomap_ops = {
3682
3640
.iomap_end = ext4_iomap_end ,
3683
3641
};
3684
3642
3643
+ static bool ext4_iomap_is_delalloc (struct inode * inode ,
3644
+ struct ext4_map_blocks * map )
3645
+ {
3646
+ struct extent_status es ;
3647
+ ext4_lblk_t offset = 0 , end = map -> m_lblk + map -> m_len - 1 ;
3648
+
3649
+ ext4_es_find_extent_range (inode , & ext4_es_is_delayed ,
3650
+ map -> m_lblk , end , & es );
3651
+
3652
+ if (!es .es_len || es .es_lblk > end )
3653
+ return false;
3654
+
3655
+ if (es .es_lblk > map -> m_lblk ) {
3656
+ map -> m_len = es .es_lblk - map -> m_lblk ;
3657
+ return false;
3658
+ }
3659
+
3660
+ offset = map -> m_lblk - es .es_lblk ;
3661
+ map -> m_len = es .es_len - offset ;
3662
+
3663
+ return true;
3664
+ }
3665
+
3666
+ static int ext4_iomap_begin_report (struct inode * inode , loff_t offset ,
3667
+ loff_t length , unsigned int flags ,
3668
+ struct iomap * iomap , struct iomap * srcmap )
3669
+ {
3670
+ int ret ;
3671
+ bool delalloc = false;
3672
+ struct ext4_map_blocks map ;
3673
+ u8 blkbits = inode -> i_blkbits ;
3674
+
3675
+ if ((offset >> blkbits ) > EXT4_MAX_LOGICAL_BLOCK )
3676
+ return - EINVAL ;
3677
+
3678
+ if (ext4_has_inline_data (inode )) {
3679
+ ret = ext4_inline_data_iomap (inode , iomap );
3680
+ if (ret != - EAGAIN ) {
3681
+ if (ret == 0 && offset >= iomap -> length )
3682
+ ret = - ENOENT ;
3683
+ return ret ;
3684
+ }
3685
+ }
3686
+
3687
+ /*
3688
+ * Calculate the first and last logical block respectively.
3689
+ */
3690
+ map .m_lblk = offset >> blkbits ;
3691
+ map .m_len = min_t (loff_t , (offset + length - 1 ) >> blkbits ,
3692
+ EXT4_MAX_LOGICAL_BLOCK ) - map .m_lblk + 1 ;
3693
+
3694
+ ret = ext4_map_blocks (NULL , inode , & map , 0 );
3695
+ if (ret < 0 )
3696
+ return ret ;
3697
+ if (ret == 0 )
3698
+ delalloc = ext4_iomap_is_delalloc (inode , & map );
3699
+
3700
+ ext4_set_iomap (inode , iomap , & map , offset , length );
3701
+ if (delalloc && iomap -> type == IOMAP_HOLE )
3702
+ iomap -> type = IOMAP_DELALLOC ;
3703
+
3704
+ return 0 ;
3705
+ }
3706
+
3707
+ const struct iomap_ops ext4_iomap_report_ops = {
3708
+ .iomap_begin = ext4_iomap_begin_report ,
3709
+ };
3710
+
3685
3711
static int ext4_end_io_dio (struct kiocb * iocb , loff_t offset ,
3686
3712
ssize_t size , void * private )
3687
3713
{
0 commit comments