aboutsummaryrefslogtreecommitdiffstats
path: root/fs/bio.c
diff options
context:
space:
mode:
authorKent Overstreet <kmo@daterainc.com>2013-11-23 20:26:46 -0500
committerKent Overstreet <kmo@daterainc.com>2013-11-24 01:33:53 -0500
commitbdb53207411ae39b8a80dda0a66d1b468cbe1380 (patch)
treeba0473f17eb5a6ee399b2e0ce0c9e0289fa10d6c /fs/bio.c
parentf619d25460473788944e3b71b030398681e8809b (diff)
block: Refactor bio_clone_bioset() for immutable biovecs
bio_clone() needs to produce a bio that's suitable for the caller to munge with the biovec. Part of the immutable biovec patch series is fixing stuff up so that submitting partially completed bios is safe and works: thus, we now need bio_clone() on a partially completed bio to produce a bio for which bi_idx and bi_bvec done are 0 - like they would be if the caller had just allocated a new bio. Signed-off-by: Kent Overstreet <kmo@daterainc.com> Cc: Jens Axboe <axboe@kernel.dk>
Diffstat (limited to 'fs/bio.c')
-rw-r--r--fs/bio.c60
1 files changed, 47 insertions, 13 deletions
diff --git a/fs/bio.c b/fs/bio.c
index a082ce2d197b..1628917e262a 100644
--- a/fs/bio.c
+++ b/fs/bio.c
@@ -549,36 +549,70 @@ void __bio_clone(struct bio *bio, struct bio *bio_src)
549EXPORT_SYMBOL(__bio_clone); 549EXPORT_SYMBOL(__bio_clone);
550 550
551/** 551/**
552 * bio_clone_bioset - clone a bio 552 * bio_clone_bioset - clone a bio
553 * @bio: bio to clone 553 * @bio_src: bio to clone
554 * @gfp_mask: allocation priority 554 * @gfp_mask: allocation priority
555 * @bs: bio_set to allocate from 555 * @bs: bio_set to allocate from
556 * 556 *
557 * Like __bio_clone, only also allocates the returned bio 557 * Clone bio. Caller will own the returned bio, but not the actual data it
558 * points to. Reference count of returned bio will be one.
558 */ 559 */
559struct bio *bio_clone_bioset(struct bio *bio, gfp_t gfp_mask, 560struct bio *bio_clone_bioset(struct bio *bio_src, gfp_t gfp_mask,
560 struct bio_set *bs) 561 struct bio_set *bs)
561{ 562{
562 struct bio *b; 563 unsigned nr_iovecs = 0;
564 struct bvec_iter iter;
565 struct bio_vec bv;
566 struct bio *bio;
567
568 /*
569 * Pre immutable biovecs, __bio_clone() used to just do a memcpy from
570 * bio_src->bi_io_vec to bio->bi_io_vec.
571 *
572 * We can't do that anymore, because:
573 *
574 * - The point of cloning the biovec is to produce a bio with a biovec
575 * the caller can modify: bi_idx and bi_bvec_done should be 0.
576 *
577 * - The original bio could've had more than BIO_MAX_PAGES biovecs; if
578 * we tried to clone the whole thing bio_alloc_bioset() would fail.
579 * But the clone should succeed as long as the number of biovecs we
580 * actually need to allocate is fewer than BIO_MAX_PAGES.
581 *
582 * - Lastly, bi_vcnt should not be looked at or relied upon by code
583 * that does not own the bio - reason being drivers don't use it for
584 * iterating over the biovec anymore, so expecting it to be kept up
585 * to date (i.e. for clones that share the parent biovec) is just
586 * asking for trouble and would force extra work on
587 * __bio_clone_fast() anyways.
588 */
589
590 bio_for_each_segment(bv, bio_src, iter)
591 nr_iovecs++;
563 592
564 b = bio_alloc_bioset(gfp_mask, bio->bi_max_vecs, bs); 593 bio = bio_alloc_bioset(gfp_mask, nr_iovecs, bs);
565 if (!b) 594 if (!bio)
566 return NULL; 595 return NULL;
567 596
568 __bio_clone(b, bio); 597 bio->bi_bdev = bio_src->bi_bdev;
598 bio->bi_rw = bio_src->bi_rw;
599 bio->bi_iter.bi_sector = bio_src->bi_iter.bi_sector;
600 bio->bi_iter.bi_size = bio_src->bi_iter.bi_size;
569 601
570 if (bio_integrity(bio)) { 602 bio_for_each_segment(bv, bio_src, iter)
571 int ret; 603 bio->bi_io_vec[bio->bi_vcnt++] = bv;
572 604
573 ret = bio_integrity_clone(b, bio, gfp_mask); 605 if (bio_integrity(bio_src)) {
606 int ret;
574 607
608 ret = bio_integrity_clone(bio, bio_src, gfp_mask);
575 if (ret < 0) { 609 if (ret < 0) {
576 bio_put(b); 610 bio_put(bio);
577 return NULL; 611 return NULL;
578 } 612 }
579 } 613 }
580 614
581 return b; 615 return bio;
582} 616}
583EXPORT_SYMBOL(bio_clone_bioset); 617EXPORT_SYMBOL(bio_clone_bioset);
584 618