@@ -3448,10 +3448,54 @@ static bool ext4_inode_datasync_dirty(struct inode *inode)
3448
3448
return inode -> i_state & I_DIRTY_DATASYNC ;
3449
3449
}
3450
3450
3451
+ static void ext4_set_iomap (struct inode * inode , struct iomap * iomap ,
3452
+ struct ext4_map_blocks * map , loff_t offset ,
3453
+ loff_t length )
3454
+ {
3455
+ u8 blkbits = inode -> i_blkbits ;
3456
+
3457
+ /*
3458
+ * Writes that span EOF might trigger an I/O size update on completion,
3459
+ * so consider them to be dirty for the purpose of O_DSYNC, even if
3460
+ * there is no other metadata changes being made or are pending.
3461
+ */
3462
+ iomap -> flags = 0 ;
3463
+ if (ext4_inode_datasync_dirty (inode ) ||
3464
+ offset + length > i_size_read (inode ))
3465
+ iomap -> flags |= IOMAP_F_DIRTY ;
3466
+
3467
+ if (map -> m_flags & EXT4_MAP_NEW )
3468
+ iomap -> flags |= IOMAP_F_NEW ;
3469
+
3470
+ iomap -> bdev = inode -> i_sb -> s_bdev ;
3471
+ iomap -> dax_dev = EXT4_SB (inode -> i_sb )-> s_daxdev ;
3472
+ iomap -> offset = (u64 ) map -> m_lblk << blkbits ;
3473
+ iomap -> length = (u64 ) map -> m_len << blkbits ;
3474
+
3475
+ /*
3476
+ * Flags passed to ext4_map_blocks() for direct I/O writes can result
3477
+ * in m_flags having both EXT4_MAP_MAPPED and EXT4_MAP_UNWRITTEN bits
3478
+ * set. In order for any allocated unwritten extents to be converted
3479
+ * into written extents correctly within the ->end_io() handler, we
3480
+ * need to ensure that the iomap->type is set appropriately. Hence, the
3481
+ * reason why we need to check whether the EXT4_MAP_UNWRITTEN bit has
3482
+ * been set first.
3483
+ */
3484
+ if (map -> m_flags & EXT4_MAP_UNWRITTEN ) {
3485
+ iomap -> type = IOMAP_UNWRITTEN ;
3486
+ iomap -> addr = (u64 ) map -> m_pblk << blkbits ;
3487
+ } else if (map -> m_flags & EXT4_MAP_MAPPED ) {
3488
+ iomap -> type = IOMAP_MAPPED ;
3489
+ iomap -> addr = (u64 ) map -> m_pblk << blkbits ;
3490
+ } else {
3491
+ iomap -> type = IOMAP_HOLE ;
3492
+ iomap -> addr = IOMAP_NULL_ADDR ;
3493
+ }
3494
+ }
3495
+
3451
3496
static int ext4_iomap_begin (struct inode * inode , loff_t offset , loff_t length ,
3452
3497
unsigned flags , struct iomap * iomap , struct iomap * srcmap )
3453
3498
{
3454
- struct ext4_sb_info * sbi = EXT4_SB (inode -> i_sb );
3455
3499
unsigned int blkbits = inode -> i_blkbits ;
3456
3500
unsigned long first_block , last_block ;
3457
3501
struct ext4_map_blocks map ;
@@ -3565,47 +3609,9 @@ static int ext4_iomap_begin(struct inode *inode, loff_t offset, loff_t length,
3565
3609
return ret ;
3566
3610
}
3567
3611
3568
- /*
3569
- * Writes that span EOF might trigger an I/O size update on completion,
3570
- * so consider them to be dirty for the purposes of O_DSYNC, even if
3571
- * there is no other metadata changes being made or are pending here.
3572
- */
3573
- iomap -> flags = 0 ;
3574
- if (ext4_inode_datasync_dirty (inode ) ||
3575
- offset + length > i_size_read (inode ))
3576
- iomap -> flags |= IOMAP_F_DIRTY ;
3577
- iomap -> bdev = inode -> i_sb -> s_bdev ;
3578
- iomap -> dax_dev = sbi -> s_daxdev ;
3579
- iomap -> offset = (u64 )first_block << blkbits ;
3580
- iomap -> length = (u64 )map .m_len << blkbits ;
3581
-
3582
- if (ret == 0 ) {
3583
- iomap -> type = delalloc ? IOMAP_DELALLOC : IOMAP_HOLE ;
3584
- iomap -> addr = IOMAP_NULL_ADDR ;
3585
- } else {
3586
- /*
3587
- * Flags passed into ext4_map_blocks() for direct I/O writes
3588
- * can result in m_flags having both EXT4_MAP_MAPPED and
3589
- * EXT4_MAP_UNWRITTEN bits set. In order for any allocated
3590
- * unwritten extents to be converted into written extents
3591
- * correctly within the ->end_io() handler, we need to ensure
3592
- * that the iomap->type is set appropriately. Hence the reason
3593
- * why we need to check whether EXT4_MAP_UNWRITTEN is set
3594
- * first.
3595
- */
3596
- if (map .m_flags & EXT4_MAP_UNWRITTEN ) {
3597
- iomap -> type = IOMAP_UNWRITTEN ;
3598
- } else if (map .m_flags & EXT4_MAP_MAPPED ) {
3599
- iomap -> type = IOMAP_MAPPED ;
3600
- } else {
3601
- WARN_ON_ONCE (1 );
3602
- return - EIO ;
3603
- }
3604
- iomap -> addr = (u64 )map .m_pblk << blkbits ;
3605
- }
3606
-
3607
- if (map .m_flags & EXT4_MAP_NEW )
3608
- iomap -> flags |= IOMAP_F_NEW ;
3612
+ ext4_set_iomap (inode , iomap , & map , offset , length );
3613
+ if (delalloc && iomap -> type == IOMAP_HOLE )
3614
+ iomap -> type = IOMAP_DELALLOC ;
3609
3615
3610
3616
return 0 ;
3611
3617
}
0 commit comments