diff options
author | Olaf Kirch <olaf.kirch@oracle.com> | 2007-05-09 05:32:52 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-05-09 15:30:46 -0400 |
commit | 027581f3515b5ec2218847dab578afa439a9d6b9 (patch) | |
tree | a15a2e0f3711c42a70170b9d4232b61d694899ca /drivers | |
parent | 9c89f8be1a7d14aad9d2c3f7d90d7d88f82c61e2 (diff) |
dm crypt: fix call to clone_init
Call clone_init early
We need to call clone_init as early as possible - at least before call
bio_put(clone) in any error path. Otherwise, the destructor will try to
dereference bi_private, which may still be NULL.
Signed-off-by: Olaf Kirch <olaf.kirch@oracle.com>
Signed-off-by: Alasdair G Kergon <agk@redhat.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/md/dm-crypt.c | 12 |
1 files changed, 7 insertions, 5 deletions
diff --git a/drivers/md/dm-crypt.c b/drivers/md/dm-crypt.c index 8527827b24f1..db439363f97d 100644 --- a/drivers/md/dm-crypt.c +++ b/drivers/md/dm-crypt.c | |||
@@ -107,6 +107,8 @@ struct crypt_config { | |||
107 | 107 | ||
108 | static struct kmem_cache *_crypt_io_pool; | 108 | static struct kmem_cache *_crypt_io_pool; |
109 | 109 | ||
110 | static void clone_init(struct crypt_io *, struct bio *); | ||
111 | |||
110 | /* | 112 | /* |
111 | * Different IV generation algorithms: | 113 | * Different IV generation algorithms: |
112 | * | 114 | * |
@@ -379,9 +381,10 @@ static int crypt_convert(struct crypt_config *cc, | |||
379 | * May return a smaller bio when running out of pages | 381 | * May return a smaller bio when running out of pages |
380 | */ | 382 | */ |
381 | static struct bio * | 383 | static struct bio * |
382 | crypt_alloc_buffer(struct crypt_config *cc, unsigned int size, | 384 | crypt_alloc_buffer(struct crypt_io *io, unsigned int size, |
383 | struct bio *base_bio, unsigned int *bio_vec_idx) | 385 | struct bio *base_bio, unsigned int *bio_vec_idx) |
384 | { | 386 | { |
387 | struct crypt_config *cc = io->target->private; | ||
385 | struct bio *clone; | 388 | struct bio *clone; |
386 | unsigned int nr_iovecs = (size + PAGE_SIZE - 1) >> PAGE_SHIFT; | 389 | unsigned int nr_iovecs = (size + PAGE_SIZE - 1) >> PAGE_SHIFT; |
387 | gfp_t gfp_mask = GFP_NOIO | __GFP_HIGHMEM; | 390 | gfp_t gfp_mask = GFP_NOIO | __GFP_HIGHMEM; |
@@ -396,7 +399,7 @@ crypt_alloc_buffer(struct crypt_config *cc, unsigned int size, | |||
396 | if (!clone) | 399 | if (!clone) |
397 | return NULL; | 400 | return NULL; |
398 | 401 | ||
399 | clone->bi_destructor = dm_crypt_bio_destructor; | 402 | clone_init(io, clone); |
400 | 403 | ||
401 | /* if the last bio was not complete, continue where that one ended */ | 404 | /* if the last bio was not complete, continue where that one ended */ |
402 | clone->bi_idx = *bio_vec_idx; | 405 | clone->bi_idx = *bio_vec_idx; |
@@ -562,6 +565,7 @@ static void clone_init(struct crypt_io *io, struct bio *clone) | |||
562 | clone->bi_end_io = crypt_endio; | 565 | clone->bi_end_io = crypt_endio; |
563 | clone->bi_bdev = cc->dev->bdev; | 566 | clone->bi_bdev = cc->dev->bdev; |
564 | clone->bi_rw = io->base_bio->bi_rw; | 567 | clone->bi_rw = io->base_bio->bi_rw; |
568 | clone->bi_destructor = dm_crypt_bio_destructor; | ||
565 | } | 569 | } |
566 | 570 | ||
567 | static void process_read(struct crypt_io *io) | 571 | static void process_read(struct crypt_io *io) |
@@ -585,7 +589,6 @@ static void process_read(struct crypt_io *io) | |||
585 | } | 589 | } |
586 | 590 | ||
587 | clone_init(io, clone); | 591 | clone_init(io, clone); |
588 | clone->bi_destructor = dm_crypt_bio_destructor; | ||
589 | clone->bi_idx = 0; | 592 | clone->bi_idx = 0; |
590 | clone->bi_vcnt = bio_segments(base_bio); | 593 | clone->bi_vcnt = bio_segments(base_bio); |
591 | clone->bi_size = base_bio->bi_size; | 594 | clone->bi_size = base_bio->bi_size; |
@@ -615,7 +618,7 @@ static void process_write(struct crypt_io *io) | |||
615 | * so repeat the whole process until all the data can be handled. | 618 | * so repeat the whole process until all the data can be handled. |
616 | */ | 619 | */ |
617 | while (remaining) { | 620 | while (remaining) { |
618 | clone = crypt_alloc_buffer(cc, base_bio->bi_size, | 621 | clone = crypt_alloc_buffer(io, base_bio->bi_size, |
619 | io->first_clone, &bvec_idx); | 622 | io->first_clone, &bvec_idx); |
620 | if (unlikely(!clone)) { | 623 | if (unlikely(!clone)) { |
621 | dec_pending(io, -ENOMEM); | 624 | dec_pending(io, -ENOMEM); |
@@ -631,7 +634,6 @@ static void process_write(struct crypt_io *io) | |||
631 | return; | 634 | return; |
632 | } | 635 | } |
633 | 636 | ||
634 | clone_init(io, clone); | ||
635 | clone->bi_sector = cc->start + sector; | 637 | clone->bi_sector = cc->start + sector; |
636 | 638 | ||
637 | if (!io->first_clone) { | 639 | if (!io->first_clone) { |