Re: [PATCH 21/24] xfs: use ->t_dfops for rmap extent swap operations

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Thu, Jun 28, 2018 at 12:36:33PM -0400, Brian Foster wrote:
> 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: Brian Foster <bfoster@xxxxxxxxxx>
> ---
>  fs/xfs/xfs_bmap_util.c | 32 +++++++++++++++++++-------------
>  1 file changed, 19 insertions(+), 13 deletions(-)
> 
> diff --git a/fs/xfs/xfs_bmap_util.c b/fs/xfs/xfs_bmap_util.c
> index 2c0c9534941c..4fdf013603ab 100644
> --- a/fs/xfs/xfs_bmap_util.c
> +++ b/fs/xfs/xfs_bmap_util.c
> @@ -1570,6 +1570,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;
> @@ -1577,7 +1579,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;
> @@ -1613,7 +1614,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 */
> @@ -1635,31 +1636,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;
>  
> @@ -1679,7 +1681,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;
> @@ -1846,6 +1848,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;
> @@ -1853,6 +1856,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
> @@ -1915,6 +1919,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;

Hmm... another redundant initialization here, and extra stack usage too.

If we're going to move the dfops into struct xfs_trans I don't want this
series and that series to be split across a release with all these bits
scattered everywhere for a single release.

It's at this point I'm tempted to suggest starting this series over with
adding a new dfops to the transaction and then converting the
t_agfl_dfops and the open-coded/stack-allocated dfops to use the one
embedded in the transaction, if nothing else to avoid all this scattered
churn.

OTOH I also see that you already moved firstblock into the transaction.
I'll keep my mouth shut until I get to the end of that series because I
sense there's a lot of changes captured in those two series that would
happen even if you'd started with putting the dfops in the transaction.
Maybe you're really close to mailing out that last piece anyway.

Code otherwise looks ok, if a bit messy:
Reviewed-by: Darrick J. Wong <darrick.wong@xxxxxxxxxx>

--D

>  
>  	/*
>  	 * Lock and join the inodes to the tansaction so that transaction commit
> -- 
> 2.17.1
> 
> --
> To unsubscribe from this list: send the line "unsubscribe linux-xfs" in
> the body of a message to majordomo@xxxxxxxxxxxxxxx
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
--
To unsubscribe from this list: send the line "unsubscribe linux-xfs" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html



[Index of Archives]     [XFS Filesystem Development (older mail)]     [Linux Filesystem Development]     [Linux Audio Users]     [Yosemite Trails]     [Linux Kernel]     [Linux RAID]     [Linux SCSI]


  Powered by Linux