@@ -7309,13 +7309,6 @@ static int btrfs_get_blocks_direct_write(struct extent_map **map,
len = min(len, em->len - (start - em->start));
skip_cow:
- /*
- * Need to update the i_size under the extent lock so buffered
- * readers will get the updated i_size when we unlock.
- */
- if (start + len > i_size_read(inode))
- i_size_write(inode, start + len);
-
dio_data->reserve -= len;
out:
return ret;
@@ -7542,10 +7535,16 @@ static void btrfs_dio_private_put(struct btrfs_dio_private *dip)
return;
if (bio_op(dip->dio_bio) == REQ_OP_WRITE) {
- __endio_write_update_ordered(BTRFS_I(dip->inode),
- dip->logical_offset,
- dip->bytes,
- !dip->dio_bio->bi_status);
+ u64 offset = dip->logical_offset;
+ u64 length = dip->bytes;
+ bool uptodate = !dip->dio_bio->bi_status;
+
+ /* Increment the filesize iff the DIO write is successful */
+ if (uptodate && i_size_read(dip->inode) < offset + length)
+ i_size_write(dip->inode, offset + length);
+
+ __endio_write_update_ordered(BTRFS_I(dip->inode), offset,
+ length, uptodate);
} else {
unlock_extent(&BTRFS_I(dip->inode)->io_tree,
dip->logical_offset,
i_size is incremented when btrfs creates new extents during the start of a DIO write. If there is a failure until the endio, we will have a file with incremented filesize but no data. Increment the filesize after the successful completion of a DIO write. Signed-off-by: Goldwyn Rodrigues <rgoldwyn@suse.com>