Commit 6b7349ec authored by John Garry's avatar John Garry Committed by Long Li
Browse files

fs: xfs: iomap: Sub-extent zeroing

maillist inclusion
category: feature
bugzilla: https://gitee.com/openeuler/kernel/issues/I9VTE3
CVE: NA

Reference: https://lore.kernel.org/all/20240326133813.3224593-1-john.g.garry@oracle.com/



--------------------------------

Set iomap->extent_shift when sub-extent zeroing is required.

We treat a sub-extent write same as an unaligned write, so we can leverage
the existing sub-FSblock unaligned write support, i.e. try a shared lock
with IOMAP_DIO_OVERWRITE_ONLY flag, if this fails then try the exclusive
lock.

In xfs_iomap_write_unwritten(), FSB calcs are now based on the extsize.

Signed-off-by: default avatarJohn Garry <john.g.garry@oracle.com>
Signed-off-by: default avatarLong Li <leo.lilong@huawei.com>
parent 6d37fb9c
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -597,8 +597,8 @@ xfs_file_dio_aio_write(
	 * the inode as necessary for EOF zeroing cases and fill out the new
	 * inode size as appropriate.
	 */
	if ((iocb->ki_pos & mp->m_blockmask) ||
	    ((iocb->ki_pos + count) & mp->m_blockmask)) {
	if ((iocb->ki_pos & (XFS_FSB_TO_B(mp, xfs_get_extsz(ip)) - 1)) ||
	    ((iocb->ki_pos + count) & (XFS_FSB_TO_B(mp, xfs_get_extsz(ip)) - 1))) {
		unaligned_io = 1;

		/*
+13 −2
Original line number Diff line number Diff line
@@ -90,6 +90,7 @@ xfs_bmbt_to_iomap(
{
	struct xfs_mount	*mp = ip->i_mount;
	struct xfs_buftarg	*target = xfs_inode_buftarg(ip);
	xfs_extlen_t		extsz = xfs_get_extsz(ip);

	if (unlikely(!xfs_valid_startblock(ip, imap->br_startblock)))
		return xfs_alert_fsblock_zero(ip, imap);
@@ -120,6 +121,8 @@ xfs_bmbt_to_iomap(

	iomap->validity_cookie = sequence_cookie;
	iomap->page_ops = &xfs_iomap_page_ops;
	if (extsz > 1)
		iomap->extent_shift = ffs(extsz) - 1;
	return 0;
}

@@ -546,11 +549,19 @@ xfs_iomap_write_unwritten(
	xfs_fsize_t	i_size;
	uint		resblks;
	int		error;
	xfs_extlen_t	extsz = xfs_get_extsz(ip);

	trace_xfs_unwritten_convert(ip, offset, count);

	if (extsz > 1) {
		xfs_extlen_t extsize_bytes = XFS_FSB_TO_B(mp, extsz);

		offset_fsb = XFS_B_TO_FSBT(mp, round_down(offset, extsize_bytes));
		count_fsb = XFS_B_TO_FSB(mp, round_up(offset + count, extsize_bytes));
	} else {
		offset_fsb = XFS_B_TO_FSBT(mp, offset);
		count_fsb = XFS_B_TO_FSB(mp, (xfs_ufsize_t)offset + count);
	}
	count_fsb = (xfs_filblks_t)(count_fsb - offset_fsb);

	/*