diff options
author | Kent Overstreet <kent.overstreet@gmail.com> | 2013-11-24 01:30:22 -0500 |
---|---|---|
committer | Jens Axboe <axboe@fb.com> | 2015-08-13 14:31:37 -0400 |
commit | c66a14d07c136cc35d4dcb84bfc7bc188be24d4c (patch) | |
tree | 92ffa5e392126cab041c1624dc4a573f3b40e8b8 /block/bio.c | |
parent | 54efd50bfd873e2dbf784e0b21a8027ba4299a3e (diff) |
block: simplify bio_add_page()
Since generic_make_request() can now handle arbitrary size bios, all we
have to do is make sure the bvec array doesn't overflow.
__bio_add_page() doesn't need to call ->merge_bvec_fn(), where
we can get rid of unnecessary code paths.
Removing the call to ->merge_bvec_fn() is also fine, as no driver that
implements support for BLOCK_PC commands even has a ->merge_bvec_fn()
method.
Cc: Christoph Hellwig <hch@infradead.org>
Cc: Jens Axboe <axboe@kernel.dk>
Signed-off-by: Kent Overstreet <kent.overstreet@gmail.com>
[dpark: rebase and resolve merge conflicts, change a couple of comments,
make bio_add_page() warn once upon a cloned bio.]
Signed-off-by: Dongsu Park <dpark@posteo.net>
Signed-off-by: Ming Lin <ming.l@ssi.samsung.com>
Signed-off-by: Jens Axboe <axboe@fb.com>
Diffstat (limited to 'block/bio.c')
-rw-r--r-- | block/bio.c | 135 |
1 files changed, 55 insertions, 80 deletions
diff --git a/block/bio.c b/block/bio.c index 911ae8f82752..ba9c4b0c0ff2 100644 --- a/block/bio.c +++ b/block/bio.c | |||
@@ -716,9 +716,23 @@ int bio_get_nr_vecs(struct block_device *bdev) | |||
716 | } | 716 | } |
717 | EXPORT_SYMBOL(bio_get_nr_vecs); | 717 | EXPORT_SYMBOL(bio_get_nr_vecs); |
718 | 718 | ||
719 | static int __bio_add_page(struct request_queue *q, struct bio *bio, struct page | 719 | /** |
720 | *page, unsigned int len, unsigned int offset, | 720 | * bio_add_pc_page - attempt to add page to bio |
721 | unsigned int max_sectors) | 721 | * @q: the target queue |
722 | * @bio: destination bio | ||
723 | * @page: page to add | ||
724 | * @len: vec entry length | ||
725 | * @offset: vec entry offset | ||
726 | * | ||
727 | * Attempt to add a page to the bio_vec maplist. This can fail for a | ||
728 | * number of reasons, such as the bio being full or target block device | ||
729 | * limitations. The target block device must allow bio's up to PAGE_SIZE, | ||
730 | * so it is always possible to add a single page to an empty bio. | ||
731 | * | ||
732 | * This should only be used by REQ_PC bios. | ||
733 | */ | ||
734 | int bio_add_pc_page(struct request_queue *q, struct bio *bio, struct page | ||
735 | *page, unsigned int len, unsigned int offset) | ||
722 | { | 736 | { |
723 | int retried_segments = 0; | 737 | int retried_segments = 0; |
724 | struct bio_vec *bvec; | 738 | struct bio_vec *bvec; |
@@ -729,7 +743,7 @@ static int __bio_add_page(struct request_queue *q, struct bio *bio, struct page | |||
729 | if (unlikely(bio_flagged(bio, BIO_CLONED))) | 743 | if (unlikely(bio_flagged(bio, BIO_CLONED))) |
730 | return 0; | 744 | return 0; |
731 | 745 | ||
732 | if (((bio->bi_iter.bi_size + len) >> 9) > max_sectors) | 746 | if (((bio->bi_iter.bi_size + len) >> 9) > queue_max_hw_sectors(q)) |
733 | return 0; | 747 | return 0; |
734 | 748 | ||
735 | /* | 749 | /* |
@@ -742,28 +756,7 @@ static int __bio_add_page(struct request_queue *q, struct bio *bio, struct page | |||
742 | 756 | ||
743 | if (page == prev->bv_page && | 757 | if (page == prev->bv_page && |
744 | offset == prev->bv_offset + prev->bv_len) { | 758 | offset == prev->bv_offset + prev->bv_len) { |
745 | unsigned int prev_bv_len = prev->bv_len; | ||
746 | prev->bv_len += len; | 759 | prev->bv_len += len; |
747 | |||
748 | if (q->merge_bvec_fn) { | ||
749 | struct bvec_merge_data bvm = { | ||
750 | /* prev_bvec is already charged in | ||
751 | bi_size, discharge it in order to | ||
752 | simulate merging updated prev_bvec | ||
753 | as new bvec. */ | ||
754 | .bi_bdev = bio->bi_bdev, | ||
755 | .bi_sector = bio->bi_iter.bi_sector, | ||
756 | .bi_size = bio->bi_iter.bi_size - | ||
757 | prev_bv_len, | ||
758 | .bi_rw = bio->bi_rw, | ||
759 | }; | ||
760 | |||
761 | if (q->merge_bvec_fn(q, &bvm, prev) < prev->bv_len) { | ||
762 | prev->bv_len -= len; | ||
763 | return 0; | ||
764 | } | ||
765 | } | ||
766 | |||
767 | bio->bi_iter.bi_size += len; | 760 | bio->bi_iter.bi_size += len; |
768 | goto done; | 761 | goto done; |
769 | } | 762 | } |
@@ -806,27 +799,6 @@ static int __bio_add_page(struct request_queue *q, struct bio *bio, struct page | |||
806 | blk_recount_segments(q, bio); | 799 | blk_recount_segments(q, bio); |
807 | } | 800 | } |
808 | 801 | ||
809 | /* | ||
810 | * if queue has other restrictions (eg varying max sector size | ||
811 | * depending on offset), it can specify a merge_bvec_fn in the | ||
812 | * queue to get further control | ||
813 | */ | ||
814 | if (q->merge_bvec_fn) { | ||
815 | struct bvec_merge_data bvm = { | ||
816 | .bi_bdev = bio->bi_bdev, | ||
817 | .bi_sector = bio->bi_iter.bi_sector, | ||
818 | .bi_size = bio->bi_iter.bi_size - len, | ||
819 | .bi_rw = bio->bi_rw, | ||
820 | }; | ||
821 | |||
822 | /* | ||
823 | * merge_bvec_fn() returns number of bytes it can accept | ||
824 | * at this offset | ||
825 | */ | ||
826 | if (q->merge_bvec_fn(q, &bvm, bvec) < bvec->bv_len) | ||
827 | goto failed; | ||
828 | } | ||
829 | |||
830 | /* If we may be able to merge these biovecs, force a recount */ | 802 | /* If we may be able to merge these biovecs, force a recount */ |
831 | if (bio->bi_vcnt > 1 && (BIOVEC_PHYS_MERGEABLE(bvec-1, bvec))) | 803 | if (bio->bi_vcnt > 1 && (BIOVEC_PHYS_MERGEABLE(bvec-1, bvec))) |
832 | bio_clear_flag(bio, BIO_SEG_VALID); | 804 | bio_clear_flag(bio, BIO_SEG_VALID); |
@@ -843,28 +815,6 @@ static int __bio_add_page(struct request_queue *q, struct bio *bio, struct page | |||
843 | blk_recount_segments(q, bio); | 815 | blk_recount_segments(q, bio); |
844 | return 0; | 816 | return 0; |
845 | } | 817 | } |
846 | |||
847 | /** | ||
848 | * bio_add_pc_page - attempt to add page to bio | ||
849 | * @q: the target queue | ||
850 | * @bio: destination bio | ||
851 | * @page: page to add | ||
852 | * @len: vec entry length | ||
853 | * @offset: vec entry offset | ||
854 | * | ||
855 | * Attempt to add a page to the bio_vec maplist. This can fail for a | ||
856 | * number of reasons, such as the bio being full or target block device | ||
857 | * limitations. The target block device must allow bio's up to PAGE_SIZE, | ||
858 | * so it is always possible to add a single page to an empty bio. | ||
859 | * | ||
860 | * This should only be used by REQ_PC bios. | ||
861 | */ | ||
862 | int bio_add_pc_page(struct request_queue *q, struct bio *bio, struct page *page, | ||
863 | unsigned int len, unsigned int offset) | ||
864 | { | ||
865 | return __bio_add_page(q, bio, page, len, offset, | ||
866 | queue_max_hw_sectors(q)); | ||
867 | } | ||
868 | EXPORT_SYMBOL(bio_add_pc_page); | 818 | EXPORT_SYMBOL(bio_add_pc_page); |
869 | 819 | ||
870 | /** | 820 | /** |
@@ -874,22 +824,47 @@ EXPORT_SYMBOL(bio_add_pc_page); | |||
874 | * @len: vec entry length | 824 | * @len: vec entry length |
875 | * @offset: vec entry offset | 825 | * @offset: vec entry offset |
876 | * | 826 | * |
877 | * Attempt to add a page to the bio_vec maplist. This can fail for a | 827 | * Attempt to add a page to the bio_vec maplist. This will only fail |
878 | * number of reasons, such as the bio being full or target block device | 828 | * if either bio->bi_vcnt == bio->bi_max_vecs or it's a cloned bio. |
879 | * limitations. The target block device must allow bio's up to PAGE_SIZE, | ||
880 | * so it is always possible to add a single page to an empty bio. | ||
881 | */ | 829 | */ |
882 | int bio_add_page(struct bio *bio, struct page *page, unsigned int len, | 830 | int bio_add_page(struct bio *bio, struct page *page, |
883 | unsigned int offset) | 831 | unsigned int len, unsigned int offset) |
884 | { | 832 | { |
885 | struct request_queue *q = bdev_get_queue(bio->bi_bdev); | 833 | struct bio_vec *bv; |
886 | unsigned int max_sectors; | ||
887 | 834 | ||
888 | max_sectors = blk_max_size_offset(q, bio->bi_iter.bi_sector); | 835 | /* |
889 | if ((max_sectors < (len >> 9)) && !bio->bi_iter.bi_size) | 836 | * cloned bio must not modify vec list |
890 | max_sectors = len >> 9; | 837 | */ |
838 | if (WARN_ON_ONCE(bio_flagged(bio, BIO_CLONED))) | ||
839 | return 0; | ||
891 | 840 | ||
892 | return __bio_add_page(q, bio, page, len, offset, max_sectors); | 841 | /* |
842 | * For filesystems with a blocksize smaller than the pagesize | ||
843 | * we will often be called with the same page as last time and | ||
844 | * a consecutive offset. Optimize this special case. | ||
845 | */ | ||
846 | if (bio->bi_vcnt > 0) { | ||
847 | bv = &bio->bi_io_vec[bio->bi_vcnt - 1]; | ||
848 | |||
849 | if (page == bv->bv_page && | ||
850 | offset == bv->bv_offset + bv->bv_len) { | ||
851 | bv->bv_len += len; | ||
852 | goto done; | ||
853 | } | ||
854 | } | ||
855 | |||
856 | if (bio->bi_vcnt >= bio->bi_max_vecs) | ||
857 | return 0; | ||
858 | |||
859 | bv = &bio->bi_io_vec[bio->bi_vcnt]; | ||
860 | bv->bv_page = page; | ||
861 | bv->bv_len = len; | ||
862 | bv->bv_offset = offset; | ||
863 | |||
864 | bio->bi_vcnt++; | ||
865 | done: | ||
866 | bio->bi_iter.bi_size += len; | ||
867 | return len; | ||
893 | } | 868 | } |
894 | EXPORT_SYMBOL(bio_add_page); | 869 | EXPORT_SYMBOL(bio_add_page); |
895 | 870 | ||