aboutsummaryrefslogtreecommitdiffstats
path: root/block
diff options
authorChristoph Hellwig <hch@lst.de>2026-01-14 14:06:41 +0100
committerCarlos Maiolino <cem@kernel.org>2026-01-21 12:57:16 +0100
commit7ca44303f9f6160a2f87ae3d5d2326d9127cd61c (patch)
tree086776d9211d63edff93e02143681cd8ecffddd8 /block
parentcf9b52fa7d65362b648927d1d752ec99659f5c43 (diff)
downloadath-7ca44303f9f6160a2f87ae3d5d2326d9127cd61c.tar.gz
block: add a bio_reuse helper
Add a helper to allow an existing bio to be resubmitted without having to re-add the payload. Signed-off-by: Christoph Hellwig <hch@lst.de> Reviewed-by: Jens Axboe <axboe@kernel.dk> Reviewed-by: Hans Holmberg <hans.holmberg@wdc.com> Reviewed-by: Carlos Maiolino <cmaiolino@redhat.com> Reviewed-by: Damien Le Moal <dlemoal@kernel.org> Reviewed-by: Darrick J. Wong <djwong@kernel.org> Signed-off-by: Carlos Maiolino <cem@kernel.org>
Diffstat (limited to 'block')
-rw-r--r--block/bio.c34
1 files changed, 34 insertions, 0 deletions
diff --git a/block/bio.c b/block/bio.c
index e726c0e280a8d..40f690985bfb6 100644
--- a/block/bio.c
+++ b/block/bio.c
@@ -311,6 +311,40 @@ void bio_reset(struct bio *bio, struct block_device *bdev, blk_opf_t opf)
}
EXPORT_SYMBOL(bio_reset);
+/**
+ * bio_reuse - reuse a bio with the payload left intact
+ * @bio: bio to reuse
+ * @opf: operation and flags for the next I/O
+ *
+ * Allow reusing an existing bio for another operation with all set up
+ * fields including the payload, device and end_io handler left intact.
+ *
+ * Typically used when @bio is first used to read data which is then written
+ * to another location without modification. @bio must not be in-flight and
+ * owned by the caller. Can't be used for cloned bios.
+ *
+ * Note: Can't be used when @bio has integrity or blk-crypto contexts for now.
+ * Feel free to add that support when you need it, though.
+ */
+void bio_reuse(struct bio *bio, blk_opf_t opf)
+{
+ unsigned short vcnt = bio->bi_vcnt, i;
+ bio_end_io_t *end_io = bio->bi_end_io;
+ void *private = bio->bi_private;
+
+ WARN_ON_ONCE(bio_flagged(bio, BIO_CLONED));
+ WARN_ON_ONCE(bio_integrity(bio));
+ WARN_ON_ONCE(bio_has_crypt_ctx(bio));
+
+ bio_reset(bio, bio->bi_bdev, opf);
+ for (i = 0; i < vcnt; i++)
+ bio->bi_iter.bi_size += bio->bi_io_vec[i].bv_len;
+ bio->bi_vcnt = vcnt;
+ bio->bi_private = private;
+ bio->bi_end_io = end_io;
+}
+EXPORT_SYMBOL_GPL(bio_reuse);
+
static struct bio *__bio_chain_endio(struct bio *bio)
{
struct bio *parent = bio->bi_private;