|
@@ -58,7 +58,7 @@ xfs_zero_range(
|
|
|
xfs_off_t count,
|
|
|
bool *did_zero)
|
|
|
{
|
|
|
- return iomap_zero_range(VFS_I(ip), pos, count, NULL, &xfs_iomap_ops);
|
|
|
+ return iomap_zero_range(VFS_I(ip), pos, count, did_zero, &xfs_iomap_ops);
|
|
|
}
|
|
|
|
|
|
int
|
|
@@ -377,8 +377,6 @@ restart:
|
|
|
*/
|
|
|
spin_lock(&ip->i_flags_lock);
|
|
|
if (iocb->ki_pos > i_size_read(inode)) {
|
|
|
- bool zero = false;
|
|
|
-
|
|
|
spin_unlock(&ip->i_flags_lock);
|
|
|
if (!drained_dio) {
|
|
|
if (*iolock == XFS_IOLOCK_SHARED) {
|
|
@@ -399,7 +397,7 @@ restart:
|
|
|
drained_dio = true;
|
|
|
goto restart;
|
|
|
}
|
|
|
- error = xfs_zero_eof(ip, iocb->ki_pos, i_size_read(inode), &zero);
|
|
|
+ error = xfs_zero_eof(ip, iocb->ki_pos, i_size_read(inode), NULL);
|
|
|
if (error)
|
|
|
return error;
|
|
|
} else
|
|
@@ -436,7 +434,6 @@ xfs_dio_write_end_io(
|
|
|
struct inode *inode = file_inode(iocb->ki_filp);
|
|
|
struct xfs_inode *ip = XFS_I(inode);
|
|
|
loff_t offset = iocb->ki_pos;
|
|
|
- bool update_size = false;
|
|
|
int error = 0;
|
|
|
|
|
|
trace_xfs_end_io_direct_write(ip, offset, size);
|
|
@@ -447,6 +444,21 @@ xfs_dio_write_end_io(
|
|
|
if (size <= 0)
|
|
|
return size;
|
|
|
|
|
|
+ if (flags & IOMAP_DIO_COW) {
|
|
|
+ error = xfs_reflink_end_cow(ip, offset, size);
|
|
|
+ if (error)
|
|
|
+ return error;
|
|
|
+ }
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Unwritten conversion updates the in-core isize after extent
|
|
|
+ * conversion but before updating the on-disk size. Updating isize any
|
|
|
+ * earlier allows a racing dio read to find unwritten extents before
|
|
|
+ * they are converted.
|
|
|
+ */
|
|
|
+ if (flags & IOMAP_DIO_UNWRITTEN)
|
|
|
+ return xfs_iomap_write_unwritten(ip, offset, size, true);
|
|
|
+
|
|
|
/*
|
|
|
* We need to update the in-core inode size here so that we don't end up
|
|
|
* with the on-disk inode size being outside the in-core inode size. We
|
|
@@ -461,20 +473,11 @@ xfs_dio_write_end_io(
|
|
|
spin_lock(&ip->i_flags_lock);
|
|
|
if (offset + size > i_size_read(inode)) {
|
|
|
i_size_write(inode, offset + size);
|
|
|
- update_size = true;
|
|
|
- }
|
|
|
- spin_unlock(&ip->i_flags_lock);
|
|
|
-
|
|
|
- if (flags & IOMAP_DIO_COW) {
|
|
|
- error = xfs_reflink_end_cow(ip, offset, size);
|
|
|
- if (error)
|
|
|
- return error;
|
|
|
- }
|
|
|
-
|
|
|
- if (flags & IOMAP_DIO_UNWRITTEN)
|
|
|
- error = xfs_iomap_write_unwritten(ip, offset, size);
|
|
|
- else if (update_size)
|
|
|
+ spin_unlock(&ip->i_flags_lock);
|
|
|
error = xfs_setfilesize(ip, offset, size);
|
|
|
+ } else {
|
|
|
+ spin_unlock(&ip->i_flags_lock);
|
|
|
+ }
|
|
|
|
|
|
return error;
|
|
|
}
|