diff --git a/fs/btrfs/direct-io.c b/fs/btrfs/direct-io.c index b80dc45c3ff9..27d227f5bdc0 100644 --- a/fs/btrfs/direct-io.c +++ b/fs/btrfs/direct-io.c @@ -280,17 +280,24 @@ static int btrfs_get_blocks_direct_write(struct extent_map **map, em2 = btrfs_create_dio_extent(BTRFS_I(inode), dio_data, start, &file_extent, type); btrfs_dec_nocow_writers(bg); - if (type == BTRFS_ORDERED_PREALLOC) { + if (IS_ERR(em2)) { + ret = PTR_ERR(em2); + btrfs_free_extent_map(em); + *map = NULL; + goto out; + } + + /* + * True NOCOW writes don't need to create a new extent map, + * while PREALLOC writes must replace the existing one. + */ + if (em2) { + ASSERT(type == BTRFS_ORDERED_PREALLOC); btrfs_free_extent_map(em); *map = em2; em = em2; } - if (IS_ERR(em2)) { - ret = PTR_ERR(em2); - goto out; - } - dio_data->nocow_done = true; } else { /* Our caller expects us to free the input extent map. */