From: Christoph Hellwig Date: Mon, 26 Jan 2026 05:53:41 +0000 (+0100) Subject: iomap: share code between iomap_dio_bio_end_io and iomap_finish_ioend_direct X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=e2fcff5bb4c48bf602082e5a1428ff7328f7558f;p=thirdparty%2Flinux.git iomap: share code between iomap_dio_bio_end_io and iomap_finish_ioend_direct Refactor the two per-bio completion handlers to share common code using a new helper. Signed-off-by: Christoph Hellwig Reviewed-by: Damien Le Moal Reviewed-by: Darrick J. Wong Tested-by: Anuj Gupta Signed-off-by: Jens Axboe --- diff --git a/fs/iomap/direct-io.c b/fs/iomap/direct-io.c index bb79519dec657..c1d5db85c8c78 100644 --- a/fs/iomap/direct-io.c +++ b/fs/iomap/direct-io.c @@ -211,16 +211,20 @@ static void iomap_dio_done(struct iomap_dio *dio) iomap_dio_complete_work(&dio->aio.work); } -void iomap_dio_bio_end_io(struct bio *bio) +static void __iomap_dio_bio_end_io(struct bio *bio, bool inline_completion) { struct iomap_dio *dio = bio->bi_private; bool should_dirty = (dio->flags & IOMAP_DIO_DIRTY); - if (bio->bi_status) - iomap_dio_set_error(dio, blk_status_to_errno(bio->bi_status)); - - if (atomic_dec_and_test(&dio->ref)) + if (atomic_dec_and_test(&dio->ref)) { + /* + * Avoid another context switch for the completion when already + * called from the ioend completion workqueue. + */ + if (inline_completion) + dio->flags &= ~IOMAP_DIO_COMP_WORK; iomap_dio_done(dio); + } if (should_dirty) { bio_check_pages_dirty(bio); @@ -229,33 +233,25 @@ void iomap_dio_bio_end_io(struct bio *bio) bio_put(bio); } } + +void iomap_dio_bio_end_io(struct bio *bio) +{ + struct iomap_dio *dio = bio->bi_private; + + if (bio->bi_status) + iomap_dio_set_error(dio, blk_status_to_errno(bio->bi_status)); + __iomap_dio_bio_end_io(bio, false); +} EXPORT_SYMBOL_GPL(iomap_dio_bio_end_io); u32 iomap_finish_ioend_direct(struct iomap_ioend *ioend) { struct iomap_dio *dio = ioend->io_bio.bi_private; - bool should_dirty = (dio->flags & IOMAP_DIO_DIRTY); u32 vec_count = ioend->io_bio.bi_vcnt; if (ioend->io_error) iomap_dio_set_error(dio, ioend->io_error); - - if (atomic_dec_and_test(&dio->ref)) { - /* - * Try to avoid another context switch for the completion given - * that we are already called from the ioend completion - * workqueue. - */ - dio->flags &= ~IOMAP_DIO_COMP_WORK; - iomap_dio_done(dio); - } - - if (should_dirty) { - bio_check_pages_dirty(&ioend->io_bio); - } else { - bio_release_pages(&ioend->io_bio, false); - bio_put(&ioend->io_bio); - } + __iomap_dio_bio_end_io(&ioend->io_bio, true); /* * Return the number of bvecs completed as even direct I/O completions