--
dm-devel mailing list
dm-devel@redhat.com
https://www.redhat.com/mailman/listinfo/dm-devel
05-18-2012, 08:39 PM
Kent Overstreet
block: Add bio_clone_kmalloc()
On Fri, May 18, 2012 at 09:09:03AM -0700, Tejun Heo wrote:
> On Thu, May 17, 2012 at 10:59:51PM -0400, koverstreet@google.com wrote:
> > @@ -729,7 +729,7 @@ static struct bio *bio_chain_clone(struct bio **old, struct bio **next,
> > }
> >
> > while (old_chain && (total < len)) {
> > - tmp = bio_kmalloc(gfpmask, old_chain->bi_max_vecs);
> > + tmp = bio_clone_kmalloc(old_chain, gfpmask);
> > if (!tmp)
> > goto err_out;
> >
> > @@ -751,13 +751,9 @@ static struct bio *bio_chain_clone(struct bio **old, struct bio **next,
> > if (!bp)
> > goto err_out;
> >
> > - __bio_clone(tmp, &bp->bio1);
> > -
>
> This effectively swaps the order of bio_split() and __bio_clone(). Is
> that safe? Also, please cc the maintainer.
Now that I look at that code some more, I'm not sure it was quite right
before - that or I don't follow how it's supposed to work.
That bio_split() effectively does its own clone, so it seems to me the
bio_kmalloc()/bio_clone_kmalloc() should only be happening in the non
split case.
Also, there's a bio_chain_clone in drivers/block/osdblk.c that looks
like it's doing something similar, probably we should have some generic
code for this.
--
dm-devel mailing list
dm-devel@redhat.com
https://www.redhat.com/mailman/listinfo/dm-devel
tmp->bi_bdev = NULL;
gfpmask &= ~__GFP_WAIT;
diff --git a/fs/bio.c b/fs/bio.c
index 4cb621f..e2c0970 100644
--- a/fs/bio.c
+++ b/fs/bio.c
@@ -491,6 +491,19 @@ struct bio *bio_clone(struct bio *bio, gfp_t gfp_mask)
}
EXPORT_SYMBOL(bio_clone);
+struct bio *bio_clone_kmalloc(struct bio *bio, gfp_t gfp_mask)
+{
+ struct bio *b = bio_kmalloc(gfp_mask, bio->bi_max_vecs);
+
+ if (!b)
+ return NULL;
+
+ __bio_clone(b, bio);
+
+ return b;
+}
+EXPORT_SYMBOL(bio_clone_kmalloc);
+
/**
* bio_get_nr_vecs - return approx number of vecs
* @bdev: I/O target
diff --git a/fs/exofs/ore.c b/fs/exofs/ore.c
index 49cf230..95c7264 100644
--- a/fs/exofs/ore.c
+++ b/fs/exofs/ore.c
@@ -820,8 +820,8 @@ static int _write_mirror(struct ore_io_state *ios, int cur_comp)
struct bio *bio;
if (per_dev != master_dev) {
- bio = bio_kmalloc(GFP_KERNEL,
- master_dev->bio->bi_max_vecs);
+ bio = bio_clone_kmalloc(master_dev->bio,
+ GFP_KERNEL);
if (unlikely(!bio)) {
ORE_DBGMSG(
"Failed to allocate BIO size=%u
",
@@ -830,7 +830,6 @@ static int _write_mirror(struct ore_io_state *ios, int cur_comp)
goto out;
}
- __bio_clone(bio, master_dev->bio);
bio->bi_bdev = NULL;
bio->bi_next = NULL;
per_dev->offset = master_dev->offset;
diff --git a/include/linux/bio.h b/include/linux/bio.h
index e068a68..b27f16b 100644
--- a/include/linux/bio.h
+++ b/include/linux/bio.h
@@ -225,6 +225,7 @@ extern int bio_phys_segments(struct request_queue *, struct bio *);
extern void __bio_clone(struct bio *, struct bio *);
extern struct bio *bio_clone_bioset(struct bio *, gfp_t, struct bio_set *bs);
extern struct bio *bio_clone(struct bio *, gfp_t);
+struct bio *bio_clone_kmalloc(struct bio *, gfp_t);
extern void bio_init(struct bio *);
--
1.7.9.3.327.g2980b
--
dm-devel mailing list
dm-devel@redhat.com
https://www.redhat.com/mailman/listinfo/dm-devel
05-24-2012, 06:59 PM
Vivek Goyal
block: Add bio_clone_kmalloc()
On Wed, May 23, 2012 at 05:02:41PM -0700, Kent Overstreet wrote:
[..]
> diff --git a/drivers/block/rbd.c b/drivers/block/rbd.c
> index 013c7a5..5a953c6 100644
> --- a/drivers/block/rbd.c
> +++ b/drivers/block/rbd.c
> @@ -729,7 +729,7 @@ static struct bio *bio_chain_clone(struct bio **old, struct bio **next,
> }
>
> while (old_chain && (total < len)) {
> - tmp = bio_kmalloc(gfpmask, old_chain->bi_max_vecs);
> + tmp = bio_clone_kmalloc(old_chain, gfpmask);
> if (!tmp)
> goto err_out;
>
> @@ -751,13 +751,9 @@ static struct bio *bio_chain_clone(struct bio **old, struct bio **next,
> if (!bp)
> goto err_out;
>
> - __bio_clone(tmp, &bp->bio1);
> -
> *next = &bp->bio2;
Is this code correct. Now original code might clone bio after split and
new code will clone the original bio itself and not the split one?
Thanks
Vivek
--
dm-devel mailing list
dm-devel@redhat.com
https://www.redhat.com/mailman/listinfo/dm-devel
05-24-2012, 09:41 PM
Yehuda Sadeh
block: Add bio_clone_kmalloc()
On Thu, May 24, 2012 at 11:59 AM, Vivek Goyal <vgoyal@redhat.com> wrote:
> On Wed, May 23, 2012 at 05:02:41PM -0700, Kent Overstreet wrote:
>
> [..]
>> diff --git a/drivers/block/rbd.c b/drivers/block/rbd.c
>> index 013c7a5..5a953c6 100644
>> --- a/drivers/block/rbd.c
>> +++ b/drivers/block/rbd.c
>> @@ -729,7 +729,7 @@ static struct bio *bio_chain_clone(struct bio **old, struct bio **next,
>> * * * }
>>
>> * * * while (old_chain && (total < len)) {
>> - * * * * * * tmp = bio_kmalloc(gfpmask, old_chain->bi_max_vecs);
>> + * * * * * * tmp = bio_clone_kmalloc(old_chain, gfpmask);
>> * * * * * * * if (!tmp)
>> * * * * * * * * * * * goto err_out;
>>
>> @@ -751,13 +751,9 @@ static struct bio *bio_chain_clone(struct bio **old, struct bio **next,
>> * * * * * * * * * * * if (!bp)
>> * * * * * * * * * * * * * * * goto err_out;
>>
>> - * * * * * * * * * * __bio_clone(tmp, &bp->bio1);
>> -
>> * * * * * * * * * * * *next = &bp->bio2;
>
> Is this code correct. Now original code might clone bio after split and
> new code will clone the original bio itself and not the split one?
>
Yeah, that's wrong.
Yehuda
--
dm-devel mailing list
dm-devel@redhat.com
https://www.redhat.com/mailman/listinfo/dm-devel
05-25-2012, 12:31 AM
Kent Overstreet
block: Add bio_clone_kmalloc()
On Thu, May 24, 2012 at 02:59:19PM -0400, Vivek Goyal wrote:
> On Wed, May 23, 2012 at 05:02:41PM -0700, Kent Overstreet wrote:
>
> [..]
> > diff --git a/drivers/block/rbd.c b/drivers/block/rbd.c
> > index 013c7a5..5a953c6 100644
> > --- a/drivers/block/rbd.c
> > +++ b/drivers/block/rbd.c
> > @@ -729,7 +729,7 @@ static struct bio *bio_chain_clone(struct bio **old, struct bio **next,
> > }
> >
> > while (old_chain && (total < len)) {
> > - tmp = bio_kmalloc(gfpmask, old_chain->bi_max_vecs);
> > + tmp = bio_clone_kmalloc(old_chain, gfpmask);
> > if (!tmp)
> > goto err_out;
> >
> > @@ -751,13 +751,9 @@ static struct bio *bio_chain_clone(struct bio **old, struct bio **next,
> > if (!bp)
> > goto err_out;
> >
> > - __bio_clone(tmp, &bp->bio1);
> > -
> > *next = &bp->bio2;
>
> Is this code correct. Now original code might clone bio after split and
> new code will clone the original bio itself and not the split one?
Argh, you're right, I screwed that up.
I'd like to get rid of all the open coded bio_clone()s out there (to
reduce the amount of code that "Only clone bio vecs that are in use" has
to change, but this code is too tricky - I'm just going to drop this
bit.
--
dm-devel mailing list
dm-devel@redhat.com
https://www.redhat.com/mailman/listinfo/dm-devel
extern void __bio_clone(struct bio *, struct bio *);
extern struct bio *bio_clone(struct bio *, gfp_t);
+struct bio *bio_clone_kmalloc(struct bio *, gfp_t);
extern void bio_init(struct bio *);
extern void bio_reset(struct bio *);
--
1.7.9.3.327.g2980b
--
dm-devel mailing list
dm-devel@redhat.com
https://www.redhat.com/mailman/listinfo/dm-devel
extern void __bio_clone(struct bio *, struct bio *);
extern struct bio *bio_clone(struct bio *, gfp_t);
+struct bio *bio_clone_kmalloc(struct bio *, gfp_t);
extern void bio_init(struct bio *);
extern void bio_reset(struct bio *);
--
1.7.7.3
--
dm-devel mailing list
dm-devel@redhat.com
https://www.redhat.com/mailman/listinfo/dm-devel