Re: [PATCH] xfs: split xfs_zone_record_blocks

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

 



On Wed, Jul 23, 2025 at 07:35:44AM +0200, Christoph Hellwig wrote:
> xfs_zone_record_blocks not only records successfully written blocks that
> now back file data, but is also used for blocks speculatively written by
> garbage collection that were never linked to an inode and instantly
> become invalid.
> 
> Split the latter functionality out to be easier to understand.  This also
> make it clear that we don't need to attach the rmap inode to a
> transaction for the skipped blocks case as we never dirty any peristent
> data structure.
> 
> Also make the argument order to xfs_zone_record_blocks a bit more
> natural.
> 
> Signed-off-by: Christoph Hellwig <hch@xxxxxx>

Looks good to me,
Reviewed-by: "Darrick J. Wong" <djwong@xxxxxxxxxx>

--D

> ---
>  fs/xfs/xfs_trace.h      |  1 +
>  fs/xfs/xfs_zone_alloc.c | 42 ++++++++++++++++++++++++++++-------------
>  2 files changed, 30 insertions(+), 13 deletions(-)
> 
> diff --git a/fs/xfs/xfs_trace.h b/fs/xfs/xfs_trace.h
> index 10d4fd671dcf..178b204dee3b 100644
> --- a/fs/xfs/xfs_trace.h
> +++ b/fs/xfs/xfs_trace.h
> @@ -455,6 +455,7 @@ DEFINE_EVENT(xfs_zone_alloc_class, name,			\
>  		 xfs_extlen_t len),				\
>  	TP_ARGS(oz, rgbno, len))
>  DEFINE_ZONE_ALLOC_EVENT(xfs_zone_record_blocks);
> +DEFINE_ZONE_ALLOC_EVENT(xfs_zone_skip_blocks);
>  DEFINE_ZONE_ALLOC_EVENT(xfs_zone_alloc_blocks);
>  
>  TRACE_EVENT(xfs_zone_gc_select_victim,
> diff --git a/fs/xfs/xfs_zone_alloc.c b/fs/xfs/xfs_zone_alloc.c
> index 33f7eee521a8..f8bd6d741755 100644
> --- a/fs/xfs/xfs_zone_alloc.c
> +++ b/fs/xfs/xfs_zone_alloc.c
> @@ -166,10 +166,9 @@ xfs_open_zone_mark_full(
>  static void
>  xfs_zone_record_blocks(
>  	struct xfs_trans	*tp,
> -	xfs_fsblock_t		fsbno,
> -	xfs_filblks_t		len,
>  	struct xfs_open_zone	*oz,
> -	bool			used)
> +	xfs_fsblock_t		fsbno,
> +	xfs_filblks_t		len)
>  {
>  	struct xfs_mount	*mp = tp->t_mountp;
>  	struct xfs_rtgroup	*rtg = oz->oz_rtg;
> @@ -179,18 +178,37 @@ xfs_zone_record_blocks(
>  
>  	xfs_rtgroup_lock(rtg, XFS_RTGLOCK_RMAP);
>  	xfs_rtgroup_trans_join(tp, rtg, XFS_RTGLOCK_RMAP);
> -	if (used) {
> -		rmapip->i_used_blocks += len;
> -		ASSERT(rmapip->i_used_blocks <= rtg_blocks(rtg));
> -	} else {
> -		xfs_add_frextents(mp, len);
> -	}
> +	rmapip->i_used_blocks += len;
> +	ASSERT(rmapip->i_used_blocks <= rtg_blocks(rtg));
>  	oz->oz_written += len;
>  	if (oz->oz_written == rtg_blocks(rtg))
>  		xfs_open_zone_mark_full(oz);
>  	xfs_trans_log_inode(tp, rmapip, XFS_ILOG_CORE);
>  }
>  
> +/*
> + * Called for blocks that have been written to disk, but not actually linked to
> + * an inode, which can happen when garbage collection races with user data
> + * writes to a file.
> + */
> +static void
> +xfs_zone_skip_blocks(
> +	struct xfs_open_zone	*oz,
> +	xfs_filblks_t		len)
> +{
> +	struct xfs_rtgroup	*rtg = oz->oz_rtg;
> +
> +	trace_xfs_zone_skip_blocks(oz, 0, len);
> +
> +	xfs_rtgroup_lock(rtg, XFS_RTGLOCK_RMAP);
> +	oz->oz_written += len;
> +	if (oz->oz_written == rtg_blocks(rtg))
> +		xfs_open_zone_mark_full(oz);
> +	xfs_rtgroup_unlock(rtg, XFS_RTGLOCK_RMAP);
> +
> +	xfs_add_frextents(rtg_mount(rtg), len);
> +}
> +
>  static int
>  xfs_zoned_map_extent(
>  	struct xfs_trans	*tp,
> @@ -250,8 +268,7 @@ xfs_zoned_map_extent(
>  		}
>  	}
>  
> -	xfs_zone_record_blocks(tp, new->br_startblock, new->br_blockcount, oz,
> -			true);
> +	xfs_zone_record_blocks(tp, oz, new->br_startblock, new->br_blockcount);
>  
>  	/* Map the new blocks into the data fork. */
>  	xfs_bmap_map_extent(tp, ip, XFS_DATA_FORK, new);
> @@ -259,8 +276,7 @@ xfs_zoned_map_extent(
>  
>  skip:
>  	trace_xfs_reflink_cow_remap_skip(ip, new);
> -	xfs_zone_record_blocks(tp, new->br_startblock, new->br_blockcount, oz,
> -			false);
> +	xfs_zone_skip_blocks(oz, new->br_blockcount);
>  	return 0;
>  }
>  
> -- 
> 2.47.2
> 
> 




[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