@@ -3428,10 +3428,19 @@ static void ext4_set_iomap(struct inode *inode, struct iomap *iomap,
iomap->length = (u64) map->m_len << blkbits;
if (map->m_flags & (EXT4_MAP_MAPPED | EXT4_MAP_UNWRITTEN)) {
- 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 map->m_flags having both EXT4_MAP_MAPPED and
+ * EXT4_MAP_UNWRITTEN bits set. In order for any allocated
+ * extents to be converted to written extents correctly in 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;
iomap->addr = (u64) map->m_pblk << blkbits;
} else {
iomap->type = IOMAP_HOLE;