public inbox for linux-xfs@vger.kernel.org
 help / color / mirror / Atom feed
From: Brian Foster <bfoster@redhat.com>
To: Christoph Hellwig <hch@lst.de>
Cc: cem@kernel.org, linux-xfs@vger.kernel.org
Subject: Re: [PATCH] xfs: fix XFS_ERRTAG_FORCE_ZERO_RANGE for zoned file system
Date: Wed, 10 Dec 2025 10:36:55 -0500	[thread overview]
Message-ID: <aTmTl_khrrNz9yLY@bfoster> (raw)
In-Reply-To: <20251210090400.3642383-1-hch@lst.de>

On Wed, Dec 10, 2025 at 10:03:55AM +0100, Christoph Hellwig wrote:
> The new XFS_ERRTAG_FORCE_ZERO_RANGE error tag added by commit
> ea9989668081 ("xfs: error tag to force zeroing on debug kernels") fails
> to account for the zoned space reservation rules and this reliably fails
> xfs/131 because the zeroing operation returns -EIO.
> 
> Fix this by reserving enough space to zero the entire range, which
> requires a bit of (fairly ugly) reshuffling to do the error injection
> early enough to affect the space reservation.
> 
> Fixes: ea9989668081 ("xfs: error tag to force zeroing on debug kernels")
> Signed-off-by: Christoph Hellwig <hch@lst.de>
> ---

Is there a reason in particular for testing this with the zone mode?
It's just a DEBUG thing for the zeroing mechanism. Why not just filter
out the is_zoned_inode() case at the injection site?

I suppose you could argue there is a point if we have separate zoned
mode iomap callbacks and whatnot, but I agree the factoring here is a
little unfortunate. I wonder if it would be nicer if we could set a flag
or something on an ac and toggle the zone mode off that, but on a quick
look I don't see a flag field in the zone ctx.

Hmm.. I wonder if we could still do something more clever where the zone
mode has its own injection site to bump the res, and then the lower
level logic just checks whether the reservation is sufficient for a full
zero..? I'm not totally sure if that's ultimately cleaner, but maybe
worth a thought..

Brian

>  fs/xfs/xfs_file.c | 46 ++++++++++++++++++++++++++++++++--------------
>  1 file changed, 32 insertions(+), 14 deletions(-)
> 
> diff --git a/fs/xfs/xfs_file.c b/fs/xfs/xfs_file.c
> index 6108612182e2..dbf37adf3a6b 100644
> --- a/fs/xfs/xfs_file.c
> +++ b/fs/xfs/xfs_file.c
> @@ -1254,7 +1254,8 @@ xfs_falloc_zero_range(
>  	int			mode,
>  	loff_t			offset,
>  	loff_t			len,
> -	struct xfs_zone_alloc_ctx *ac)
> +	struct xfs_zone_alloc_ctx *ac,
> +	bool			force_zero_range)
>  {
>  	struct inode		*inode = file_inode(file);
>  	struct xfs_inode	*ip = XFS_I(inode);
> @@ -1274,8 +1275,7 @@ xfs_falloc_zero_range(
>  	 * extents than to perform zeroing here, so use an errortag to randomly
>  	 * force zeroing on DEBUG kernels for added test coverage.
>  	 */
> -	if (XFS_TEST_ERROR(ip->i_mount,
> -			   XFS_ERRTAG_FORCE_ZERO_RANGE)) {
> +	if (force_zero_range) {
>  		error = xfs_zero_range(ip, offset, len, ac, NULL);
>  	} else {
>  		error = xfs_free_file_space(ip, offset, len, ac);
> @@ -1357,7 +1357,8 @@ __xfs_file_fallocate(
>  	int			mode,
>  	loff_t			offset,
>  	loff_t			len,
> -	struct xfs_zone_alloc_ctx *ac)
> +	struct xfs_zone_alloc_ctx *ac,
> +	bool			force_zero_range)
>  {
>  	struct inode		*inode = file_inode(file);
>  	struct xfs_inode	*ip = XFS_I(inode);
> @@ -1393,7 +1394,8 @@ __xfs_file_fallocate(
>  		error = xfs_falloc_insert_range(file, offset, len);
>  		break;
>  	case FALLOC_FL_ZERO_RANGE:
> -		error = xfs_falloc_zero_range(file, mode, offset, len, ac);
> +		error = xfs_falloc_zero_range(file, mode, offset, len, ac,
> +				force_zero_range);
>  		break;
>  	case FALLOC_FL_UNSHARE_RANGE:
>  		error = xfs_falloc_unshare_range(file, mode, offset, len);
> @@ -1419,17 +1421,24 @@ xfs_file_zoned_fallocate(
>  	struct file		*file,
>  	int			mode,
>  	loff_t			offset,
> -	loff_t			len)
> +	loff_t			len,
> +	bool			force_zero_range)
>  {
>  	struct xfs_zone_alloc_ctx ac = { };
>  	struct xfs_inode	*ip = XFS_I(file_inode(file));
> +	struct xfs_mount	*mp = ip->i_mount;
>  	int			error;
> +	xfs_filblks_t		count_fsb = 2;
>  
> -	error = xfs_zoned_space_reserve(ip->i_mount, 2, XFS_ZR_RESERVED, &ac);
> +	if (force_zero_range)
> +		count_fsb += XFS_B_TO_FSB(mp, len) + 1;
> +
> +	error = xfs_zoned_space_reserve(mp, count_fsb, XFS_ZR_RESERVED, &ac);
>  	if (error)
>  		return error;
> -	error = __xfs_file_fallocate(file, mode, offset, len, &ac);
> -	xfs_zoned_space_unreserve(ip->i_mount, &ac);
> +	error = __xfs_file_fallocate(file, mode, offset, len, &ac,
> +			force_zero_range);
> +	xfs_zoned_space_unreserve(mp, &ac);
>  	return error;
>  }
>  
> @@ -1441,12 +1450,18 @@ xfs_file_fallocate(
>  	loff_t			len)
>  {
>  	struct inode		*inode = file_inode(file);
> +	struct xfs_inode	*ip = XFS_I(inode);
> +	bool			force_zero_range = false;
>  
>  	if (!S_ISREG(inode->i_mode))
>  		return -EINVAL;
>  	if (mode & ~XFS_FALLOC_FL_SUPPORTED)
>  		return -EOPNOTSUPP;
>  
> +	if ((mode & FALLOC_FL_MODE_MASK) == FALLOC_FL_ZERO_RANGE &&
> +	    XFS_TEST_ERROR(ip->i_mount, XFS_ERRTAG_FORCE_ZERO_RANGE))
> +		force_zero_range = true;
> +
>  	/*
>  	 * For zoned file systems, zeroing the first and last block of a hole
>  	 * punch requires allocating a new block to rewrite the remaining data
> @@ -1455,11 +1470,14 @@ xfs_file_fallocate(
>  	 * expected to be able to punch a hole even on a completely full
>  	 * file system.
>  	 */
> -	if (xfs_is_zoned_inode(XFS_I(inode)) &&
> -	    (mode & (FALLOC_FL_PUNCH_HOLE | FALLOC_FL_ZERO_RANGE |
> -		     FALLOC_FL_COLLAPSE_RANGE)))
> -		return xfs_file_zoned_fallocate(file, mode, offset, len);
> -	return __xfs_file_fallocate(file, mode, offset, len, NULL);
> +	if (xfs_is_zoned_inode(ip) &&
> +	    (force_zero_range ||
> +	     (mode & (FALLOC_FL_PUNCH_HOLE | FALLOC_FL_ZERO_RANGE |
> +		      FALLOC_FL_COLLAPSE_RANGE))))
> +		return xfs_file_zoned_fallocate(file, mode, offset, len,
> +				force_zero_range);
> +	return __xfs_file_fallocate(file, mode, offset, len, NULL,
> +			force_zero_range);
>  }
>  
>  STATIC int
> -- 
> 2.47.3
> 
> 


  reply	other threads:[~2025-12-10 15:37 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-12-10  9:03 [PATCH] xfs: fix XFS_ERRTAG_FORCE_ZERO_RANGE for zoned file system Christoph Hellwig
2025-12-10 15:36 ` Brian Foster [this message]
2025-12-10 15:40   ` Christoph Hellwig
2025-12-10 17:14     ` Brian Foster
2025-12-10 17:18       ` Christoph Hellwig
2025-12-12  7:39       ` Christoph Hellwig
2025-12-12 12:24         ` Brian Foster

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=aTmTl_khrrNz9yLY@bfoster \
    --to=bfoster@redhat.com \
    --cc=cem@kernel.org \
    --cc=hch@lst.de \
    --cc=linux-xfs@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox