All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Darrick J. Wong" <djwong@kernel.org>
To: Andrey Albershteyn <aalbersh@kernel.org>
Cc: ebiggers@kernel.org, hch@lst.de, Carlos Maiolino <cem@kernel.org>,
	fsverity@lists.linux.dev, linux-fsdevel@vger.kernel.org,
	linux-xfs@vger.kernel.org, linux-unionfs@vger.kernel.org,
	linux-ext4@vger.kernel.org,
	linux-f2fs-devel@lists.sourceforge.net,
	linux-btrfs@vger.kernel.org, david@fromorbit.com
Subject: Re: [PATCH v16 12/21] xfs: use read ioend for fsverity data verification
Date: Mon, 21 Sep 2026 21:29:19 -0700	[thread overview]
Message-ID: <20260922042919.GL2705364@frogsfrogsfrogs> (raw)
In-Reply-To: <20260918111539.1003439-13-aalbersh@kernel.org>

On Fri, Sep 18, 2026 at 01:15:24PM +0200, Andrey Albershteyn wrote:
> Use read ioends for fsverity verification. Do not issue fsverity
> metadata I/O through the same workqueue due to risk of a deadlock by a
> filled workqueue.
> 
> Pass fsverity_info from iomap context down to the ioend as hashtable
> lookups are expensive.
> 
> Add a simple helper to check that this is not fsverity metadata but file
> data that needs verification.
> 
> Signed-off-by: Andrey Albershteyn <aalbersh@kernel.org>

Seems fine to me, though I would like to see hch's blessing on this
since he's written more of the read ioend workqueue completion code.

Reviewed-by: "Darrick J. Wong" <djwong@kernel.org>

--D

> ---
>  fs/xfs/xfs_aops.c     | 13 +++++----
>  fs/xfs/xfs_file.c     |  3 +-
>  fs/xfs/xfs_fsverity.c | 11 ++++++++
>  fs/xfs/xfs_fsverity.h | 14 ++++++++++
>  fs/xfs/xfs_ioend.c    | 65 +++++++++++++++++++++++++++++++++++++++----
>  fs/xfs/xfs_ioend.h    |  4 ++-
>  fs/xfs/xfs_super.c    | 15 ++++++++++
>  7 files changed, 112 insertions(+), 13 deletions(-)
> 
> diff --git a/fs/xfs/xfs_aops.c b/fs/xfs/xfs_aops.c
> index 19640e4e3ed1..a36f840884b4 100644
> --- a/fs/xfs/xfs_aops.c
> +++ b/fs/xfs/xfs_aops.c
> @@ -24,6 +24,7 @@
>  #include "xfs_zone_alloc.h"
>  #include "xfs_rtgroup.h"
>  #include "xfs_fsverity.h"
> +#include <linux/fsverity.h>
>  
>  struct xfs_writepage_ctx {
>  	struct iomap_writepage_ctx ctx;
> @@ -611,7 +612,7 @@ xfs_bio_submit_read(
>  {
>  	xfs_ioend_submit_read(iter->inode, ctx->read_ctx,
>  			ctx->read_ctx_file_offset,
> -			iomap_ioend_flags(&iter->iomap));
> +			iomap_ioend_flags(&iter->iomap), ctx->vi);
>  	ctx->read_ctx = NULL;
>  }
>  
> @@ -623,11 +624,13 @@ static const struct iomap_read_ops xfs_iomap_read_ops = {
>  
>  static inline const struct iomap_read_ops *
>  xfs_get_iomap_read_ops(
> -	const struct address_space	*mapping)
> +	const struct address_space	*mapping,
> +	loff_t				pos)
>  {
>  	struct xfs_inode		*ip = XFS_I(mapping->host);
>  
> -	if (bdev_has_integrity_csum(xfs_inode_buftarg(ip)->bt_bdev))
> +	if (bdev_has_integrity_csum(xfs_inode_buftarg(ip)->bt_bdev) ||
> +	    xfs_fsverity_is_file_data(ip, pos))
>  		return &xfs_iomap_read_ops;
>  	return &iomap_bio_read_ops;
>  }
> @@ -639,7 +642,7 @@ xfs_vm_read_folio(
>  {
>  	struct iomap_read_folio_ctx	ctx = { .cur_folio = folio };
>  
> -	ctx.ops = xfs_get_iomap_read_ops(folio->mapping);
> +	ctx.ops = xfs_get_iomap_read_ops(folio->mapping, folio_pos(folio));
>  	iomap_read_folio(&xfs_read_iomap_ops, &ctx, NULL);
>  	return 0;
>  }
> @@ -650,7 +653,7 @@ xfs_vm_readahead(
>  {
>  	struct iomap_read_folio_ctx	ctx = { .rac = rac };
>  
> -	ctx.ops = xfs_get_iomap_read_ops(rac->mapping),
> +	ctx.ops = xfs_get_iomap_read_ops(rac->mapping, readahead_pos(rac));
>  	iomap_readahead(&xfs_read_iomap_ops, &ctx, NULL);
>  }
>  
> diff --git a/fs/xfs/xfs_file.c b/fs/xfs/xfs_file.c
> index 07abf6e8783f..578ca6fb8292 100644
> --- a/fs/xfs/xfs_file.c
> +++ b/fs/xfs/xfs_file.c
> @@ -225,7 +225,8 @@ xfs_dio_read_bounce_submit_io(
>  	loff_t			file_offset)
>  {
>  	xfs_ioend_submit_read(iter->inode, bio, file_offset,
> -			iomap_ioend_flags(&iter->iomap) | IOMAP_IOEND_DIRECT);
> +			iomap_ioend_flags(&iter->iomap) | IOMAP_IOEND_DIRECT,
> +			NULL);
>  }
>  
>  static const struct iomap_dio_ops xfs_dio_read_bounce_ops = {
> diff --git a/fs/xfs/xfs_fsverity.c b/fs/xfs/xfs_fsverity.c
> index e30021c22683..525855fdd30d 100644
> --- a/fs/xfs/xfs_fsverity.c
> +++ b/fs/xfs/xfs_fsverity.c
> @@ -14,9 +14,20 @@
>  #include <linux/fsverity.h>
>  #include <linux/iomap.h>
>  
> +struct kmem_cache *xfs_fsverity_ioend_cache;
> +
>  loff_t
>  xfs_fsverity_metadata_offset(
>  	const struct xfs_inode	*ip)
>  {
>  	return round_up(i_size_read(VFS_IC(ip)), XFS_FSVERITY_START_ALIGN);
>  }
> +
> +bool
> +xfs_fsverity_is_file_data(
> +	const struct xfs_inode	*ip,
> +	loff_t			offset)
> +{
> +	return fsverity_active(VFS_IC(ip)) &&
> +			offset < xfs_fsverity_metadata_offset(ip);
> +}
> diff --git a/fs/xfs/xfs_fsverity.h b/fs/xfs/xfs_fsverity.h
> index c2ab5af89370..836e3a4eb194 100644
> --- a/fs/xfs/xfs_fsverity.h
> +++ b/fs/xfs/xfs_fsverity.h
> @@ -6,15 +6,29 @@
>  #define __XFS_FSVERITY_H__
>  
>  #include "xfs_platform.h"
> +#include <linux/iomap.h>
>  
>  #ifdef CONFIG_FS_VERITY
>  loff_t xfs_fsverity_metadata_offset(const struct xfs_inode *ip);
> +bool xfs_fsverity_is_file_data(const struct xfs_inode *ip, loff_t offset);
>  #else
>  static inline loff_t xfs_fsverity_metadata_offset(const struct xfs_inode *ip)
>  {
>  	WARN_ON_ONCE(1);
>  	return ULLONG_MAX;
>  }
> +static inline bool xfs_fsverity_is_file_data(const struct xfs_inode *ip,
> +					    loff_t offset)
> +{
> +	return false;
> +}
>  #endif	/* CONFIG_FS_VERITY */
>  
> +struct xfs_fsverity_ioend {
> +	struct iomap_ioend	*ioend;
> +	struct work_struct	work;
> +};
> +
> +extern struct kmem_cache *xfs_fsverity_ioend_cache;
> +
>  #endif	/* __XFS_FSVERITY_H__ */
> diff --git a/fs/xfs/xfs_ioend.c b/fs/xfs/xfs_ioend.c
> index e70be5b86f0b..2f46855b052f 100644
> --- a/fs/xfs/xfs_ioend.c
> +++ b/fs/xfs/xfs_ioend.c
> @@ -18,7 +18,26 @@
>  #include "xfs_ioend.h"
>  #include "xfs_error.h"
>  #include "xfs_errortag.h"
> +#include "xfs_fsverity.h"
>  #include <linux/bio-integrity.h>
> +#include <linux/fsverity.h>
> +
> +static void
> +xfs_end_fsverity_io_read(
> +	struct work_struct		*work)
> +{
> +	struct xfs_fsverity_ioend	*fsv_ioend =
> +			container_of(work, struct xfs_fsverity_ioend, work);
> +	struct iomap_ioend		*ioend = fsv_ioend->ioend;
> +	struct bio			*bio = &ioend->io_bio;
> +
> +	kmem_cache_free(xfs_fsverity_ioend_cache, fsv_ioend);
> +
> +	if (!bio->bi_status)
> +		fsverity_verify_bio(ioend->io_vi, bio);
> +
> +	iomap_finish_ioends(ioend, blk_status_to_errno(bio->bi_status));
> +}
>  
>  static void
>  xfs_dio_bounce_end_io(
> @@ -93,12 +112,14 @@ xfs_read_bounce_and_resubmit(
>  
>  static void
>  xfs_end_io_read(
> -	struct bio		*bio)
> +	struct bio			*bio)
>  {
> -	struct iomap_ioend	*ioend = iomap_ioend_from_bio(bio);
> -	struct xfs_inode	*ip = XFS_I(ioend->io_inode);
> -	struct xfs_mount	*mp = ip->i_mount;
> -	int			error = blk_status_to_errno(bio->bi_status);
> +	struct iomap_ioend		*ioend = iomap_ioend_from_bio(bio);
> +	struct xfs_inode		*ip = XFS_I(ioend->io_inode);
> +	struct xfs_mount		*mp = ip->i_mount;
> +	int				error =
> +			blk_status_to_errno(bio->bi_status);
> +	struct xfs_fsverity_ioend	*fsv_ioend;
>  
>  	if (!error && (ioend->io_flags & IOMAP_IOEND_INTEGRITY)) {
>  		error = iomap_ioend_integrity_verify(ioend);
> @@ -117,6 +138,36 @@ xfs_end_io_read(
>  		}
>  	}
>  
> +	/*
> +	 * If we have fsverity and block device integrity attached to this bio,
> +	 * we need to run fsverity verification of data folios from a separate
> +	 * fsverity workqueue. This is necessary to avoid deadlocking due to
> +	 * fsverity issuing more reads of fsverity metadata which would be
> +	 * processed by the same worker in the BIO completion workqueue.
> +	 *
> +	 * Without block device integrity, fsverity metadata IO will not use
> +	 * ioends for completion.
> +	 */
> +	if (IS_ENABLED(CONFIG_FS_VERITY) && !error && ioend->io_vi &&
> +			xfs_fsverity_is_file_data(ip, ioend->io_offset)) {
> +		if (ioend->io_flags & IOMAP_IOEND_INTEGRITY) {
> +			fsv_ioend = kmem_cache_zalloc(xfs_fsverity_ioend_cache,
> +					GFP_KERNEL);
> +			if (!fsv_ioend) {
> +				iomap_finish_ioends(ioend, -ENOMEM);
> +				return;
> +			}
> +			fsv_ioend->ioend = ioend;
> +			INIT_WORK(&fsv_ioend->work, xfs_end_fsverity_io_read);
> +
> +			fsverity_enqueue_verify_work(&fsv_ioend->work);
> +			return;
> +		}
> +
> +		fsverity_verify_bio(ioend->io_vi, &ioend->io_bio);
> +		error = blk_status_to_errno(ioend->io_bio.bi_status);
> +	}
> +
>  	iomap_finish_ioends(ioend, error);
>  }
>  
> @@ -125,13 +176,15 @@ xfs_ioend_submit_read(
>  	struct inode		*inode,
>  	struct bio		*bio,
>  	loff_t			file_offset,
> -	u16			ioend_flags)
> +	u16			ioend_flags,
> +	struct fsverity_info	*vi)
>  {
>  	struct xfs_inode	*ip = XFS_I(inode);
>  	struct xfs_mount	*mp = ip->i_mount;
>  	struct iomap_ioend	*ioend;
>  
>  	ioend = iomap_init_ioend(inode, bio, file_offset, ioend_flags);
> +	ioend->io_vi = vi;
>  	if ((ioend_flags & IOMAP_IOEND_DIRECT) &&
>  	    READ_ONCE(mp->m_read_bounce) == XFS_READ_BOUNCE_ALWAYS) {
>  		iomap_bounce_read(ioend, bdev_logical_block_size(bio->bi_bdev),
> diff --git a/fs/xfs/xfs_ioend.h b/fs/xfs/xfs_ioend.h
> index 7c2a1ea3e6ed..992c248a693a 100644
> --- a/fs/xfs/xfs_ioend.h
> +++ b/fs/xfs/xfs_ioend.h
> @@ -2,6 +2,8 @@
>  #ifndef __XFS_IOEND_H
>  #define __XFS_IOEND_H
>  
> +#include <linux/fsverity.h>
> +
>  /*
>   * Fast and loose check if this write could update the on-disk inode size.
>   */
> @@ -13,6 +15,6 @@ static inline bool xfs_ioend_is_append(struct iomap_ioend *ioend)
>  
>  void xfs_end_bio(struct bio *bio);
>  void xfs_ioend_submit_read(struct inode *inode, struct bio *bio,
> -		loff_t file_offset, u16 ioend_flags);
> +		loff_t file_offset, u16 ioend_flags, struct fsverity_info *vi);
>  
>  #endif /* __XFS_IOEND_H */
> diff --git a/fs/xfs/xfs_super.c b/fs/xfs/xfs_super.c
> index fce1d2905c94..aca50130625e 100644
> --- a/fs/xfs/xfs_super.c
> +++ b/fs/xfs/xfs_super.c
> @@ -2516,8 +2516,20 @@ xfs_init_caches(void)
>  	if (!xfs_parent_args_cache)
>  		goto out_destroy_xmi_cache;
>  
> +#ifdef CONFIG_FS_VERITY
> +	xfs_fsverity_ioend_cache = kmem_cache_create("xfs_fsverity_ioend",
> +					     sizeof(struct xfs_fsverity_ioend),
> +					     0, 0, NULL);
> +	if (!xfs_fsverity_ioend_cache)
> +		goto out_destroy_fsverity_ioend_cache;
> +#endif
> +
>  	return 0;
>  
> +#ifdef CONFIG_FS_VERITY
> + out_destroy_fsverity_ioend_cache:
> +	kmem_cache_destroy(xfs_fsverity_ioend_cache);
> +#endif
>   out_destroy_xmi_cache:
>  	kmem_cache_destroy(xfs_xmi_cache);
>   out_destroy_xmd_cache:
> @@ -2580,6 +2592,9 @@ xfs_destroy_caches(void)
>  	 * destroy caches.
>  	 */
>  	rcu_barrier();
> +#ifdef CONFIG_FS_VERITY
> +	kmem_cache_destroy(xfs_fsverity_ioend_cache);
> +#endif
>  	kmem_cache_destroy(xfs_parent_args_cache);
>  	kmem_cache_destroy(xfs_xmd_cache);
>  	kmem_cache_destroy(xfs_xmi_cache);
> -- 
> 2.54.0
> 
> 

WARNING: multiple messages have this Message-ID (diff)
From: "Darrick J. Wong via Linux-f2fs-devel" <linux-f2fs-devel@lists.sourceforge.net>
To: Andrey Albershteyn <aalbersh@kernel.org>
Cc: fsverity@lists.linux.dev, linux-xfs@vger.kernel.org,
	Carlos Maiolino <cem@kernel.org>,
	david@fromorbit.com, linux-unionfs@vger.kernel.org,
	linux-f2fs-devel@lists.sourceforge.net, ebiggers@kernel.org,
	linux-fsdevel@vger.kernel.org, linux-ext4@vger.kernel.org,
	hch@lst.de, linux-btrfs@vger.kernel.org
Subject: Re: [f2fs-dev] [PATCH v16 12/21] xfs: use read ioend for fsverity data verification
Date: Mon, 21 Sep 2026 21:29:19 -0700	[thread overview]
Message-ID: <20260922042919.GL2705364@frogsfrogsfrogs> (raw)
In-Reply-To: <20260918111539.1003439-13-aalbersh@kernel.org>

On Fri, Sep 18, 2026 at 01:15:24PM +0200, Andrey Albershteyn wrote:
> Use read ioends for fsverity verification. Do not issue fsverity
> metadata I/O through the same workqueue due to risk of a deadlock by a
> filled workqueue.
> 
> Pass fsverity_info from iomap context down to the ioend as hashtable
> lookups are expensive.
> 
> Add a simple helper to check that this is not fsverity metadata but file
> data that needs verification.
> 
> Signed-off-by: Andrey Albershteyn <aalbersh@kernel.org>

Seems fine to me, though I would like to see hch's blessing on this
since he's written more of the read ioend workqueue completion code.

Reviewed-by: "Darrick J. Wong" <djwong@kernel.org>

--D

> ---
>  fs/xfs/xfs_aops.c     | 13 +++++----
>  fs/xfs/xfs_file.c     |  3 +-
>  fs/xfs/xfs_fsverity.c | 11 ++++++++
>  fs/xfs/xfs_fsverity.h | 14 ++++++++++
>  fs/xfs/xfs_ioend.c    | 65 +++++++++++++++++++++++++++++++++++++++----
>  fs/xfs/xfs_ioend.h    |  4 ++-
>  fs/xfs/xfs_super.c    | 15 ++++++++++
>  7 files changed, 112 insertions(+), 13 deletions(-)
> 
> diff --git a/fs/xfs/xfs_aops.c b/fs/xfs/xfs_aops.c
> index 19640e4e3ed1..a36f840884b4 100644
> --- a/fs/xfs/xfs_aops.c
> +++ b/fs/xfs/xfs_aops.c
> @@ -24,6 +24,7 @@
>  #include "xfs_zone_alloc.h"
>  #include "xfs_rtgroup.h"
>  #include "xfs_fsverity.h"
> +#include <linux/fsverity.h>
>  
>  struct xfs_writepage_ctx {
>  	struct iomap_writepage_ctx ctx;
> @@ -611,7 +612,7 @@ xfs_bio_submit_read(
>  {
>  	xfs_ioend_submit_read(iter->inode, ctx->read_ctx,
>  			ctx->read_ctx_file_offset,
> -			iomap_ioend_flags(&iter->iomap));
> +			iomap_ioend_flags(&iter->iomap), ctx->vi);
>  	ctx->read_ctx = NULL;
>  }
>  
> @@ -623,11 +624,13 @@ static const struct iomap_read_ops xfs_iomap_read_ops = {
>  
>  static inline const struct iomap_read_ops *
>  xfs_get_iomap_read_ops(
> -	const struct address_space	*mapping)
> +	const struct address_space	*mapping,
> +	loff_t				pos)
>  {
>  	struct xfs_inode		*ip = XFS_I(mapping->host);
>  
> -	if (bdev_has_integrity_csum(xfs_inode_buftarg(ip)->bt_bdev))
> +	if (bdev_has_integrity_csum(xfs_inode_buftarg(ip)->bt_bdev) ||
> +	    xfs_fsverity_is_file_data(ip, pos))
>  		return &xfs_iomap_read_ops;
>  	return &iomap_bio_read_ops;
>  }
> @@ -639,7 +642,7 @@ xfs_vm_read_folio(
>  {
>  	struct iomap_read_folio_ctx	ctx = { .cur_folio = folio };
>  
> -	ctx.ops = xfs_get_iomap_read_ops(folio->mapping);
> +	ctx.ops = xfs_get_iomap_read_ops(folio->mapping, folio_pos(folio));
>  	iomap_read_folio(&xfs_read_iomap_ops, &ctx, NULL);
>  	return 0;
>  }
> @@ -650,7 +653,7 @@ xfs_vm_readahead(
>  {
>  	struct iomap_read_folio_ctx	ctx = { .rac = rac };
>  
> -	ctx.ops = xfs_get_iomap_read_ops(rac->mapping),
> +	ctx.ops = xfs_get_iomap_read_ops(rac->mapping, readahead_pos(rac));
>  	iomap_readahead(&xfs_read_iomap_ops, &ctx, NULL);
>  }
>  
> diff --git a/fs/xfs/xfs_file.c b/fs/xfs/xfs_file.c
> index 07abf6e8783f..578ca6fb8292 100644
> --- a/fs/xfs/xfs_file.c
> +++ b/fs/xfs/xfs_file.c
> @@ -225,7 +225,8 @@ xfs_dio_read_bounce_submit_io(
>  	loff_t			file_offset)
>  {
>  	xfs_ioend_submit_read(iter->inode, bio, file_offset,
> -			iomap_ioend_flags(&iter->iomap) | IOMAP_IOEND_DIRECT);
> +			iomap_ioend_flags(&iter->iomap) | IOMAP_IOEND_DIRECT,
> +			NULL);
>  }
>  
>  static const struct iomap_dio_ops xfs_dio_read_bounce_ops = {
> diff --git a/fs/xfs/xfs_fsverity.c b/fs/xfs/xfs_fsverity.c
> index e30021c22683..525855fdd30d 100644
> --- a/fs/xfs/xfs_fsverity.c
> +++ b/fs/xfs/xfs_fsverity.c
> @@ -14,9 +14,20 @@
>  #include <linux/fsverity.h>
>  #include <linux/iomap.h>
>  
> +struct kmem_cache *xfs_fsverity_ioend_cache;
> +
>  loff_t
>  xfs_fsverity_metadata_offset(
>  	const struct xfs_inode	*ip)
>  {
>  	return round_up(i_size_read(VFS_IC(ip)), XFS_FSVERITY_START_ALIGN);
>  }
> +
> +bool
> +xfs_fsverity_is_file_data(
> +	const struct xfs_inode	*ip,
> +	loff_t			offset)
> +{
> +	return fsverity_active(VFS_IC(ip)) &&
> +			offset < xfs_fsverity_metadata_offset(ip);
> +}
> diff --git a/fs/xfs/xfs_fsverity.h b/fs/xfs/xfs_fsverity.h
> index c2ab5af89370..836e3a4eb194 100644
> --- a/fs/xfs/xfs_fsverity.h
> +++ b/fs/xfs/xfs_fsverity.h
> @@ -6,15 +6,29 @@
>  #define __XFS_FSVERITY_H__
>  
>  #include "xfs_platform.h"
> +#include <linux/iomap.h>
>  
>  #ifdef CONFIG_FS_VERITY
>  loff_t xfs_fsverity_metadata_offset(const struct xfs_inode *ip);
> +bool xfs_fsverity_is_file_data(const struct xfs_inode *ip, loff_t offset);
>  #else
>  static inline loff_t xfs_fsverity_metadata_offset(const struct xfs_inode *ip)
>  {
>  	WARN_ON_ONCE(1);
>  	return ULLONG_MAX;
>  }
> +static inline bool xfs_fsverity_is_file_data(const struct xfs_inode *ip,
> +					    loff_t offset)
> +{
> +	return false;
> +}
>  #endif	/* CONFIG_FS_VERITY */
>  
> +struct xfs_fsverity_ioend {
> +	struct iomap_ioend	*ioend;
> +	struct work_struct	work;
> +};
> +
> +extern struct kmem_cache *xfs_fsverity_ioend_cache;
> +
>  #endif	/* __XFS_FSVERITY_H__ */
> diff --git a/fs/xfs/xfs_ioend.c b/fs/xfs/xfs_ioend.c
> index e70be5b86f0b..2f46855b052f 100644
> --- a/fs/xfs/xfs_ioend.c
> +++ b/fs/xfs/xfs_ioend.c
> @@ -18,7 +18,26 @@
>  #include "xfs_ioend.h"
>  #include "xfs_error.h"
>  #include "xfs_errortag.h"
> +#include "xfs_fsverity.h"
>  #include <linux/bio-integrity.h>
> +#include <linux/fsverity.h>
> +
> +static void
> +xfs_end_fsverity_io_read(
> +	struct work_struct		*work)
> +{
> +	struct xfs_fsverity_ioend	*fsv_ioend =
> +			container_of(work, struct xfs_fsverity_ioend, work);
> +	struct iomap_ioend		*ioend = fsv_ioend->ioend;
> +	struct bio			*bio = &ioend->io_bio;
> +
> +	kmem_cache_free(xfs_fsverity_ioend_cache, fsv_ioend);
> +
> +	if (!bio->bi_status)
> +		fsverity_verify_bio(ioend->io_vi, bio);
> +
> +	iomap_finish_ioends(ioend, blk_status_to_errno(bio->bi_status));
> +}
>  
>  static void
>  xfs_dio_bounce_end_io(
> @@ -93,12 +112,14 @@ xfs_read_bounce_and_resubmit(
>  
>  static void
>  xfs_end_io_read(
> -	struct bio		*bio)
> +	struct bio			*bio)
>  {
> -	struct iomap_ioend	*ioend = iomap_ioend_from_bio(bio);
> -	struct xfs_inode	*ip = XFS_I(ioend->io_inode);
> -	struct xfs_mount	*mp = ip->i_mount;
> -	int			error = blk_status_to_errno(bio->bi_status);
> +	struct iomap_ioend		*ioend = iomap_ioend_from_bio(bio);
> +	struct xfs_inode		*ip = XFS_I(ioend->io_inode);
> +	struct xfs_mount		*mp = ip->i_mount;
> +	int				error =
> +			blk_status_to_errno(bio->bi_status);
> +	struct xfs_fsverity_ioend	*fsv_ioend;
>  
>  	if (!error && (ioend->io_flags & IOMAP_IOEND_INTEGRITY)) {
>  		error = iomap_ioend_integrity_verify(ioend);
> @@ -117,6 +138,36 @@ xfs_end_io_read(
>  		}
>  	}
>  
> +	/*
> +	 * If we have fsverity and block device integrity attached to this bio,
> +	 * we need to run fsverity verification of data folios from a separate
> +	 * fsverity workqueue. This is necessary to avoid deadlocking due to
> +	 * fsverity issuing more reads of fsverity metadata which would be
> +	 * processed by the same worker in the BIO completion workqueue.
> +	 *
> +	 * Without block device integrity, fsverity metadata IO will not use
> +	 * ioends for completion.
> +	 */
> +	if (IS_ENABLED(CONFIG_FS_VERITY) && !error && ioend->io_vi &&
> +			xfs_fsverity_is_file_data(ip, ioend->io_offset)) {
> +		if (ioend->io_flags & IOMAP_IOEND_INTEGRITY) {
> +			fsv_ioend = kmem_cache_zalloc(xfs_fsverity_ioend_cache,
> +					GFP_KERNEL);
> +			if (!fsv_ioend) {
> +				iomap_finish_ioends(ioend, -ENOMEM);
> +				return;
> +			}
> +			fsv_ioend->ioend = ioend;
> +			INIT_WORK(&fsv_ioend->work, xfs_end_fsverity_io_read);
> +
> +			fsverity_enqueue_verify_work(&fsv_ioend->work);
> +			return;
> +		}
> +
> +		fsverity_verify_bio(ioend->io_vi, &ioend->io_bio);
> +		error = blk_status_to_errno(ioend->io_bio.bi_status);
> +	}
> +
>  	iomap_finish_ioends(ioend, error);
>  }
>  
> @@ -125,13 +176,15 @@ xfs_ioend_submit_read(
>  	struct inode		*inode,
>  	struct bio		*bio,
>  	loff_t			file_offset,
> -	u16			ioend_flags)
> +	u16			ioend_flags,
> +	struct fsverity_info	*vi)
>  {
>  	struct xfs_inode	*ip = XFS_I(inode);
>  	struct xfs_mount	*mp = ip->i_mount;
>  	struct iomap_ioend	*ioend;
>  
>  	ioend = iomap_init_ioend(inode, bio, file_offset, ioend_flags);
> +	ioend->io_vi = vi;
>  	if ((ioend_flags & IOMAP_IOEND_DIRECT) &&
>  	    READ_ONCE(mp->m_read_bounce) == XFS_READ_BOUNCE_ALWAYS) {
>  		iomap_bounce_read(ioend, bdev_logical_block_size(bio->bi_bdev),
> diff --git a/fs/xfs/xfs_ioend.h b/fs/xfs/xfs_ioend.h
> index 7c2a1ea3e6ed..992c248a693a 100644
> --- a/fs/xfs/xfs_ioend.h
> +++ b/fs/xfs/xfs_ioend.h
> @@ -2,6 +2,8 @@
>  #ifndef __XFS_IOEND_H
>  #define __XFS_IOEND_H
>  
> +#include <linux/fsverity.h>
> +
>  /*
>   * Fast and loose check if this write could update the on-disk inode size.
>   */
> @@ -13,6 +15,6 @@ static inline bool xfs_ioend_is_append(struct iomap_ioend *ioend)
>  
>  void xfs_end_bio(struct bio *bio);
>  void xfs_ioend_submit_read(struct inode *inode, struct bio *bio,
> -		loff_t file_offset, u16 ioend_flags);
> +		loff_t file_offset, u16 ioend_flags, struct fsverity_info *vi);
>  
>  #endif /* __XFS_IOEND_H */
> diff --git a/fs/xfs/xfs_super.c b/fs/xfs/xfs_super.c
> index fce1d2905c94..aca50130625e 100644
> --- a/fs/xfs/xfs_super.c
> +++ b/fs/xfs/xfs_super.c
> @@ -2516,8 +2516,20 @@ xfs_init_caches(void)
>  	if (!xfs_parent_args_cache)
>  		goto out_destroy_xmi_cache;
>  
> +#ifdef CONFIG_FS_VERITY
> +	xfs_fsverity_ioend_cache = kmem_cache_create("xfs_fsverity_ioend",
> +					     sizeof(struct xfs_fsverity_ioend),
> +					     0, 0, NULL);
> +	if (!xfs_fsverity_ioend_cache)
> +		goto out_destroy_fsverity_ioend_cache;
> +#endif
> +
>  	return 0;
>  
> +#ifdef CONFIG_FS_VERITY
> + out_destroy_fsverity_ioend_cache:
> +	kmem_cache_destroy(xfs_fsverity_ioend_cache);
> +#endif
>   out_destroy_xmi_cache:
>  	kmem_cache_destroy(xfs_xmi_cache);
>   out_destroy_xmd_cache:
> @@ -2580,6 +2592,9 @@ xfs_destroy_caches(void)
>  	 * destroy caches.
>  	 */
>  	rcu_barrier();
> +#ifdef CONFIG_FS_VERITY
> +	kmem_cache_destroy(xfs_fsverity_ioend_cache);
> +#endif
>  	kmem_cache_destroy(xfs_parent_args_cache);
>  	kmem_cache_destroy(xfs_xmd_cache);
>  	kmem_cache_destroy(xfs_xmi_cache);
> -- 
> 2.54.0
> 
> 


_______________________________________________
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel

  parent reply	other threads:[~2026-09-22  4:29 UTC|newest]

Thread overview: 111+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-09-18 11:15 [PATCH v16 00/21] fs-verity support for XFS with post EOF merkle tree Andrey Albershteyn
2026-09-18 11:15 ` [f2fs-dev] " Andrey Albershteyn via Linux-f2fs-devel
2026-09-18 11:15 ` [PATCH v16 01/21] fsverity: report validation errors through fserror to fsnotify Andrey Albershteyn
2026-09-18 11:15   ` [f2fs-dev] " Andrey Albershteyn via Linux-f2fs-devel
2026-09-18 11:27   ` sashiko-bot
2026-09-18 11:15 ` [PATCH v16 02/21] fsverity: expose ensure_fsverity_info() Andrey Albershteyn
2026-09-18 11:15   ` [f2fs-dev] " Andrey Albershteyn via Linux-f2fs-devel
2026-09-18 11:32   ` sashiko-bot
2026-09-18 11:15 ` [PATCH v16 03/21] fsverity: pass digest size and hash of the all-zeroes block to ->write Andrey Albershteyn
2026-09-18 11:15   ` [f2fs-dev] " Andrey Albershteyn via Linux-f2fs-devel
2026-09-18 11:24   ` sashiko-bot
2026-09-18 11:15 ` [PATCH v16 04/21] fsverity: hoist pagecache_read from f2fs/ext4 to fsverity Andrey Albershteyn
2026-09-18 11:15   ` [f2fs-dev] " Andrey Albershteyn via Linux-f2fs-devel
2026-09-18 11:26   ` sashiko-bot
2026-09-18 11:15 ` [PATCH v16 05/21] fsverity: don't allow setting DAX file attribute on fsverity files Andrey Albershteyn
2026-09-18 11:15   ` [f2fs-dev] " Andrey Albershteyn via Linux-f2fs-devel
2026-09-18 11:28   ` sashiko-bot
2026-09-25  4:35   ` Eric Biggers
2026-09-25  4:35     ` [f2fs-dev] " Eric Biggers via Linux-f2fs-devel
2026-09-18 11:15 ` [PATCH v16 06/21] fsverity: hoist statx reporting of fs-verity flag Andrey Albershteyn
2026-09-18 11:15   ` [f2fs-dev] " Andrey Albershteyn via Linux-f2fs-devel
2026-09-18 11:28   ` sashiko-bot
2026-09-18 11:15 ` [PATCH v16 07/21] xfs: introduce fsverity on-disk changes Andrey Albershteyn
2026-09-18 11:15   ` [f2fs-dev] " Andrey Albershteyn via Linux-f2fs-devel
2026-09-18 11:34   ` sashiko-bot
2026-09-18 11:15 ` [PATCH v16 08/21] xfs: don't allow to enable DAX on fs-verity sealed inode Andrey Albershteyn
2026-09-18 11:15   ` [f2fs-dev] " Andrey Albershteyn via Linux-f2fs-devel
2026-09-18 11:27   ` sashiko-bot
2026-09-18 11:15 ` [PATCH v16 09/21] xfs: disable direct read path for fs-verity files Andrey Albershteyn
2026-09-18 11:15   ` [f2fs-dev] " Andrey Albershteyn via Linux-f2fs-devel
2026-09-18 11:26   ` sashiko-bot
2026-09-18 11:15 ` [PATCH v16 10/21] xfs: don't report dio_mem_align and dio_offset_align for fsverity files Andrey Albershteyn
2026-09-18 11:15   ` [f2fs-dev] " Andrey Albershteyn via Linux-f2fs-devel
2026-09-18 11:26   ` sashiko-bot
2026-09-18 11:15 ` [PATCH v16 11/21] xfs: handle fsverity I/O in write/read path Andrey Albershteyn
2026-09-18 11:15   ` [f2fs-dev] " Andrey Albershteyn via Linux-f2fs-devel
2026-09-18 11:38   ` sashiko-bot
2026-09-22  7:15   ` Christoph Hellwig
2026-09-22  7:15     ` [f2fs-dev] " Christoph Hellwig
2026-09-18 11:15 ` [PATCH v16 12/21] xfs: use read ioend for fsverity data verification Andrey Albershteyn
2026-09-18 11:15   ` [f2fs-dev] " Andrey Albershteyn via Linux-f2fs-devel
2026-09-18 11:36   ` sashiko-bot
2026-09-22  4:29   ` Darrick J. Wong [this message]
2026-09-22  4:29     ` [f2fs-dev] " Darrick J. Wong via Linux-f2fs-devel
2026-09-22  7:18   ` Christoph Hellwig
2026-09-22  7:18     ` [f2fs-dev] " Christoph Hellwig
2026-09-22  9:13     ` Andrey Albershteyn
2026-09-22  9:13       ` [f2fs-dev] " Andrey Albershteyn via Linux-f2fs-devel
2026-09-22 12:31       ` Christoph Hellwig
2026-09-22 12:31         ` [f2fs-dev] " Christoph Hellwig
2026-09-22 13:17         ` Andrey Albershteyn
2026-09-22 13:17           ` [f2fs-dev] " Andrey Albershteyn via Linux-f2fs-devel
2026-09-18 11:15 ` [PATCH v16 13/21] xfs: add XFS_BMAPI_UNWRITTEN to unmap unwritten extents in __xfs_bunmapi() Andrey Albershteyn
2026-09-18 11:15   ` [f2fs-dev] " Andrey Albershteyn via Linux-f2fs-devel
2026-09-18 11:32   ` sashiko-bot
2026-09-22  4:49     ` Darrick J. Wong
2026-09-22  4:34   ` Darrick J. Wong
2026-09-22  4:34     ` [f2fs-dev] " Darrick J. Wong via Linux-f2fs-devel
2026-09-22  7:20     ` Christoph Hellwig
2026-09-22  7:20       ` [f2fs-dev] " Christoph Hellwig
2026-09-22  8:32       ` Andrey Albershteyn
2026-09-22  8:32         ` [f2fs-dev] " Andrey Albershteyn via Linux-f2fs-devel
2026-09-18 11:15 ` [PATCH v16 14/21] xfs: don't remove written extents past EOF on fsverity inodes Andrey Albershteyn
2026-09-18 11:15   ` [f2fs-dev] " Andrey Albershteyn via Linux-f2fs-devel
2026-09-18 11:41   ` sashiko-bot
2026-09-22  4:37   ` Darrick J. Wong
2026-09-22  4:37     ` [f2fs-dev] " Darrick J. Wong via Linux-f2fs-devel
2026-09-22  8:33     ` Andrey Albershteyn
2026-09-22  8:33       ` [f2fs-dev] " Andrey Albershteyn via Linux-f2fs-devel
2026-09-22 11:29       ` Andrey Albershteyn
2026-09-22 11:29         ` [f2fs-dev] " Andrey Albershteyn via Linux-f2fs-devel
2026-09-18 11:15 ` [PATCH v16 15/21] xfs: add fs-verity support Andrey Albershteyn
2026-09-18 11:15   ` [f2fs-dev] " Andrey Albershteyn via Linux-f2fs-devel
2026-09-18 11:43   ` sashiko-bot
2026-09-22  4:50     ` Darrick J. Wong
2026-09-22  4:45   ` Darrick J. Wong
2026-09-22  4:45     ` [f2fs-dev] " Darrick J. Wong via Linux-f2fs-devel
2026-09-22  9:27     ` Andrey Albershteyn
2026-09-22  9:27       ` [f2fs-dev] " Andrey Albershteyn via Linux-f2fs-devel
2026-09-22  7:22   ` Christoph Hellwig
2026-09-22  7:22     ` [f2fs-dev] " Christoph Hellwig
2026-09-22  8:56     ` Andrey Albershteyn
2026-09-22  8:56       ` [f2fs-dev] " Andrey Albershteyn via Linux-f2fs-devel
2026-09-22 12:32       ` Christoph Hellwig
2026-09-22 12:32         ` [f2fs-dev] " Christoph Hellwig
2026-09-22 13:27         ` Andrey Albershteyn
2026-09-22 13:27           ` [f2fs-dev] " Andrey Albershteyn via Linux-f2fs-devel
2026-09-23  4:44           ` Christoph Hellwig
2026-09-23  4:44             ` [f2fs-dev] " Christoph Hellwig
2026-09-18 11:15 ` [PATCH v16 16/21] xfs: initialize fs-verity on file open Andrey Albershteyn
2026-09-18 11:15   ` [f2fs-dev] " Andrey Albershteyn via Linux-f2fs-devel
2026-09-18 11:33   ` sashiko-bot
2026-09-18 11:15 ` [PATCH v16 17/21] xfs: add fs-verity ioctls Andrey Albershteyn
2026-09-18 11:15   ` [f2fs-dev] " Andrey Albershteyn via Linux-f2fs-devel
2026-09-18 11:31   ` sashiko-bot
2026-09-18 11:15 ` [PATCH v16 18/21] xfs: advertise fs-verity being available on filesystem Andrey Albershteyn
2026-09-18 11:15   ` [f2fs-dev] " Andrey Albershteyn via Linux-f2fs-devel
2026-09-18 11:30   ` sashiko-bot
2026-09-18 11:15 ` [PATCH v16 19/21] xfs: check and repair the verity inode flag state Andrey Albershteyn
2026-09-18 11:15   ` [f2fs-dev] " Andrey Albershteyn via Linux-f2fs-devel
2026-09-18 11:40   ` sashiko-bot
2026-09-18 11:15 ` [PATCH v16 20/21] xfs: introduce health state for corrupted fsverity metadata Andrey Albershteyn
2026-09-18 11:15   ` [f2fs-dev] " Andrey Albershteyn via Linux-f2fs-devel
2026-09-18 11:34   ` sashiko-bot
2026-09-18 11:15 ` [PATCH v16 21/21] xfs: enable ro-compat fs-verity flag Andrey Albershteyn
2026-09-18 11:15   ` [f2fs-dev] " Andrey Albershteyn via Linux-f2fs-devel
2026-09-18 11:44   ` sashiko-bot
2026-09-22  4:51 ` [PATCH v16 00/21] fs-verity support for XFS with post EOF merkle tree Darrick J. Wong
2026-09-22  4:51   ` [f2fs-dev] " Darrick J. Wong via Linux-f2fs-devel
2026-09-22  9:00   ` Andrey Albershteyn
2026-09-22  9:00     ` [f2fs-dev] " Andrey Albershteyn via Linux-f2fs-devel

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=20260922042919.GL2705364@frogsfrogsfrogs \
    --to=djwong@kernel.org \
    --cc=aalbersh@kernel.org \
    --cc=cem@kernel.org \
    --cc=david@fromorbit.com \
    --cc=ebiggers@kernel.org \
    --cc=fsverity@lists.linux.dev \
    --cc=hch@lst.de \
    --cc=linux-btrfs@vger.kernel.org \
    --cc=linux-ext4@vger.kernel.org \
    --cc=linux-f2fs-devel@lists.sourceforge.net \
    --cc=linux-fsdevel@vger.kernel.org \
    --cc=linux-unionfs@vger.kernel.org \
    --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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.