Commit 85bf2dfa authored by Darrick J. Wong's avatar Darrick J. Wong
Browse files

xfs: ignore HW which cannot atomic write a single block



Currently only HW which can write at least 1x block is supported.

For supporting atomic writes > 1x block, a CoW-based method will also be
used and this will not be resticted to using HW which can write >= 1x
block.

However for deciding if HW-based atomic writes can be used, we need to
start adding checks for write length < HW min, which complicates the
code.  Indeed, a statx field similar to unit_max_opt should also be
added for this minimum, which is undesirable.

HW which can only write > 1x blocks would be uncommon and quite weird,
so let's just not support it.

Signed-off-by: default avatar"Darrick J. Wong" <djwong@kernel.org>
Signed-off-by: default avatarJohn Garry <john.g.garry@oracle.com>
Reviewed-by: default avatarChristoph Hellwig <hch@lst.de>
parent 805f8988
Loading
Loading
Loading
Loading
+12 −0
Original line number Diff line number Diff line
@@ -1722,11 +1722,23 @@ static inline void
xfs_configure_buftarg_atomic_writes(
	struct xfs_buftarg	*btp)
{
	struct xfs_mount	*mp = btp->bt_mount;
	unsigned int		min_bytes, max_bytes;

	min_bytes = bdev_atomic_write_unit_min_bytes(btp->bt_bdev);
	max_bytes = bdev_atomic_write_unit_max_bytes(btp->bt_bdev);

	/*
	 * Ignore atomic write geometry that is nonsense or doesn't even cover
	 * a single fsblock.
	 */
	if (min_bytes > max_bytes ||
	    min_bytes > mp->m_sb.sb_blocksize ||
	    max_bytes < mp->m_sb.sb_blocksize) {
		min_bytes = 0;
		max_bytes = 0;
	}

	btp->bt_bdev_awu_min = min_bytes;
	btp->bt_bdev_awu_max = max_bytes;
}
+1 −1
Original line number Diff line number Diff line
@@ -112,7 +112,7 @@ struct xfs_buftarg {
	struct percpu_counter	bt_readahead_count;
	struct ratelimit_state	bt_ioerror_rl;

	/* Atomic write unit values */
	/* Atomic write unit values, bytes */
	unsigned int		bt_bdev_awu_min;
	unsigned int		bt_bdev_awu_max;

+1 −9
Original line number Diff line number Diff line
@@ -358,15 +358,7 @@ static inline bool xfs_inode_has_bigrtalloc(const struct xfs_inode *ip)

static inline bool xfs_inode_can_hw_atomic_write(const struct xfs_inode *ip)
{
	struct xfs_mount	*mp = ip->i_mount;
	struct xfs_buftarg	*target = xfs_inode_buftarg(ip);

	if (mp->m_sb.sb_blocksize < target->bt_bdev_awu_min)
		return false;
	if (mp->m_sb.sb_blocksize > target->bt_bdev_awu_max)
		return false;

	return true;
	return xfs_inode_buftarg(ip)->bt_bdev_awu_max > 0;
}

/*