Re: [PATCH 01/22] iomap: add a separate bio_set for iomap_split_ioend
"Darrick J. Wong" <[email protected]>
| Newsgroups | org.kernel.vger.linux-xfs,org.kernel.vger.linux-block,org.kernel.vger.linux-fsdevel |
|---|---|
| Message-ID | <20260723164907.GA2901224@frogsfrogsfrogs> |
On Thu, Jul 23, 2026 at 04:49:26PM +0200, Christoph Hellwig wrote:
> iomap_split_ioend can split bios that already come from
> iomap_ioend_bioset and thus deadlock when the bioset is exhausted.
>
> Add a separate bio_set to avoid this deadlock.
>
> Fixes: 5fcbd555d483 ("iomap: split bios to zone append limits in the submission handlers")
> Signed-off-by: Christoph Hellwig <[email protected]>
Cc: <[email protected]> # v6.15
Reviewed-by: "Darrick J. Wong" <[email protected]>
--D
> ---
> fs/iomap/ioend.c | 21 +++++++++++++++++++--
> 1 file changed, 19 insertions(+), 2 deletions(-)
>
> diff --git a/fs/iomap/ioend.c b/fs/iomap/ioend.c
> index 0565328764c1..2ec755a89228 100644
> --- a/fs/iomap/ioend.c
> +++ b/fs/iomap/ioend.c
> @@ -13,6 +13,7 @@
>
> struct bio_set iomap_ioend_bioset;
> EXPORT_SYMBOL_GPL(iomap_ioend_bioset);
> +static struct bio_set iomap_ioend_split_bioset;
>
> struct iomap_ioend *iomap_init_ioend(struct inode *inode,
> struct bio *bio, loff_t file_offset, u16 ioend_flags)
> @@ -486,7 +487,8 @@ struct iomap_ioend *iomap_split_ioend(struct iomap_ioend *ioend,
> sector_offset = ALIGN_DOWN(sector_offset << SECTOR_SHIFT,
> i_blocksize(ioend->io_inode)) >> SECTOR_SHIFT;
>
> - split = bio_split(bio, sector_offset, GFP_NOFS, &iomap_ioend_bioset);
> + split = bio_split(bio, sector_offset, GFP_NOFS,
> + &iomap_ioend_split_bioset);
> if (IS_ERR(split))
> return ERR_CAST(split);
> split->bi_private = bio->bi_private;
> @@ -509,8 +511,23 @@ EXPORT_SYMBOL_GPL(iomap_split_ioend);
>
> static int __init iomap_ioend_init(void)
> {
> - return bioset_init(&iomap_ioend_bioset, 4 * (PAGE_SIZE / SECTOR_SIZE),
> + const unsigned int nr_mempool_entries = 4 * (PAGE_SIZE / SECTOR_SIZE);
> + int error;
> +
> + error = bioset_init(&iomap_ioend_bioset, nr_mempool_entries,
> offsetof(struct iomap_ioend, io_bio),
> BIOSET_NEED_BVECS);
> + if (error)
> + return error;
> + error = bioset_init(&iomap_ioend_split_bioset, nr_mempool_entries,
> + offsetof(struct iomap_ioend, io_bio),
> + BIOSET_NEED_BVECS);
> + if (error)
> + goto out_exit_ioend_bioset;
> + return 0;
> +
> +out_exit_ioend_bioset:
> + bioset_exit(&iomap_ioend_bioset);
> + return error;
> }
> fs_initcall(iomap_ioend_init);
> --
> 2.53.0
>
>