@@ -3535,10 +3535,20 @@ static int ext4_iomap_begin(struct inode *inode, loff_t offset, loff_t length,
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;