From 6f8802852f7e58a12177a86179803b9efaad98e2 Mon Sep 17 00:00:00 2001 From: Ming Lei Date: Fri, 17 Mar 2017 00:12:29 +0800 Subject: block: introduce bio_copy_data_partial Turns out we can use bio_copy_data in raid1's write behind, and we can make alloc_behind_pages() more clean/efficient, but we need to partial version of bio_copy_data(). Signed-off-by: Ming Lei Reviewed-by: Jens Axboe Signed-off-by: Shaohua Li --- block/bio.c | 60 +++++++++++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 47 insertions(+), 13 deletions(-) (limited to 'block') diff --git a/block/bio.c b/block/bio.c index e75878f8b14a..1ccff0dace89 100644 --- a/block/bio.c +++ b/block/bio.c @@ -1025,19 +1025,8 @@ int bio_alloc_pages(struct bio *bio, gfp_t gfp_mask) } EXPORT_SYMBOL(bio_alloc_pages); -/** - * bio_copy_data - copy contents of data buffers from one chain of bios to - * another - * @src: source bio list - * @dst: destination bio list - * - * If @src and @dst are single bios, bi_next must be NULL - otherwise, treats - * @src and @dst as linked lists of bios. - * - * Stops when it reaches the end of either @src or @dst - that is, copies - * min(src->bi_size, dst->bi_size) bytes (or the equivalent for lists of bios). - */ -void bio_copy_data(struct bio *dst, struct bio *src) +static void __bio_copy_data(struct bio *dst, struct bio *src, + int offset, int size) { struct bvec_iter src_iter, dst_iter; struct bio_vec src_bv, dst_bv; @@ -1047,6 +1036,12 @@ void bio_copy_data(struct bio *dst, struct bio *src) src_iter = src->bi_iter; dst_iter = dst->bi_iter; + /* for supporting partial copy */ + if (offset || size != src->bi_iter.bi_size) { + bio_advance_iter(src, &src_iter, offset); + src_iter.bi_size = size; + } + while (1) { if (!src_iter.bi_size) { src = src->bi_next; @@ -1083,8 +1078,47 @@ void bio_copy_data(struct bio *dst, struct bio *src) bio_advance_iter(dst, &dst_iter, bytes); } } + +/** + * bio_copy_data - copy contents of data buffers from one chain of bios to + * another + * @src: source bio list + * @dst: destination bio list + * + * If @src and @dst are single bios, bi_next must be NULL - otherwise, treats + * @src and @dst as linked lists of bios. + * + * Stops when it reaches the end of either @src or @dst - that is, copies + * min(src->bi_size, dst->bi_size) bytes (or the equivalent for lists of bios). + */ +void bio_copy_data(struct bio *dst, struct bio *src) +{ + __bio_copy_data(dst, src, 0, src->bi_iter.bi_size); +} EXPORT_SYMBOL(bio_copy_data); +/** + * bio_copy_data_partial - copy partial contents of data buffers from one + * chain of bios to another + * @dst: destination bio list + * @src: source bio list + * @offset: starting copy from the offset + * @size: how many bytes to copy + * + * If @src and @dst are single bios, bi_next must be NULL - otherwise, treats + * @src and @dst as linked lists of bios. + * + * Stops when it reaches the end of either @src or @dst - that is, copies + * min(src->bi_size, dst->bi_size) bytes (or the equivalent for lists of bios). + */ +void bio_copy_data_partial(struct bio *dst, struct bio *src, + int offset, int size) +{ + __bio_copy_data(dst, src, offset, size); + +} +EXPORT_SYMBOL(bio_copy_data_partial); + struct bio_map_data { int is_our_pages; struct iov_iter iter; -- cgit From f45958756fef552436e4a63029a168495920026e Mon Sep 17 00:00:00 2001 From: Shaohua Li Date: Fri, 24 Mar 2017 10:34:43 -0700 Subject: block: remove bio_clone_bioset_partial() commit c18a1e0(block: introduce bio_clone_bioset_partial()) introduced bio_clone_bioset_partial() for raid1 write behind IO. Now the write behind is rewritten by Ming. We don't need the API any more, so revert the commit. Cc: Christoph Hellwig Reviewed-by: Jens Axboe Reviewed-by: Ming Lei Signed-off-by: Shaohua Li --- block/bio.c | 61 +++++++++++++------------------------------------------------ 1 file changed, 13 insertions(+), 48 deletions(-) (limited to 'block') diff --git a/block/bio.c b/block/bio.c index 1ccff0dace89..036435995c55 100644 --- a/block/bio.c +++ b/block/bio.c @@ -631,20 +631,21 @@ struct bio *bio_clone_fast(struct bio *bio, gfp_t gfp_mask, struct bio_set *bs) } EXPORT_SYMBOL(bio_clone_fast); -static struct bio *__bio_clone_bioset(struct bio *bio_src, gfp_t gfp_mask, - struct bio_set *bs, int offset, - int size) +/** + * bio_clone_bioset - clone a bio + * @bio_src: bio to clone + * @gfp_mask: allocation priority + * @bs: bio_set to allocate from + * + * Clone bio. Caller will own the returned bio, but not the actual data it + * points to. Reference count of returned bio will be one. + */ +struct bio *bio_clone_bioset(struct bio *bio_src, gfp_t gfp_mask, + struct bio_set *bs) { struct bvec_iter iter; struct bio_vec bv; struct bio *bio; - struct bvec_iter iter_src = bio_src->bi_iter; - - /* for supporting partial clone */ - if (offset || size != bio_src->bi_iter.bi_size) { - bio_advance_iter(bio_src, &iter_src, offset); - iter_src.bi_size = size; - } /* * Pre immutable biovecs, __bio_clone() used to just do a memcpy from @@ -668,8 +669,7 @@ static struct bio *__bio_clone_bioset(struct bio *bio_src, gfp_t gfp_mask, * __bio_clone_fast() anyways. */ - bio = bio_alloc_bioset(gfp_mask, __bio_segments(bio_src, - &iter_src), bs); + bio = bio_alloc_bioset(gfp_mask, bio_segments(bio_src), bs); if (!bio) return NULL; bio->bi_bdev = bio_src->bi_bdev; @@ -686,7 +686,7 @@ static struct bio *__bio_clone_bioset(struct bio *bio_src, gfp_t gfp_mask, bio->bi_io_vec[bio->bi_vcnt++] = bio_src->bi_io_vec[0]; break; default: - __bio_for_each_segment(bv, bio_src, iter, iter_src) + bio_for_each_segment(bv, bio_src, iter) bio->bi_io_vec[bio->bi_vcnt++] = bv; break; } @@ -705,43 +705,8 @@ static struct bio *__bio_clone_bioset(struct bio *bio_src, gfp_t gfp_mask, return bio; } - -/** - * bio_clone_bioset - clone a bio - * @bio_src: bio to clone - * @gfp_mask: allocation priority - * @bs: bio_set to allocate from - * - * Clone bio. Caller will own the returned bio, but not the actual data it - * points to. Reference count of returned bio will be one. - */ -struct bio *bio_clone_bioset(struct bio *bio_src, gfp_t gfp_mask, - struct bio_set *bs) -{ - return __bio_clone_bioset(bio_src, gfp_mask, bs, 0, - bio_src->bi_iter.bi_size); -} EXPORT_SYMBOL(bio_clone_bioset); -/** - * bio_clone_bioset_partial - clone a partial bio - * @bio_src: bio to clone - * @gfp_mask: allocation priority - * @bs: bio_set to allocate from - * @offset: cloned starting from the offset - * @size: size for the cloned bio - * - * Clone bio. Caller will own the returned bio, but not the actual data it - * points to. Reference count of returned bio will be one. - */ -struct bio *bio_clone_bioset_partial(struct bio *bio_src, gfp_t gfp_mask, - struct bio_set *bs, int offset, - int size) -{ - return __bio_clone_bioset(bio_src, gfp_mask, bs, offset, size); -} -EXPORT_SYMBOL(bio_clone_bioset_partial); - /** * bio_add_pc_page - attempt to add page to bio * @q: the target queue -- cgit From 50512625da06c41517cb596f51b923ce15f401a4 Mon Sep 17 00:00:00 2001 From: NeilBrown Date: Wed, 5 Apr 2017 14:05:50 +1000 Subject: Revert "block: introduce bio_copy_data_partial" This reverts commit 6f8802852f7e58a12177a86179803b9efaad98e2. bio_copy_data_partial() is no longer needed. Signed-off-by: NeilBrown Signed-off-by: Shaohua Li --- block/bio.c | 60 +++++++++++++----------------------------------------------- 1 file changed, 13 insertions(+), 47 deletions(-) (limited to 'block') diff --git a/block/bio.c b/block/bio.c index 036435995c55..12c2837c4277 100644 --- a/block/bio.c +++ b/block/bio.c @@ -990,8 +990,19 @@ int bio_alloc_pages(struct bio *bio, gfp_t gfp_mask) } EXPORT_SYMBOL(bio_alloc_pages); -static void __bio_copy_data(struct bio *dst, struct bio *src, - int offset, int size) +/** + * bio_copy_data - copy contents of data buffers from one chain of bios to + * another + * @src: source bio list + * @dst: destination bio list + * + * If @src and @dst are single bios, bi_next must be NULL - otherwise, treats + * @src and @dst as linked lists of bios. + * + * Stops when it reaches the end of either @src or @dst - that is, copies + * min(src->bi_size, dst->bi_size) bytes (or the equivalent for lists of bios). + */ +void bio_copy_data(struct bio *dst, struct bio *src) { struct bvec_iter src_iter, dst_iter; struct bio_vec src_bv, dst_bv; @@ -1001,12 +1012,6 @@ static void __bio_copy_data(struct bio *dst, struct bio *src, src_iter = src->bi_iter; dst_iter = dst->bi_iter; - /* for supporting partial copy */ - if (offset || size != src->bi_iter.bi_size) { - bio_advance_iter(src, &src_iter, offset); - src_iter.bi_size = size; - } - while (1) { if (!src_iter.bi_size) { src = src->bi_next; @@ -1043,47 +1048,8 @@ static void __bio_copy_data(struct bio *dst, struct bio *src, bio_advance_iter(dst, &dst_iter, bytes); } } - -/** - * bio_copy_data - copy contents of data buffers from one chain of bios to - * another - * @src: source bio list - * @dst: destination bio list - * - * If @src and @dst are single bios, bi_next must be NULL - otherwise, treats - * @src and @dst as linked lists of bios. - * - * Stops when it reaches the end of either @src or @dst - that is, copies - * min(src->bi_size, dst->bi_size) bytes (or the equivalent for lists of bios). - */ -void bio_copy_data(struct bio *dst, struct bio *src) -{ - __bio_copy_data(dst, src, 0, src->bi_iter.bi_size); -} EXPORT_SYMBOL(bio_copy_data); -/** - * bio_copy_data_partial - copy partial contents of data buffers from one - * chain of bios to another - * @dst: destination bio list - * @src: source bio list - * @offset: starting copy from the offset - * @size: how many bytes to copy - * - * If @src and @dst are single bios, bi_next must be NULL - otherwise, treats - * @src and @dst as linked lists of bios. - * - * Stops when it reaches the end of either @src or @dst - that is, copies - * min(src->bi_size, dst->bi_size) bytes (or the equivalent for lists of bios). - */ -void bio_copy_data_partial(struct bio *dst, struct bio *src, - int offset, int size) -{ - __bio_copy_data(dst, src, offset, size); - -} -EXPORT_SYMBOL(bio_copy_data_partial); - struct bio_map_data { int is_our_pages; struct iov_iter iter; -- cgit