Re: [PATCH 12/43] xfs: refine the unaligned check for always COW inodes in xfs_file_dio_write

Darrick J. Wong
2024-12-12T21:44:43Z

On Wed, Dec 11, 2024 at 09:54:37AM +0100, Christoph Hellwig wrote:
> 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.

I'm not sure why an alwayscow inode now needs to require fsblock-aligned
segments, seeing as it's been running mostly fine for years.

Is this a bug fix? Or prep for rtzone files, which are (presumably)
always written out of place?

--D

> Signed-off-by: Christoph Hellwig <hch@lst.de>
> ---
> fs/xfs/xfs_file.c | 11 ++++++++++-
> 1 file changed, 10 insertions(+), 1 deletion(-)
>
> diff --git a/fs/xfs/xfs_file.c b/fs/xfs/xfs_file.c
> index 2b6d4c71994d..6bcfd4c34a37 100644
> --- a/fs/xfs/xfs_file.c
> +++ b/fs/xfs/xfs_file.c
> @@ -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);
> }
> --
> 2.45.2
>
>