Skip to content

Commit 6fa7475

Browse files
Christoph Hellwigaxboe
authored andcommitted
block: factor out a bio_await helper
Add a new helper to wait for a bio and anything chained off it to complete synchronously after submitting it. This factors common code out of submit_bio_wait and bio_await_chain and will also be useful for file system code and thus is exported. Note that this will now set REQ_SYNC also for the bio_await case for consistency. Nothing should look at the flag in the end_io handler, but if something does having the flag set makes more sense. Signed-off-by: Christoph Hellwig <hch@lst.de> Reviewed-by: Damien Le Moal <dlemoal@kernel.org> Link: https://patch.msgid.link/20260407140538.633364-4-hch@lst.de Signed-off-by: Jens Axboe <axboe@kernel.dk>
1 parent 65565ca commit 6fa7475

2 files changed

Lines changed: 39 additions & 16 deletions

File tree

block/bio.c

Lines changed: 37 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1468,31 +1468,58 @@ static void bio_wait_end_io(struct bio *bio)
14681468
}
14691469

14701470
/**
1471-
* submit_bio_wait - submit a bio, and wait until it completes
1472-
* @bio: The &struct bio which describes the I/O
1471+
* bio_await - call a function on a bio, and wait until it completes
1472+
* @bio: the bio which describes the I/O
1473+
* @submit: function called to submit the bio
1474+
* @priv: private data passed to @submit
14731475
*
1474-
* Simple wrapper around submit_bio(). Returns 0 on success, or the error from
1475-
* bio_endio() on failure.
1476+
* Wait for the bio as well as any bio chained off it after executing the
1477+
* passed in callback @submit. The wait for the bio is set up before calling
1478+
* @submit to ensure that the completion is captured. If @submit is %NULL,
1479+
* submit_bio() is used instead to submit the bio.
14761480
*
1477-
* WARNING: Unlike to how submit_bio() is usually used, this function does not
1478-
* result in bio reference to be consumed. The caller must drop the reference
1479-
* on his own.
1481+
* Note: this overrides the bi_private and bi_end_io fields in the bio.
14801482
*/
1481-
int submit_bio_wait(struct bio *bio)
1483+
void bio_await(struct bio *bio, void *priv,
1484+
void (*submit)(struct bio *bio, void *priv))
14821485
{
14831486
DECLARE_COMPLETION_ONSTACK_MAP(done,
14841487
bio->bi_bdev->bd_disk->lockdep_map);
14851488

14861489
bio->bi_private = &done;
14871490
bio->bi_end_io = bio_wait_end_io;
14881491
bio->bi_opf |= REQ_SYNC;
1489-
submit_bio(bio);
1492+
if (submit)
1493+
submit(bio, priv);
1494+
else
1495+
submit_bio(bio);
14901496
blk_wait_io(&done);
1497+
}
1498+
EXPORT_SYMBOL_GPL(bio_await);
14911499

1500+
/**
1501+
* submit_bio_wait - submit a bio, and wait until it completes
1502+
* @bio: The &struct bio which describes the I/O
1503+
*
1504+
* Simple wrapper around submit_bio(). Returns 0 on success, or the error from
1505+
* bio_endio() on failure.
1506+
*
1507+
* WARNING: Unlike to how submit_bio() is usually used, this function does not
1508+
* result in bio reference to be consumed. The caller must drop the reference
1509+
* on his own.
1510+
*/
1511+
int submit_bio_wait(struct bio *bio)
1512+
{
1513+
bio_await(bio, NULL, NULL);
14921514
return blk_status_to_errno(bio->bi_status);
14931515
}
14941516
EXPORT_SYMBOL(submit_bio_wait);
14951517

1518+
static void bio_endio_cb(struct bio *bio, void *priv)
1519+
{
1520+
bio_endio(bio);
1521+
}
1522+
14961523
/**
14971524
* bdev_rw_virt - synchronously read into / write from kernel mapping
14981525
* @bdev: block device to access
@@ -1528,13 +1555,7 @@ EXPORT_SYMBOL_GPL(bdev_rw_virt);
15281555
*/
15291556
void bio_await_chain(struct bio *bio)
15301557
{
1531-
DECLARE_COMPLETION_ONSTACK_MAP(done,
1532-
bio->bi_bdev->bd_disk->lockdep_map);
1533-
1534-
bio->bi_private = &done;
1535-
bio->bi_end_io = bio_wait_end_io;
1536-
bio_endio(bio);
1537-
blk_wait_io(&done);
1558+
bio_await(bio, NULL, bio_endio_cb);
15381559
bio_put(bio);
15391560
}
15401561

include/linux/bio.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -432,6 +432,8 @@ extern void bio_uninit(struct bio *);
432432
void bio_reset(struct bio *bio, struct block_device *bdev, blk_opf_t opf);
433433
void bio_reuse(struct bio *bio, blk_opf_t opf);
434434
void bio_chain(struct bio *, struct bio *);
435+
void bio_await(struct bio *bio, void *priv,
436+
void (*submit)(struct bio *bio, void *priv));
435437

436438
int __must_check bio_add_page(struct bio *bio, struct page *page, unsigned len,
437439
unsigned off);

0 commit comments

Comments
 (0)