aboutsummaryrefslogtreecommitdiff
path: root/block
diff options
context:
space:
mode:
authorKeith Busch2024-05-06 06:20:26 +0200
committerJens Axboe2024-05-07 07:29:42 -0600
commit0f8e9ecc4636e3abb4f3cf1ead14c94cce7dfde8 (patch)
tree6f321d692a7047694ba88e824f52ab0b77eb90a5 /block
parente8b4869bc78da1a71f2a2ab476caf50c1dcfeed0 (diff)
block: add a bio_await_chain helper
Add a helper to wait for an entire chain of bios to complete. [hch: split from a larger patch, moved and changed the name now that it is non-static] Signed-off-by: Keith Busch <kbusch@kernel.org> Signed-off-by: Christoph Hellwig <hch@lst.de> Link: https://lore.kernel.org/r/20240506042027.2289826-6-hch@lst.de Signed-off-by: Jens Axboe <axboe@kernel.dk>
Diffstat (limited to 'block')
-rw-r--r--block/bio.c20
-rw-r--r--block/blk.h1
2 files changed, 21 insertions, 0 deletions
diff --git a/block/bio.c b/block/bio.c
index d82ef4fd545c..dce12a0efdea 100644
--- a/block/bio.c
+++ b/block/bio.c
@@ -1395,6 +1395,26 @@ int submit_bio_wait(struct bio *bio)
}
EXPORT_SYMBOL(submit_bio_wait);
+static void bio_wait_end_io(struct bio *bio)
+{
+ complete(bio->bi_private);
+ bio_put(bio);
+}
+
+/*
+ * bio_await_chain - ends @bio and waits for every chained bio to complete
+ */
+void bio_await_chain(struct bio *bio)
+{
+ DECLARE_COMPLETION_ONSTACK_MAP(done,
+ bio->bi_bdev->bd_disk->lockdep_map);
+
+ bio->bi_private = &done;
+ bio->bi_end_io = bio_wait_end_io;
+ bio_endio(bio);
+ blk_wait_io(&done);
+}
+
void __bio_advance(struct bio *bio, unsigned bytes)
{
if (bio_integrity(bio))
diff --git a/block/blk.h b/block/blk.h
index ee4f782d1496..d5107e65355e 100644
--- a/block/blk.h
+++ b/block/blk.h
@@ -38,6 +38,7 @@ void __blk_mq_unfreeze_queue(struct request_queue *q, bool force_atomic);
void blk_queue_start_drain(struct request_queue *q);
int __bio_queue_enter(struct request_queue *q, struct bio *bio);
void submit_bio_noacct_nocheck(struct bio *bio);
+void bio_await_chain(struct bio *bio);
static inline bool blk_try_enter_queue(struct request_queue *q, bool pm)
{