diff options
| -rw-r--r-- | drivers/md/dm-crypt.c | 31 |
1 files changed, 5 insertions, 26 deletions
diff --git a/drivers/md/dm-crypt.c b/drivers/md/dm-crypt.c index 8216a6f75be5..64fee90bb68b 100644 --- a/drivers/md/dm-crypt.c +++ b/drivers/md/dm-crypt.c | |||
| @@ -441,33 +441,12 @@ static struct bio *crypt_alloc_buffer(struct dm_crypt_io *io, unsigned size) | |||
| 441 | return clone; | 441 | return clone; |
| 442 | } | 442 | } |
| 443 | 443 | ||
| 444 | static void crypt_free_buffer_pages(struct crypt_config *cc, | 444 | static void crypt_free_buffer_pages(struct crypt_config *cc, struct bio *clone) |
| 445 | struct bio *clone, unsigned int bytes) | ||
| 446 | { | 445 | { |
| 447 | unsigned int i, start, end; | 446 | unsigned int i; |
| 448 | struct bio_vec *bv; | 447 | struct bio_vec *bv; |
| 449 | 448 | ||
| 450 | /* | 449 | for (i = 0; i < clone->bi_vcnt; i++) { |
| 451 | * This is ugly, but Jens Axboe thinks that using bi_idx in the | ||
| 452 | * endio function is too dangerous at the moment, so I calculate the | ||
| 453 | * correct position using bi_vcnt and bi_size. | ||
| 454 | * The bv_offset and bv_len fields might already be modified but we | ||
| 455 | * know that we always allocated whole pages. | ||
| 456 | * A fix to the bi_idx issue in the kernel is in the works, so | ||
| 457 | * we will hopefully be able to revert to the cleaner solution soon. | ||
| 458 | */ | ||
| 459 | i = clone->bi_vcnt - 1; | ||
| 460 | bv = bio_iovec_idx(clone, i); | ||
| 461 | end = (i << PAGE_SHIFT) + (bv->bv_offset + bv->bv_len) - clone->bi_size; | ||
| 462 | start = end - bytes; | ||
| 463 | |||
| 464 | start >>= PAGE_SHIFT; | ||
| 465 | if (!clone->bi_size) | ||
| 466 | end = clone->bi_vcnt; | ||
| 467 | else | ||
| 468 | end >>= PAGE_SHIFT; | ||
| 469 | |||
| 470 | for (i = start; i < end; i++) { | ||
| 471 | bv = bio_iovec_idx(clone, i); | 450 | bv = bio_iovec_idx(clone, i); |
| 472 | BUG_ON(!bv->bv_page); | 451 | BUG_ON(!bv->bv_page); |
| 473 | mempool_free(bv->bv_page, cc->page_pool); | 452 | mempool_free(bv->bv_page, cc->page_pool); |
| @@ -519,7 +498,7 @@ static void crypt_endio(struct bio *clone, int error) | |||
| 519 | * free the processed pages | 498 | * free the processed pages |
| 520 | */ | 499 | */ |
| 521 | if (!read_io) { | 500 | if (!read_io) { |
| 522 | crypt_free_buffer_pages(cc, clone, clone->bi_size); | 501 | crypt_free_buffer_pages(cc, clone); |
| 523 | goto out; | 502 | goto out; |
| 524 | } | 503 | } |
| 525 | 504 | ||
| @@ -608,7 +587,7 @@ static void process_write(struct dm_crypt_io *io) | |||
| 608 | ctx.idx_out = 0; | 587 | ctx.idx_out = 0; |
| 609 | 588 | ||
| 610 | if (unlikely(crypt_convert(cc, &ctx) < 0)) { | 589 | if (unlikely(crypt_convert(cc, &ctx) < 0)) { |
| 611 | crypt_free_buffer_pages(cc, clone, clone->bi_size); | 590 | crypt_free_buffer_pages(cc, clone); |
| 612 | bio_put(clone); | 591 | bio_put(clone); |
| 613 | dec_pending(io, -EIO); | 592 | dec_pending(io, -EIO); |
| 614 | return; | 593 | return; |
