diff options
| author | Christoph Hellwig <hch@lst.de> | 2026-01-26 08:53:41 +0300 |
|---|---|---|
| committer | Jens Axboe <axboe@kernel.dk> | 2026-01-28 15:16:40 +0300 |
| commit | e2fcff5bb4c48bf602082e5a1428ff7328f7558f (patch) | |
| tree | 6774e555610d8da56a35eef5f12b97a39a4484ca | |
| parent | 2631c94602297090febd8f93d6f96d9d2045466d (diff) | |
| download | linux-e2fcff5bb4c48bf602082e5a1428ff7328f7558f.tar.xz | |
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 <hch@lst.de>
Reviewed-by: Damien Le Moal <dlemoal@kernel.org>
Reviewed-by: Darrick J. Wong <djwong@kernel.org>
Tested-by: Anuj Gupta <anuj20.g@samsung.com>
Signed-off-by: Jens Axboe <axboe@kernel.dk>
| -rw-r--r-- | fs/iomap/direct-io.c | 42 |
1 files changed, 19 insertions, 23 deletions
diff --git a/fs/iomap/direct-io.c b/fs/iomap/direct-io.c index bb79519dec65..c1d5db85c8c7 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 |
