Commit 36adcbac authored by Christoph Hellwig's avatar Christoph Hellwig Committed by Darrick J. Wong
Browse files

xfs: fill out the srcmap in iomap_begin



Replace our local hacks to report the source block in the main iomap
with the proper scrmap reporting.

Signed-off-by: default avatarChristoph Hellwig <hch@lst.de>
Reviewed-by: default avatarDarrick J. Wong <darrick.wong@oracle.com>
Signed-off-by: default avatarDarrick J. Wong <darrick.wong@oracle.com>
parent ae36b53c
Loading
Loading
Loading
Loading
+24 −25
Original line number Diff line number Diff line
@@ -527,7 +527,8 @@ xfs_file_iomap_begin_delay(
	loff_t			offset,
	loff_t			count,
	unsigned		flags,
	struct iomap		*iomap)
	struct iomap		*iomap,
	struct iomap		*srcmap)
{
	struct xfs_inode	*ip = XFS_I(inode);
	struct xfs_mount	*mp = ip->i_mount;
@@ -721,11 +722,13 @@ xfs_file_iomap_begin_delay(
found_cow:
	xfs_iunlock(ip, XFS_ILOCK_EXCL);
	if (imap.br_startoff <= offset_fsb) {
		/* ensure we only report blocks we have a reservation for */
		xfs_trim_extent(&imap, cmap.br_startoff, cmap.br_blockcount);
		return xfs_bmbt_to_iomap(ip, iomap, &imap, IOMAP_F_SHARED);
		error = xfs_bmbt_to_iomap(ip, srcmap, &imap, 0);
		if (error)
			return error;
	} else {
		xfs_trim_extent(&cmap, offset_fsb,
				imap.br_startoff - offset_fsb);
	}
	xfs_trim_extent(&cmap, offset_fsb, imap.br_startoff - offset_fsb);
	return xfs_bmbt_to_iomap(ip, iomap, &cmap, IOMAP_F_SHARED);

out_unlock:
@@ -933,7 +936,7 @@ xfs_file_iomap_begin(
{
	struct xfs_inode	*ip = XFS_I(inode);
	struct xfs_mount	*mp = ip->i_mount;
	struct xfs_bmbt_irec	imap;
	struct xfs_bmbt_irec	imap, cmap;
	xfs_fileoff_t		offset_fsb, end_fsb;
	int			nimaps = 1, error = 0;
	bool			shared = false;
@@ -947,7 +950,7 @@ xfs_file_iomap_begin(
			!IS_DAX(inode) && !xfs_get_extsz_hint(ip)) {
		/* Reserve delalloc blocks for regular writeback. */
		return xfs_file_iomap_begin_delay(inode, offset, length, flags,
				iomap);
				iomap, srcmap);
	}

	/*
@@ -987,9 +990,6 @@ xfs_file_iomap_begin(
	 * been done up front, so we don't need to do them here.
	 */
	if (xfs_is_cow_inode(ip)) {
		struct xfs_bmbt_irec	cmap;
		bool			directio = (flags & IOMAP_DIRECT);

		/* if zeroing doesn't need COW allocation, then we are done. */
		if ((flags & IOMAP_ZERO) &&
		    !needs_cow_for_zeroing(&imap, nimaps))
@@ -997,23 +997,11 @@ xfs_file_iomap_begin(

		/* may drop and re-acquire the ilock */
		error = xfs_reflink_allocate_cow(ip, &imap, &cmap, &shared,
				&lockmode, directio);
				&lockmode, flags & IOMAP_DIRECT);
		if (error)
			goto out_unlock;

		/*
		 * For buffered writes we need to report the address of the
		 * previous block (if there was any) so that the higher level
		 * write code can perform read-modify-write operations; we
		 * won't need the CoW fork mapping until writeback.  For direct
		 * I/O, which must be block aligned, we need to report the
		 * newly allocated address.  If the data fork has a hole, copy
		 * the COW fork mapping to avoid allocating to the data fork.
		 */
		if (shared &&
		    (directio || imap.br_startblock == HOLESTARTBLOCK))
			imap = cmap;

		if (shared)
			goto out_found_cow;
		end_fsb = imap.br_startoff + imap.br_blockcount;
		length = XFS_FSB_TO_B(mp, end_fsb) - offset;
	}
@@ -1074,6 +1062,17 @@ xfs_file_iomap_begin(
	trace_xfs_iomap_found(ip, offset, length, XFS_DATA_FORK, &imap);
	goto out_finish;

out_found_cow:
	xfs_iunlock(ip, lockmode);
	length = XFS_FSB_TO_B(mp, cmap.br_startoff + cmap.br_blockcount);
	trace_xfs_iomap_found(ip, offset, length - offset, XFS_COW_FORK, &cmap);
	if (imap.br_startblock != HOLESTARTBLOCK) {
		error = xfs_bmbt_to_iomap(ip, srcmap, &imap, 0);
		if (error)
			return error;
	}
	return xfs_bmbt_to_iomap(ip, iomap, &cmap, IOMAP_F_SHARED);

out_unlock:
	xfs_iunlock(ip, lockmode);
	return error;