Commit 7dca67b6 authored by Chandan Babu R's avatar Chandan Babu R Committed by Zheng Zengkai
Browse files

xfs: Check for extent overflow when moving extent from cow to data fork

mainline inclusion
from mainline-v5.12-rc1
commit 5f1d5bbf
category: bugfix
bugzilla: 187510,https://gitee.com/openeuler/kernel/issues/I4KIAO

Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=5f1d5bbfb2e674052a9fe542f53678978af20770



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

Moving an extent to data fork can cause a sub-interval of an existing
extent to be unmapped. This will increase extent count by 1. Mapping in
the new extent can increase the extent count by 1 again i.e.
 | Old extent | New extent | Old extent |
Hence number of extents increases by 2.

Reviewed-by: default avatarDarrick J. Wong <darrick.wong@oracle.com>
Reviewed-by: default avatarChristoph Hellwig <hch@lst.de>
Reviewed-by: default avatarAllison Henderson <allison.henderson@oracle.com>
Signed-off-by: default avatarChandan Babu R <chandanrlinux@gmail.com>
Signed-off-by: default avatarDarrick J. Wong <darrick.wong@oracle.com>
Signed-off-by: default avatarYu Kuai <yukuai3@huawei.com>
Signed-off-by: default avatarGuo Xuenan <guoxuenan@huawei.com>
Reviewed-by: default avatarZhang Yi <yi.zhang@huawei.com>
Signed-off-by: default avatarZheng Zengkai <zhengzengkai@huawei.com>
parent c354ad22
Loading
Loading
Loading
Loading
+9 −0
Original line number Diff line number Diff line
@@ -79,6 +79,15 @@ struct xfs_ifork {
#define XFS_IEXT_WRITE_UNWRITTEN_CNT	(2)


/*
 * Moving an extent to data fork can cause a sub-interval of an existing extent
 * to be unmapped. This will increase extent count by 1. Mapping in the new
 * extent can increase the extent count by 1 again i.e.
 * | Old extent | New extent | Old extent |
 * Hence number of extents increases by 2.
 */
#define XFS_IEXT_REFLINK_END_COW_CNT	(2)

/*
 * Fork handling.
 */
+5 −0
Original line number Diff line number Diff line
@@ -615,6 +615,11 @@ xfs_reflink_end_cow_extent(
	xfs_ilock(ip, XFS_ILOCK_EXCL);
	xfs_trans_ijoin(tp, ip, 0);

	error = xfs_iext_count_may_overflow(ip, XFS_DATA_FORK,
			XFS_IEXT_REFLINK_END_COW_CNT);
	if (error)
		goto out_cancel;

	/*
	 * In case of racing, overlapping AIO writes no COW extents might be
	 * left by the time I/O completes for the loser of the race.  In that