Commit 6fff1752 authored by Christoph Hellwig's avatar Christoph Hellwig
Browse files

xfs: refine the unaligned check for always COW inodes in xfs_file_dio_write



For always COW inodes we also must check the alignment of each individual
iovec segment, as they could end up with different I/Os due to the way
bio_iov_iter_get_pages works, and we'd then overwrite an already written
block.  The existing always_cow sysctl based code doesn't catch this
because nothing enforces that blocks aren't rewritten, but for zoned XFS
on sequential write required zones this is a hard error.

Signed-off-by: default avatarChristoph Hellwig <hch@lst.de>
Reviewed-by: default avatar"Darrick J. Wong" <djwong@kernel.org>
parent 8ae4c8ce
Loading
Loading
Loading
Loading
+10 −1
Original line number Diff line number Diff line
@@ -721,7 +721,16 @@ xfs_file_dio_write(
	/* direct I/O must be aligned to device logical sector size */
	if ((iocb->ki_pos | count) & target->bt_logical_sectormask)
		return -EINVAL;
	if ((iocb->ki_pos | count) & ip->i_mount->m_blockmask)

	/*
	 * For always COW inodes we also must check the alignment of each
	 * individual iovec segment, as they could end up with different
	 * I/Os due to the way bio_iov_iter_get_pages works, and we'd
	 * then overwrite an already written block.
	 */
	if (((iocb->ki_pos | count) & ip->i_mount->m_blockmask) ||
	    (xfs_is_always_cow_inode(ip) &&
	     (iov_iter_alignment(from) & ip->i_mount->m_blockmask)))
		return xfs_file_dio_write_unaligned(ip, iocb, from);
	return xfs_file_dio_write_aligned(ip, iocb, from);
}