diff options
author | Matthew Bobrowski <mbobrowski@mbobrowski.org> | 2019-11-05 22:58:55 +1100 |
---|---|---|
committer | Theodore Ts'o <tytso@mit.edu> | 2019-11-05 11:31:39 -0500 |
commit | 53e5cca56795a301bbe8465781dab084f7ae8d54 (patch) | |
tree | 18a2ef80ec05290931cd080454ae80a8cb95551c | |
parent | f21bdbba0a5ac69e0a632ad974f5c0df9b7d411c (diff) | |
download | linux-53e5cca56795a301bbe8465781dab084f7ae8d54.tar.bz2 |
ext4: reorder map.m_flags checks within ext4_iomap_begin()
For the direct I/O changes that follow in this patch series, we need
to accommodate for the case where the block mapping flags passed
through to ext4_map_blocks() result in m_flags having both
EXT4_MAP_MAPPED and EXT4_MAP_UNWRITTEN bits set. In order for any
allocated unwritten extents to be converted correctly in the
->end_io() handler, the iomap->type must be set to IOMAP_UNWRITTEN for
cases where the EXT4_MAP_UNWRITTEN bit has been set within
m_flags. Hence the reason why we need to reshuffle this conditional
statement around.
This change is a no-op for DAX as the block mapping flags passed
through to ext4_map_blocks() i.e. EXT4_GET_BLOCKS_CREATE_ZERO never
results in both EXT4_MAP_MAPPED and EXT4_MAP_UNWRITTEN being set at
once.
Signed-off-by: Matthew Bobrowski <mbobrowski@mbobrowski.org>
Reviewed-by: Jan Kara <jack@suse.cz>
Reviewed-by: Ritesh Harjani <riteshh@linux.ibm.com>
Link: https://lore.kernel.org/r/1309ad80d31a637b2deed55a85283d582a54a26a.1572949325.git.mbobrowski@mbobrowski.org
Signed-off-by: Theodore Ts'o <tytso@mit.edu>
-rw-r--r-- | fs/ext4/inode.c | 16 |
1 files changed, 13 insertions, 3 deletions
diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c index 0d8971b819e9..e4b0722717b3 100644 --- a/fs/ext4/inode.c +++ b/fs/ext4/inode.c @@ -3577,10 +3577,20 @@ retry: iomap->type = delalloc ? IOMAP_DELALLOC : IOMAP_HOLE; iomap->addr = IOMAP_NULL_ADDR; } else { - if (map.m_flags & EXT4_MAP_MAPPED) { - iomap->type = IOMAP_MAPPED; - } else if (map.m_flags & EXT4_MAP_UNWRITTEN) { + /* + * Flags passed into ext4_map_blocks() for direct I/O writes + * can result in m_flags having both EXT4_MAP_MAPPED and + * EXT4_MAP_UNWRITTEN bits set. In order for any allocated + * unwritten extents to be converted into written extents + * correctly within the ->end_io() handler, we need to ensure + * that the iomap->type is set appropriately. Hence the reason + * why we need to check whether EXT4_MAP_UNWRITTEN is set + * first. + */ + if (map.m_flags & EXT4_MAP_UNWRITTEN) { iomap->type = IOMAP_UNWRITTEN; + } else if (map.m_flags & EXT4_MAP_MAPPED) { + iomap->type = IOMAP_MAPPED; } else { WARN_ON_ONCE(1); return -EIO; |