Commit 7a7943c7 authored by Brian Foster's avatar Brian Foster Committed by Darrick J. Wong
Browse files

xfs: use ->t_dfops for rmap extent swap operations



xfs_swap_extent_rmap() uses a local dfops instance with a
transaction from the caller. Since there is only one caller, pull
the dfops structure into the caller and attach it to the
transaction. This avoids the need to clear ->t_dfops to prevent
invalid stack memory access.

Signed-off-by: default avatarBrian Foster <bfoster@redhat.com>
Reviewed-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 ed7ef8e5
Loading
Loading
Loading
Loading
+19 −13
Original line number Diff line number Diff line
@@ -1571,6 +1571,8 @@ xfs_swap_extent_rmap(
	struct xfs_inode		*ip,
	struct xfs_inode		*tip)
{
	struct xfs_trans		*tp = *tpp;
	struct xfs_mount		*mp = tp->t_mountp;
	struct xfs_bmbt_irec		irec;
	struct xfs_bmbt_irec		uirec;
	struct xfs_bmbt_irec		tirec;
@@ -1578,7 +1580,6 @@ xfs_swap_extent_rmap(
	xfs_fileoff_t			end_fsb;
	xfs_filblks_t			count_fsb;
	xfs_fsblock_t			firstfsb;
	struct xfs_defer_ops		dfops;
	int				error;
	xfs_filblks_t			ilen;
	xfs_filblks_t			rlen;
@@ -1614,7 +1615,7 @@ xfs_swap_extent_rmap(

		/* Unmap the old blocks in the source file. */
		while (tirec.br_blockcount) {
			xfs_defer_init(&dfops, &firstfsb);
			xfs_defer_init(tp->t_dfops, &firstfsb);
			trace_xfs_swap_extent_rmap_remap_piece(tip, &tirec);

			/* Read extent from the source file */
@@ -1636,31 +1637,32 @@ xfs_swap_extent_rmap(
			trace_xfs_swap_extent_rmap_remap_piece(tip, &uirec);

			/* Remove the mapping from the donor file. */
			error = xfs_bmap_unmap_extent((*tpp)->t_mountp, &dfops,
					tip, &uirec);
			error = xfs_bmap_unmap_extent(mp, tp->t_dfops, tip,
					&uirec);
			if (error)
				goto out_defer;

			/* Remove the mapping from the source file. */
			error = xfs_bmap_unmap_extent((*tpp)->t_mountp, &dfops,
					ip, &irec);
			error = xfs_bmap_unmap_extent(mp, tp->t_dfops, ip,
					&irec);
			if (error)
				goto out_defer;

			/* Map the donor file's blocks into the source file. */
			error = xfs_bmap_map_extent((*tpp)->t_mountp, &dfops,
					ip, &uirec);
			error = xfs_bmap_map_extent(mp, tp->t_dfops, ip,
					&uirec);
			if (error)
				goto out_defer;

			/* Map the source file's blocks into the donor file. */
			error = xfs_bmap_map_extent((*tpp)->t_mountp, &dfops,
					tip, &irec);
			error = xfs_bmap_map_extent(mp, tp->t_dfops, tip,
					&irec);
			if (error)
				goto out_defer;

			xfs_defer_ijoin(&dfops, ip);
			error = xfs_defer_finish(tpp, &dfops);
			xfs_defer_ijoin(tp->t_dfops, ip);
			error = xfs_defer_finish(tpp, tp->t_dfops);
			tp = *tpp;
			if (error)
				goto out_defer;

@@ -1680,7 +1682,7 @@ xfs_swap_extent_rmap(
	return 0;

out_defer:
	xfs_defer_cancel(&dfops);
	xfs_defer_cancel(tp->t_dfops);
out:
	trace_xfs_swap_extent_rmap_error(ip, error, _RET_IP_);
	tip->i_d.di_flags2 = tip_flags2;
@@ -1847,6 +1849,7 @@ xfs_swap_extents(
{
	struct xfs_mount	*mp = ip->i_mount;
	struct xfs_trans	*tp;
	struct xfs_defer_ops	dfops;
	struct xfs_bstat	*sbp = &sxp->sx_stat;
	int			src_log_flags, target_log_flags;
	int			error = 0;
@@ -1854,6 +1857,7 @@ xfs_swap_extents(
	struct xfs_ifork	*cowfp;
	uint64_t		f;
	int			resblks = 0;
	xfs_fsblock_t		firstfsb;

	/*
	 * Lock the inodes against other IO, page faults and truncate to
@@ -1916,6 +1920,8 @@ xfs_swap_extents(
	error = xfs_trans_alloc(mp, &M_RES(mp)->tr_write, resblks, 0, 0, &tp);
	if (error)
		goto out_unlock;
	xfs_defer_init(&dfops, &firstfsb);
	tp->t_dfops = &dfops;

	/*
	 * Lock and join the inodes to the tansaction so that transaction commit