Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > linux.kernel > #1578382 > unrolled thread
| Started by | Ming Lei <tom.leiming@gmail.com> |
|---|---|
| First post | 2017-02-10 12:00 +0100 |
| Last post | 2017-02-15 03:30 +0100 |
| Articles | 5 — 2 participants |
Back to article view | Back to linux.kernel
This discussion starts older than the indexed window; earlier articles aren't shown. The article labeled Started by
below is the oldest one visible, not the original post.
[PATCH v1 1/5] block: introduce bio_clone_bioset_partial() Ming Lei <tom.leiming@gmail.com> - 2017-02-10 12:00 +0100
Re: [PATCH v1 1/5] block: introduce bio_clone_bioset_partial() Christoph Hellwig <hch@infradead.org> - 2017-02-13 14:50 +0100
Re: [PATCH v1 1/5] block: introduce bio_clone_bioset_partial() Ming Lei <tom.leiming@gmail.com> - 2017-02-14 02:10 +0100
Re: [PATCH v1 1/5] block: introduce bio_clone_bioset_partial() Christoph Hellwig <hch@infradead.org> - 2017-02-14 17:10 +0100
Re: [PATCH v1 1/5] block: introduce bio_clone_bioset_partial() Ming Lei <tom.leiming@gmail.com> - 2017-02-15 03:30 +0100
| From | Ming Lei <tom.leiming@gmail.com> |
|---|---|
| Date | 2017-02-10 12:00 +0100 |
| Subject | [PATCH v1 1/5] block: introduce bio_clone_bioset_partial() |
| Message-ID | <t9h5M-2lX-27@gated-at.bofh.it> |
md still need bio clone(not the fast version) for behind write,
and it is more efficient to use bio_clone_bioset_partial().
The idea is simple and just copy the bvecs range specified from
parameters.
Signed-off-by: Ming Lei <tom.leiming@gmail.com>
---
block/bio.c | 61 +++++++++++++++++++++++++++++++++++++++++------------
include/linux/bio.h | 11 ++++++++--
2 files changed, 57 insertions(+), 15 deletions(-)
diff --git a/block/bio.c b/block/bio.c
index 4b564d0c3e29..5eec5e08417f 100644
--- a/block/bio.c
+++ b/block/bio.c
@@ -625,21 +625,20 @@ struct bio *bio_clone_fast(struct bio *bio, gfp_t gfp_mask, struct bio_set *bs)
}
EXPORT_SYMBOL(bio_clone_fast);
-/**
- * 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)
+static struct bio *__bio_clone_bioset(struct bio *bio_src, gfp_t gfp_mask,
+ struct bio_set *bs, int offset,
+ int size)
{
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
@@ -663,7 +662,8 @@ 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), bs);
+ bio = bio_alloc_bioset(gfp_mask, __bio_segments(bio_src,
+ &iter_src), bs);
if (!bio)
return NULL;
bio->bi_bdev = bio_src->bi_bdev;
@@ -680,7 +680,7 @@ 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)
+ __bio_for_each_segment(bv, bio_src, iter, iter_src)
bio->bi_io_vec[bio->bi_vcnt++] = bv;
break;
}
@@ -699,9 +699,44 @@ 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
* @bio: destination bio
diff --git a/include/linux/bio.h b/include/linux/bio.h
index 7cf8a6c70a3f..8e521194f6fc 100644
--- a/include/linux/bio.h
+++ b/include/linux/bio.h
@@ -183,7 +183,7 @@ static inline void bio_advance_iter(struct bio *bio, struct bvec_iter *iter,
#define bio_iter_last(bvec, iter) ((iter).bi_size == (bvec).bv_len)
-static inline unsigned bio_segments(struct bio *bio)
+static inline unsigned __bio_segments(struct bio *bio, struct bvec_iter *bvec)
{
unsigned segs = 0;
struct bio_vec bv;
@@ -205,12 +205,17 @@ static inline unsigned bio_segments(struct bio *bio)
break;
}
- bio_for_each_segment(bv, bio, iter)
+ __bio_for_each_segment(bv, bio, iter, *bvec)
segs++;
return segs;
}
+static inline unsigned bio_segments(struct bio *bio)
+{
+ return __bio_segments(bio, &bio->bi_iter);
+}
+
/*
* get a reference to a bio, so it won't disappear. the intended use is
* something like:
@@ -384,6 +389,8 @@ extern void bio_put(struct bio *);
extern void __bio_clone_fast(struct bio *, struct bio *);
extern struct bio *bio_clone_fast(struct bio *, gfp_t, struct bio_set *);
extern struct bio *bio_clone_bioset(struct bio *, gfp_t, struct bio_set *bs);
+extern struct bio *bio_clone_bioset_partial(struct bio *, gfp_t,
+ struct bio_set *, int, int);
extern struct bio_set *fs_bio_set;
--
2.7.4
[toc] | [next] | [standalone]
| From | Christoph Hellwig <hch@infradead.org> |
|---|---|
| Date | 2017-02-13 14:50 +0100 |
| Message-ID | <tapaV-4mz-1@gated-at.bofh.it> |
| In reply to | #1578382 |
On Fri, Feb 10, 2017 at 06:56:13PM +0800, Ming Lei wrote: > md still need bio clone(not the fast version) for behind write, > and it is more efficient to use bio_clone_bioset_partial(). > > The idea is simple and just copy the bvecs range specified from > parameters. Given how few users bio_clone_bioset has I wonder if we shouldn't simply add the two new arguments to it instead of adding another indirection. Otherwise looks fine: Reviewed-by: Christoph Hellwig <hch@lst.de>
[toc] | [prev] | [next] | [standalone]
| From | Ming Lei <tom.leiming@gmail.com> |
|---|---|
| Date | 2017-02-14 02:10 +0100 |
| Message-ID | <tazMZ-38v-1@gated-at.bofh.it> |
| In reply to | #1579792 |
On Mon, Feb 13, 2017 at 9:46 PM, Christoph Hellwig <hch@infradead.org> wrote: > On Fri, Feb 10, 2017 at 06:56:13PM +0800, Ming Lei wrote: >> md still need bio clone(not the fast version) for behind write, >> and it is more efficient to use bio_clone_bioset_partial(). >> >> The idea is simple and just copy the bvecs range specified from >> parameters. > > Given how few users bio_clone_bioset has I wonder if we shouldn't > simply add the two new arguments to it instead of adding another > indirection. For md write-behind, looks we have to provide the two arguments, could you explain a bit how we can do that by adding another indirection? > > Otherwise looks fine: > > Reviewed-by: Christoph Hellwig <hch@lst.de> Thanks! -- Ming Lei
[toc] | [prev] | [next] | [standalone]
| From | Christoph Hellwig <hch@infradead.org> |
|---|---|
| Date | 2017-02-14 17:10 +0100 |
| Message-ID | <taNPX-41e-1@gated-at.bofh.it> |
| In reply to | #1580176 |
On Tue, Feb 14, 2017 at 09:04:26AM +0800, Ming Lei wrote: > On Mon, Feb 13, 2017 at 9:46 PM, Christoph Hellwig <hch@infradead.org> wrote: > > On Fri, Feb 10, 2017 at 06:56:13PM +0800, Ming Lei wrote: > >> md still need bio clone(not the fast version) for behind write, > >> and it is more efficient to use bio_clone_bioset_partial(). > >> > >> The idea is simple and just copy the bvecs range specified from > >> parameters. > > > > Given how few users bio_clone_bioset has I wonder if we shouldn't > > simply add the two new arguments to it instead of adding another > > indirection. > > For md write-behind, looks we have to provide the two arguments, > could you explain a bit how we can do that by adding another indirection? I meant to just pass the additional arguments that bio_clone_bioset_partial has to bio_clone_bioset.
[toc] | [prev] | [next] | [standalone]
| From | Ming Lei <tom.leiming@gmail.com> |
|---|---|
| Date | 2017-02-15 03:30 +0100 |
| Message-ID | <taXvX-1Eg-1@gated-at.bofh.it> |
| In reply to | #1580626 |
On Wed, Feb 15, 2017 at 12:01 AM, Christoph Hellwig <hch@infradead.org> wrote: > On Tue, Feb 14, 2017 at 09:04:26AM +0800, Ming Lei wrote: >> On Mon, Feb 13, 2017 at 9:46 PM, Christoph Hellwig <hch@infradead.org> wrote: >> > On Fri, Feb 10, 2017 at 06:56:13PM +0800, Ming Lei wrote: >> >> md still need bio clone(not the fast version) for behind write, >> >> and it is more efficient to use bio_clone_bioset_partial(). >> >> >> >> The idea is simple and just copy the bvecs range specified from >> >> parameters. >> > >> > Given how few users bio_clone_bioset has I wonder if we shouldn't >> > simply add the two new arguments to it instead of adding another >> > indirection. >> >> For md write-behind, looks we have to provide the two arguments, >> could you explain a bit how we can do that by adding another indirection? > > I meant to just pass the additional arguments that > bio_clone_bioset_partial has to bio_clone_bioset. That may cause more changes(fs, ...) into this patchset, so I suggest to do that in another patchset, especially after we confirmed current users of bio_clone is absolutely necessary, and I will check if other bio_clone can be converted to fast clone. Thanks, Ming Lei
[toc] | [prev] | [standalone]
Back to top | Article view | linux.kernel
csiph-web