aboutsummaryrefslogtreecommitdiffstats
path: root/block
diff options
context:
space:
mode:
authorJens Axboe <axboe@fb.com>2014-07-14 16:04:47 -0400
committerJens Axboe <axboe@fb.com>2014-07-14 16:04:47 -0400
commit26a337944e73d88838642a09689fdf40daf00069 (patch)
treef9c44bc06c67b67448950624da3ea80b5d4b3bd2 /block
parent254c4407cb84a6dec90336054615b0f0e996bb7c (diff)
Revert "bio: modify __bio_add_page() to accept pages that don't start a new segment"
This reverts commit 254c4407cb84a6dec90336054615b0f0e996bb7c. It causes crashes with cryptsetup, even after a few iterations and updates. Drop it for now.
Diffstat (limited to 'block')
-rw-r--r--block/bio.c52
1 files changed, 23 insertions, 29 deletions
diff --git a/block/bio.c b/block/bio.c
index fb12df9af0fc..0ec61c9e536c 100644
--- a/block/bio.c
+++ b/block/bio.c
@@ -744,7 +744,6 @@ static int __bio_add_page(struct request_queue *q, struct bio *bio, struct page
744 } 744 }
745 } 745 }
746 746
747 bio->bi_iter.bi_size += len;
748 goto done; 747 goto done;
749 } 748 }
750 749
@@ -761,32 +760,29 @@ static int __bio_add_page(struct request_queue *q, struct bio *bio, struct page
761 return 0; 760 return 0;
762 761
763 /* 762 /*
764 * setup the new entry, we might clear it again later if we 763 * we might lose a segment or two here, but rather that than
765 * cannot add the page 764 * make this too complex.
766 */
767 bvec = &bio->bi_io_vec[bio->bi_vcnt];
768 bvec->bv_page = page;
769 bvec->bv_len = len;
770 bvec->bv_offset = offset;
771 bio->bi_vcnt++;
772 bio->bi_phys_segments++;
773 bio->bi_iter.bi_size += len;
774
775 /*
776 * Perform a recount if the number of segments is greater
777 * than queue_max_segments(q).
778 */ 765 */
779 766
780 while (bio->bi_phys_segments > queue_max_segments(q)) { 767 while (bio->bi_phys_segments >= queue_max_segments(q)) {
781 768
782 if (retried_segments) 769 if (retried_segments)
783 goto failed; 770 return 0;
784 771
785 retried_segments = 1; 772 retried_segments = 1;
786 blk_recount_segments(q, bio); 773 blk_recount_segments(q, bio);
787 } 774 }
788 775
789 /* 776 /*
777 * setup the new entry, we might clear it again later if we
778 * cannot add the page
779 */
780 bvec = &bio->bi_io_vec[bio->bi_vcnt];
781 bvec->bv_page = page;
782 bvec->bv_len = len;
783 bvec->bv_offset = offset;
784
785 /*
790 * if queue has other restrictions (eg varying max sector size 786 * if queue has other restrictions (eg varying max sector size
791 * depending on offset), it can specify a merge_bvec_fn in the 787 * depending on offset), it can specify a merge_bvec_fn in the
792 * queue to get further control 788 * queue to get further control
@@ -803,25 +799,23 @@ static int __bio_add_page(struct request_queue *q, struct bio *bio, struct page
803 * merge_bvec_fn() returns number of bytes it can accept 799 * merge_bvec_fn() returns number of bytes it can accept
804 * at this offset 800 * at this offset
805 */ 801 */
806 if (q->merge_bvec_fn(q, &bvm, bvec) < bvec->bv_len) 802 if (q->merge_bvec_fn(q, &bvm, bvec) < bvec->bv_len) {
807 goto failed; 803 bvec->bv_page = NULL;
804 bvec->bv_len = 0;
805 bvec->bv_offset = 0;
806 return 0;
807 }
808 } 808 }
809 809
810 /* If we may be able to merge these biovecs, force a recount */ 810 /* If we may be able to merge these biovecs, force a recount */
811 if (bio->bi_vcnt > 1 && (BIOVEC_PHYS_MERGEABLE(bvec-1, bvec))) 811 if (bio->bi_vcnt && (BIOVEC_PHYS_MERGEABLE(bvec-1, bvec)))
812 bio->bi_flags &= ~(1 << BIO_SEG_VALID); 812 bio->bi_flags &= ~(1 << BIO_SEG_VALID);
813 813
814 bio->bi_vcnt++;
815 bio->bi_phys_segments++;
814 done: 816 done:
817 bio->bi_iter.bi_size += len;
815 return len; 818 return len;
816
817 failed:
818 bvec->bv_page = NULL;
819 bvec->bv_len = 0;
820 bvec->bv_offset = 0;
821 bio->bi_vcnt--;
822 bio->bi_iter.bi_size -= len;
823 blk_recount_segments(q, bio);
824 return 0;
825} 819}
826 820
827/** 821/**