Skip to content

Commit e2fcff5

Browse files
Christoph Hellwigaxboe
authored andcommitted
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>
1 parent 2631c94 commit e2fcff5

1 file changed

Lines changed: 19 additions & 23 deletions

File tree

fs/iomap/direct-io.c

Lines changed: 19 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -211,16 +211,20 @@ static void iomap_dio_done(struct iomap_dio *dio)
211211
iomap_dio_complete_work(&dio->aio.work);
212212
}
213213

214-
void iomap_dio_bio_end_io(struct bio *bio)
214+
static void __iomap_dio_bio_end_io(struct bio *bio, bool inline_completion)
215215
{
216216
struct iomap_dio *dio = bio->bi_private;
217217
bool should_dirty = (dio->flags & IOMAP_DIO_DIRTY);
218218

219-
if (bio->bi_status)
220-
iomap_dio_set_error(dio, blk_status_to_errno(bio->bi_status));
221-
222-
if (atomic_dec_and_test(&dio->ref))
219+
if (atomic_dec_and_test(&dio->ref)) {
220+
/*
221+
* Avoid another context switch for the completion when already
222+
* called from the ioend completion workqueue.
223+
*/
224+
if (inline_completion)
225+
dio->flags &= ~IOMAP_DIO_COMP_WORK;
223226
iomap_dio_done(dio);
227+
}
224228

225229
if (should_dirty) {
226230
bio_check_pages_dirty(bio);
@@ -229,33 +233,25 @@ void iomap_dio_bio_end_io(struct bio *bio)
229233
bio_put(bio);
230234
}
231235
}
236+
237+
void iomap_dio_bio_end_io(struct bio *bio)
238+
{
239+
struct iomap_dio *dio = bio->bi_private;
240+
241+
if (bio->bi_status)
242+
iomap_dio_set_error(dio, blk_status_to_errno(bio->bi_status));
243+
__iomap_dio_bio_end_io(bio, false);
244+
}
232245
EXPORT_SYMBOL_GPL(iomap_dio_bio_end_io);
233246

234247
u32 iomap_finish_ioend_direct(struct iomap_ioend *ioend)
235248
{
236249
struct iomap_dio *dio = ioend->io_bio.bi_private;
237-
bool should_dirty = (dio->flags & IOMAP_DIO_DIRTY);
238250
u32 vec_count = ioend->io_bio.bi_vcnt;
239251

240252
if (ioend->io_error)
241253
iomap_dio_set_error(dio, ioend->io_error);
242-
243-
if (atomic_dec_and_test(&dio->ref)) {
244-
/*
245-
* Try to avoid another context switch for the completion given
246-
* that we are already called from the ioend completion
247-
* workqueue.
248-
*/
249-
dio->flags &= ~IOMAP_DIO_COMP_WORK;
250-
iomap_dio_done(dio);
251-
}
252-
253-
if (should_dirty) {
254-
bio_check_pages_dirty(&ioend->io_bio);
255-
} else {
256-
bio_release_pages(&ioend->io_bio, false);
257-
bio_put(&ioend->io_bio);
258-
}
254+
__iomap_dio_bio_end_io(&ioend->io_bio, true);
259255

260256
/*
261257
* Return the number of bvecs completed as even direct I/O completions

0 commit comments

Comments
 (0)