Skip to content

Commit c8fdfe2

Browse files
matthewbobrowskitytso
authored andcommitted
ext4: move set iomap routines into a separate helper ext4_set_iomap()
Separate the iomap field population code that is currently within ext4_iomap_begin() into a separate helper ext4_set_iomap(). The intent of this function is self explanatory, however the rationale behind taking this step is to reeduce the overall clutter that we currently have within the ext4_iomap_begin() callback. Signed-off-by: Matthew Bobrowski <[email protected]> Reviewed-by: Jan Kara <[email protected]> Reviewed-by: Ritesh Harjani <[email protected]> Link: https://lore.kernel.org/r/1ea34da65eecffcddffb2386668ae06134e8deaf.1572949325.git.mbobrowski@mbobrowski.org Signed-off-by: Theodore Ts'o <[email protected]>
1 parent 2e9b51d commit c8fdfe2

File tree

1 file changed

+48
-42
lines changed

1 file changed

+48
-42
lines changed

fs/ext4/inode.c

Lines changed: 48 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -3448,10 +3448,54 @@ static bool ext4_inode_datasync_dirty(struct inode *inode)
34483448
return inode->i_state & I_DIRTY_DATASYNC;
34493449
}
34503450

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+
34513496
static int ext4_iomap_begin(struct inode *inode, loff_t offset, loff_t length,
34523497
unsigned flags, struct iomap *iomap, struct iomap *srcmap)
34533498
{
3454-
struct ext4_sb_info *sbi = EXT4_SB(inode->i_sb);
34553499
unsigned int blkbits = inode->i_blkbits;
34563500
unsigned long first_block, last_block;
34573501
struct ext4_map_blocks map;
@@ -3565,47 +3609,9 @@ static int ext4_iomap_begin(struct inode *inode, loff_t offset, loff_t length,
35653609
return ret;
35663610
}
35673611

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;
36093615

36103616
return 0;
36113617
}

0 commit comments

Comments
 (0)