diff options
Diffstat (limited to 'fs')
-rw-r--r-- | fs/bio.c | 14 |
1 files changed, 11 insertions, 3 deletions
@@ -525,8 +525,17 @@ EXPORT_SYMBOL(bio_phys_segments); | |||
525 | */ | 525 | */ |
526 | void __bio_clone(struct bio *bio, struct bio *bio_src) | 526 | void __bio_clone(struct bio *bio, struct bio *bio_src) |
527 | { | 527 | { |
528 | memcpy(bio->bi_io_vec, bio_src->bi_io_vec, | 528 | if (bio_is_rw(bio_src)) { |
529 | bio_src->bi_max_vecs * sizeof(struct bio_vec)); | 529 | struct bio_vec bv; |
530 | struct bvec_iter iter; | ||
531 | |||
532 | bio_for_each_segment(bv, bio_src, iter) | ||
533 | bio->bi_io_vec[bio->bi_vcnt++] = bv; | ||
534 | } else if (bio_has_data(bio_src)) { | ||
535 | memcpy(bio->bi_io_vec, bio_src->bi_io_vec, | ||
536 | bio_src->bi_max_vecs * sizeof(struct bio_vec)); | ||
537 | bio->bi_vcnt = bio_src->bi_vcnt; | ||
538 | } | ||
530 | 539 | ||
531 | /* | 540 | /* |
532 | * most users will be overriding ->bi_bdev with a new target, | 541 | * most users will be overriding ->bi_bdev with a new target, |
@@ -535,7 +544,6 @@ void __bio_clone(struct bio *bio, struct bio *bio_src) | |||
535 | bio->bi_bdev = bio_src->bi_bdev; | 544 | bio->bi_bdev = bio_src->bi_bdev; |
536 | bio->bi_flags |= 1 << BIO_CLONED; | 545 | bio->bi_flags |= 1 << BIO_CLONED; |
537 | bio->bi_rw = bio_src->bi_rw; | 546 | bio->bi_rw = bio_src->bi_rw; |
538 | bio->bi_vcnt = bio_src->bi_vcnt; | ||
539 | bio->bi_iter = bio_src->bi_iter; | 547 | bio->bi_iter = bio_src->bi_iter; |
540 | } | 548 | } |
541 | EXPORT_SYMBOL(__bio_clone); | 549 | EXPORT_SYMBOL(__bio_clone); |