Commit 7ca44303 authored by Christoph Hellwig's avatar Christoph Hellwig Committed by Carlos Maiolino
Browse files

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: default avatarChristoph Hellwig <hch@lst.de>
Reviewed-by: default avatarJens Axboe <axboe@kernel.dk>
Reviewed-by: default avatarHans Holmberg <hans.holmberg@wdc.com>
Reviewed-by: default avatarCarlos Maiolino <cmaiolino@redhat.com>
Reviewed-by: default avatarDamien Le Moal <dlemoal@kernel.org>
Reviewed-by: default avatarDarrick J. Wong <djwong@kernel.org>
Signed-off-by: default avatarCarlos Maiolino <cem@kernel.org>
parent cf9b52fa
Loading
Loading
Loading
Loading
+34 −0
Original line number Diff line number Diff line
@@ -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;
+1 −0
Original line number Diff line number Diff line
@@ -414,6 +414,7 @@ static inline void bio_init_inline(struct bio *bio, struct block_device *bdev,
}
extern void bio_uninit(struct bio *);
void bio_reset(struct bio *bio, struct block_device *bdev, blk_opf_t opf);
void bio_reuse(struct bio *bio, blk_opf_t opf);
void bio_chain(struct bio *, struct bio *);

int __must_check bio_add_page(struct bio *bio, struct page *page, unsigned len,